From ac45d61357e86b9a0cf14e45e8e09dfb626970ef Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 5 Mar 2012 15:48:11 +0100 Subject: [PATCH 001/438] fuse: fix nlink after unlink Anand Avati reports that the following sequence of system calls fail on a fuse filesystem: create("filename") => 0 link("filename", "linkname") => 0 unlink("filename") => 0 link("linkname", "filename") => -ENOENT ### BUG ### vfs_link() fails with ENOENT if i_nlink is zero, this is done to prevent resurrecting already deleted files. Fuse clears i_nlink on unlink even if there are other links pointing to the file. Reported-by: Anand Avati Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 206632887bb4..da379070fab5 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -644,13 +644,12 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) fuse_put_request(fc, req); if (!err) { struct inode *inode = entry->d_inode; + struct fuse_inode *fi = get_fuse_inode(inode); - /* - * Set nlink to zero so the inode can be cleared, if the inode - * does have more links this will be discovered at the next - * lookup/getattr. - */ - clear_nlink(inode); + spin_lock(&fc->lock); + fi->attr_version = ++fc->attr_version; + drop_nlink(inode); + spin_unlock(&fc->lock); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -762,8 +761,17 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, will reflect changes in the backing inode (link count, etc.) */ - if (!err || err == -EINTR) + if (!err) { + struct fuse_inode *fi = get_fuse_inode(inode); + + spin_lock(&fc->lock); + fi->attr_version = ++fc->attr_version; + inc_nlink(inode); + spin_unlock(&fc->lock); fuse_invalidate_attr(inode); + } else if (err == -EINTR) { + fuse_invalidate_attr(inode); + } return err; } From 4273b793ec68753cc3fcf5be7cbfd88c2be2058d Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Fri, 17 Feb 2012 12:46:25 -0500 Subject: [PATCH 002/438] fuse: O_DIRECT support for files Implement ->direct_IO() method in aops. The ->direct_IO() method combines the existing fuse_direct_read/fuse_direct_write methods to implement O_DIRECT functionality. Reaching ->direct_IO() in the read path via generic_file_aio_read ensures proper synchronization with page cache with its existing framework. Reaching ->direct_IO() in the write path via fuse_file_aio_write is made to come via generic_file_direct_write() which makes it play nice with the page cache w.r.t other mmap pages etc. On files marked 'direct_io' by the filesystem server, IO always follows the fuse_direct_read/write path. There is no effect of fcntl(O_DIRECT) and it always succeeds. On files not marked with 'direct_io' by the filesystem server, the IO path depends on O_DIRECT flag by the application. This can be passed at the time of open() as well as via fcntl(). Note that asynchronous O_DIRECT iocb jobs are completed synchronously always (this has been the case with FUSE even before this patch) Signed-off-by: Anand Avati Reviewed-by: Jeff Moyer Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 3 -- fs/fuse/file.c | 129 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 112 insertions(+), 20 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index da379070fab5..df5ac048dc74 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -387,9 +387,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (fc->no_create) return -ENOSYS; - if (flags & O_DIRECT) - return -EINVAL; - forget = fuse_alloc_forget(); if (!forget) return -ENOMEM; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 4a199fd93fbd..8ca007d09c96 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -194,10 +194,6 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = get_fuse_conn(inode); int err; - /* VFS checks this, but only _after_ ->open() */ - if (file->f_flags & O_DIRECT) - return -EINVAL; - err = generic_file_open(inode, file); if (err) return err; @@ -932,17 +928,23 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; size_t count = 0; + size_t ocount = 0; ssize_t written = 0; + ssize_t written_buffered = 0; struct inode *inode = mapping->host; ssize_t err; struct iov_iter i; + loff_t endbyte = 0; WARN_ON(iocb->ki_pos != pos); - err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); + ocount = 0; + err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); if (err) return err; + count = ocount; + mutex_lock(&inode->i_mutex); vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); @@ -962,11 +964,41 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, file_update_time(file); - iov_iter_init(&i, iov, nr_segs, count, 0); - written = fuse_perform_write(file, mapping, &i, pos); - if (written >= 0) - iocb->ki_pos = pos + written; + if (file->f_flags & O_DIRECT) { + written = generic_file_direct_write(iocb, iov, &nr_segs, + pos, &iocb->ki_pos, + count, ocount); + if (written < 0 || written == count) + goto out; + pos += written; + count -= written; + + iov_iter_init(&i, iov, nr_segs, count, written); + written_buffered = fuse_perform_write(file, mapping, &i, pos); + if (written_buffered < 0) { + err = written_buffered; + goto out; + } + endbyte = pos + written_buffered - 1; + + err = filemap_write_and_wait_range(file->f_mapping, pos, + endbyte); + if (err) + goto out; + + invalidate_mapping_pages(file->f_mapping, + pos >> PAGE_CACHE_SHIFT, + endbyte >> PAGE_CACHE_SHIFT); + + written += written_buffered; + iocb->ki_pos = pos + written_buffered; + } else { + iov_iter_init(&i, iov, nr_segs, count, 0); + written = fuse_perform_write(file, mapping, &i, pos); + if (written >= 0) + iocb->ki_pos = pos + written; + } out: current->backing_dev_info = NULL; mutex_unlock(&inode->i_mutex); @@ -1101,6 +1133,24 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, return res; } +static ssize_t __fuse_direct_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct inode *inode = file->f_path.dentry->d_inode; + ssize_t res; + + res = generic_write_checks(file, ppos, &count, 0); + if (!res) { + res = fuse_direct_io(file, buf, count, ppos, 1); + if (res > 0) + fuse_write_update_size(inode, *ppos); + } + + fuse_invalidate_attr(inode); + + return res; +} + static ssize_t fuse_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -1112,16 +1162,9 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = generic_write_checks(file, ppos, &count, 0); - if (!res) { - res = fuse_direct_io(file, buf, count, ppos, 1); - if (res > 0) - fuse_write_update_size(inode, *ppos); - } + res = __fuse_direct_write(file, buf, count, ppos); mutex_unlock(&inode->i_mutex); - fuse_invalidate_attr(inode); - return res; } @@ -2077,6 +2120,57 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } +static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov, + unsigned long nr_segs, loff_t *ppos, int rw) +{ + const struct iovec *vector = iov; + ssize_t ret = 0; + + while (nr_segs > 0) { + void __user *base; + size_t len; + ssize_t nr; + + base = vector->iov_base; + len = vector->iov_len; + vector++; + nr_segs--; + + if (rw == WRITE) + nr = __fuse_direct_write(filp, base, len, ppos); + else + nr = fuse_direct_read(filp, base, len, ppos); + + if (nr < 0) { + if (!ret) + ret = nr; + break; + } + ret += nr; + if (nr != len) + break; + } + + return ret; +} + + +static ssize_t +fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, + loff_t offset, unsigned long nr_segs) +{ + ssize_t ret = 0; + struct file *file = NULL; + loff_t pos = 0; + + file = iocb->ki_filp; + pos = offset; + + ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw); + + return ret; +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -2120,6 +2214,7 @@ static const struct address_space_operations fuse_file_aops = { .readpages = fuse_readpages, .set_page_dirty = __set_page_dirty_nobuffers, .bmap = fuse_bmap, + .direct_IO = fuse_direct_IO, }; void fuse_init_file_inode(struct inode *inode) From 4f14faaab4ee46a046b6baff85644be199de718c Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Mon, 28 Nov 2011 11:49:03 -0500 Subject: [PATCH 003/438] xen/blkback: use grant-table.c hypercall wrappers Signed-off-by: Daniel De Graaf Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 0088bf60f368..31743534d1e5 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -321,6 +321,7 @@ struct seg_buf { static void xen_blkbk_unmap(struct pending_req *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; grant_handle_t handle; int ret; @@ -332,25 +333,12 @@ static void xen_blkbk_unmap(struct pending_req *req) gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), GNTMAP_host_map, handle); pending_handle(req, i) = BLKBACK_INVALID_HANDLE; + pages[invcount] = virt_to_page(vaddr(req, i)); invcount++; } - ret = HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, invcount); + ret = gnttab_unmap_refs(unmap, pages, invcount, false); BUG_ON(ret); - /* - * Note, we use invcount, so nr->pages, so we can't index - * using vaddr(req, i). - */ - for (i = 0; i < invcount; i++) { - ret = m2p_remove_override( - virt_to_page(unmap[i].host_addr), false); - if (ret) { - pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n", - (unsigned long)unmap[i].host_addr); - continue; - } - } } static int xen_blkbk_map(struct blkif_request *req, @@ -378,7 +366,7 @@ static int xen_blkbk_map(struct blkif_request *req, pending_req->blkif->domid); } - ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg); BUG_ON(ret); /* @@ -398,15 +386,6 @@ static int xen_blkbk_map(struct blkif_request *req, if (ret) continue; - ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), - blkbk->pending_page(pending_req, i), NULL); - if (ret) { - pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n", - (unsigned long)map[i].dev_bus_addr, ret); - /* We could switch over to GNTTABOP_copy */ - continue; - } - seg[i].buf = map[i].dev_bus_addr | (req->u.rw.seg[i].first_sect << 9); } From b2167ba6dd89d55ced26a867fad8f0fe388fd595 Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Mon, 28 Nov 2011 11:49:05 -0500 Subject: [PATCH 004/438] xen/blkback: Enable blkback on HVM guests Signed-off-by: Daniel De Graaf Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 31743534d1e5..70caa8969972 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -809,7 +809,7 @@ static int __init xen_blkif_init(void) int i, mmap_pages; int rc = 0; - if (!xen_pv_domain()) + if (!xen_domain()) return -ENODEV; blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); From 34ae2e47d97216d8c66a1c5dff5b530c29b746b8 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 21 Jan 2012 00:15:26 +0900 Subject: [PATCH 005/438] xen-blkfront: use bitmap_set() and bitmap_clear() Use bitmap_set and bitmap_clear rather than modifying individual bits in a memory region. Signed-off-by: Akinobu Mita Cc: Jeremy Fitzhardinge Cc: Konrad Rzeszutek Wilk Cc: xen-devel@lists.xensource.com Cc: virtualization@lists.linux-foundation.org Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2f22874c0a37..619868d91ca8 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -177,8 +178,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) spin_lock(&minor_lock); if (find_next_bit(minors, end, minor) >= end) { - for (; minor < end; ++minor) - __set_bit(minor, minors); + bitmap_set(minors, minor, nr); rc = 0; } else rc = -EBUSY; @@ -193,8 +193,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr) BUG_ON(end > nr_minors); spin_lock(&minor_lock); - for (; minor < end; ++minor) - __clear_bit(minor, minors); + bitmap_clear(minors, minor, nr); spin_unlock(&minor_lock); } From dad5cf659b202b5070c8616b5c515f6ca4db0c42 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 16 Feb 2012 13:16:25 +0100 Subject: [PATCH 006/438] xen/blkfront: don't put bdev right after getting it We should hang onto bdev until we're done with it. Signed-off-by: Andrew Jones [v1: Fixed up git commit description] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 619868d91ca8..537cb722a211 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1409,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) mutex_lock(&blkfront_mutex); bdev = bdget_disk(disk, 0); - bdput(bdev); if (bdev->bd_openers) goto out; @@ -1440,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) } out: + bdput(bdev); mutex_unlock(&blkfront_mutex); return 0; } From 3467811e26660eb46bc655234573d22d6876d5f9 Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Fri, 17 Feb 2012 12:04:44 -0800 Subject: [PATCH 007/438] xen-blkfront: make blkif_io_lock spinlock per-device This patch moves the global blkif_io_lock to the per-device structure. The spinlock seems to exists for two reasons: to disable IRQs when in the interrupt handlers for blkfront, and to protect the blkfront VBDs when a detachment is requested. Having a global blkif_io_lock doesn't make sense given the use case, and it drastically hinders performance due to contention. All VBDs with pending IOs have to take the lock in order to get work done, which serializes everything pretty badly. Signed-off-by: Steven Noonan Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 537cb722a211..5d9c559f1877 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -82,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops; */ struct blkfront_info { + spinlock_t io_lock; struct mutex mutex; struct xenbus_device *xbdev; struct gendisk *gd; @@ -106,8 +107,6 @@ struct blkfront_info int is_ready; }; -static DEFINE_SPINLOCK(blkif_io_lock); - static unsigned int nr_minors; static unsigned long *minors; static DEFINE_SPINLOCK(minor_lock); @@ -418,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) struct request_queue *rq; struct blkfront_info *info = gd->private_data; - rq = blk_init_queue(do_blkif_request, &blkif_io_lock); + rq = blk_init_queue(do_blkif_request, &info->io_lock); if (rq == NULL) return -1; @@ -635,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) if (info->rq == NULL) return; - spin_lock_irqsave(&blkif_io_lock, flags); + spin_lock_irqsave(&info->io_lock, flags); /* No more blkif_request(). */ blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irqrestore(&blkif_io_lock, flags); + spin_unlock_irqrestore(&info->io_lock, flags); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -674,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work) { struct blkfront_info *info = container_of(work, struct blkfront_info, work); - spin_lock_irq(&blkif_io_lock); + spin_lock_irq(&info->io_lock); if (info->connected == BLKIF_STATE_CONNECTED) kick_pending_request_queues(info); - spin_unlock_irq(&blkif_io_lock); + spin_unlock_irq(&info->io_lock); } static void blkif_free(struct blkfront_info *info, int suspend) { /* Prevent new requests being issued until we fix things up. */ - spin_lock_irq(&blkif_io_lock); + spin_lock_irq(&info->io_lock); info->connected = suspend ? BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; /* No more blkif_request(). */ @@ -691,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irq(&blkif_io_lock); + spin_unlock_irq(&info->io_lock); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -727,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) struct blkfront_info *info = (struct blkfront_info *)dev_id; int error; - spin_lock_irqsave(&blkif_io_lock, flags); + spin_lock_irqsave(&info->io_lock, flags); if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { - spin_unlock_irqrestore(&blkif_io_lock, flags); + spin_unlock_irqrestore(&info->io_lock, flags); return IRQ_HANDLED; } @@ -815,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) kick_pending_request_queues(info); - spin_unlock_irqrestore(&blkif_io_lock, flags); + spin_unlock_irqrestore(&info->io_lock, flags); return IRQ_HANDLED; } @@ -990,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev, } mutex_init(&info->mutex); + spin_lock_init(&info->io_lock); info->xbdev = dev; info->vdevice = vdevice; info->connected = BLKIF_STATE_DISCONNECTED; @@ -1067,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); - spin_lock_irq(&blkif_io_lock); + spin_lock_irq(&info->io_lock); /* Now safe for us to use the shared ring */ info->connected = BLKIF_STATE_CONNECTED; @@ -1078,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info) /* Kick any other new requests queued since we resumed */ kick_pending_request_queues(info); - spin_unlock_irq(&blkif_io_lock); + spin_unlock_irq(&info->io_lock); return 0; } @@ -1276,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); /* Kick pending requests. */ - spin_lock_irq(&blkif_io_lock); + spin_lock_irq(&info->io_lock); info->connected = BLKIF_STATE_CONNECTED; kick_pending_request_queues(info); - spin_unlock_irq(&blkif_io_lock); + spin_unlock_irq(&info->io_lock); add_disk(info->gd); From 395d287526bb60411ff37b19ad9dd38b58ba8732 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 22 Mar 2012 21:40:08 +0100 Subject: [PATCH 008/438] cciss: Initialize scsi host max_sectors for tape drive support The default is too small (1024 blocks), use h->cciss_max_sectors (8192 blocks) Without this change, if you try to set the block size of a tape drive above 512*1024, via "mt -f /dev/st0 setblk nnn" where nnn is greater than 524288, it won't work right. Signed-off-by: Stephen M. Cameron Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe --- drivers/block/cciss_scsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index e820b68d2f6c..f510a9c9a6fd 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -866,6 +866,7 @@ cciss_scsi_detect(ctlr_info_t *h) sh->can_queue = cciss_tape_cmds; sh->sg_tablesize = h->maxsgentries; sh->max_cmd_len = MAX_COMMAND_SIZE; + sh->max_sectors = h->cciss_max_sectors; ((struct cciss_scsi_adapter_data_t *) h->scsi_ctlr)->scsi_host = sh; From bc67f63650fad6b3478d9ddfd5406d45a95987c9 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 22 Mar 2012 21:40:09 +0100 Subject: [PATCH 009/438] cciss: Fix scsi tape io with more than 255 scatter gather elements The total number of scatter gather elements in the CISS command used by the scsi tape code was being cast to a u8, which can hold at most 255 scatter gather elements. It should have been cast to a u16. Without this patch the command gets rejected by the controller since the total scatter gather count did not add up to the right value resulting in an i/o error. Signed-off-by: Stephen M. Cameron Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe --- drivers/block/cciss_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index f510a9c9a6fd..acda773b3720 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1411,7 +1411,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, /* track how many SG entries we are using */ if (request_nsgs > h->maxSG) h->maxSG = request_nsgs; - c->Header.SGTotal = (__u8) request_nsgs + chained; + c->Header.SGTotal = (u16) request_nsgs + chained; if (request_nsgs > h->max_cmd_sgentries) c->Header.SGList = h->max_cmd_sgentries; else From 00380a404fc4235e9b8b39598138bd3223a27b8a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Mar 2012 09:58:54 +0100 Subject: [PATCH 010/438] block: blk_alloc_queue_node(): use caller's GFP flags instead of GFP_KERNEL We should use the GFP flags that the caller specified instead of picking our own. All the callers specify GFP_KERNEL so this doesn't make a difference to how the kernel runs, it's just a cleanup. Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe --- block/blk-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 3a78b00edd71..414e8224588f 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) if (!q) return NULL; - q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL); + q->id = ida_simple_get(&blk_queue_ida, 0, 0, gfp_mask); if (q->id < 0) goto fail_q; From 22be2e6e13ac09b20000582ac34d47fb0029a6da Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Fri, 23 Mar 2012 12:33:03 +0100 Subject: [PATCH 011/438] mtip32xx: fix incorrect value set for drv_cleanup_done, and re-initialize and start port in mtip_restart_port() This patch includes two changes: * fix incorrect value set for drv_cleanup_done * re-initialize and start port in mtip_restart_port() Signed-off-by: Asai Thambi S P Signed-off-by: Sam Bradshaw Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 8eb81c96608f..04f69e6da1fe 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -422,6 +422,10 @@ static void mtip_init_port(struct mtip_port *port) /* Clear any pending interrupts for this port */ writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); + /* Clear any pending interrupts on the HBA. */ + writel(readl(port->dd->mmio + HOST_IRQ_STAT), + port->dd->mmio + HOST_IRQ_STAT); + /* Enable port interrupts */ writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); } @@ -490,11 +494,9 @@ static void mtip_restart_port(struct mtip_port *port) dev_warn(&port->dd->pdev->dev, "COM reset failed\n"); - /* Clear SError, the PxSERR.DIAG.x should be set so clear it */ - writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); + mtip_init_port(port); + mtip_start_port(port); - /* Enable the DMA engine */ - mtip_enable_engine(port, 1); } /* @@ -3359,9 +3361,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, return -ENOMEM; } - /* Set the atomic variable as 1 in case of SRSI */ - atomic_set(&dd->drv_cleanup_done, true); - atomic_set(&dd->resumeflag, false); /* Attach the private data to this PCI device. */ @@ -3434,8 +3433,8 @@ iomap_err: pci_set_drvdata(pdev, NULL); return rv; done: - /* Set the atomic variable as 0 in case of SRSI */ - atomic_set(&dd->drv_cleanup_done, true); + /* Set the atomic variable as 0 */ + atomic_set(&dd->drv_cleanup_done, false); return rv; } @@ -3463,8 +3462,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) } } } - /* Set the atomic variable as 1 in case of SRSI */ - atomic_set(&dd->drv_cleanup_done, true); /* Clean up the block layer. */ mtip_block_remove(dd); From 4dae76705fc8f9854bb732f9944e7ff9ba7a8e9f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 13 Mar 2012 18:43:23 -0400 Subject: [PATCH 012/438] xen/blkback: Squash the discard support for 'file' and 'phy' type. The only reason for the distinction was for the special case of 'file' (which is assumed to be loopback device), was to reach inside the loopback device, find the underlaying file, and call fallocate on it. Fortunately "xen-blkback: convert hole punching to discard request on loop devices" removes that use-case and we now based the discard support based on blk_queue_discard(q) and extract all appropriate parameters from the 'struct request_queue'. CC: Li Dongyang Acked-by: Jan Beulich [v1: Dropping pointless initializer and keeping blank line] [v2: Remove the kfree as it is not used anymore] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 19 ++++---- drivers/block/xen-blkback/common.h | 6 --- drivers/block/xen-blkback/xenbus.c | 70 +++++++++++------------------ 3 files changed, 34 insertions(+), 61 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 70caa8969972..73f196ca713f 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -398,21 +398,18 @@ static int dispatch_discard_io(struct xen_blkif *blkif, int err = 0; int status = BLKIF_RSP_OKAY; struct block_device *bdev = blkif->vbd.bdev; + unsigned long secure; blkif->st_ds_req++; xen_blkif_get(blkif); - if (blkif->blk_backend_type == BLKIF_BACKEND_PHY || - blkif->blk_backend_type == BLKIF_BACKEND_FILE) { - unsigned long secure = (blkif->vbd.discard_secure && - (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? - BLKDEV_DISCARD_SECURE : 0; - err = blkdev_issue_discard(bdev, - req->u.discard.sector_number, - req->u.discard.nr_sectors, - GFP_KERNEL, secure); - } else - err = -EOPNOTSUPP; + secure = (blkif->vbd.discard_secure && + (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? + BLKDEV_DISCARD_SECURE : 0; + + err = blkdev_issue_discard(bdev, req->u.discard.sector_number, + req->u.discard.nr_sectors, + GFP_KERNEL, secure); if (err == -EOPNOTSUPP) { pr_debug(DRV_PFX "discard op failed, not supported\n"); diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index d0ee7edc9be8..773cf27dc23f 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -146,11 +146,6 @@ enum blkif_protocol { BLKIF_PROTOCOL_X86_64 = 3, }; -enum blkif_backend_type { - BLKIF_BACKEND_PHY = 1, - BLKIF_BACKEND_FILE = 2, -}; - struct xen_vbd { /* What the domain refers to this vbd as. */ blkif_vdev_t handle; @@ -177,7 +172,6 @@ struct xen_blkif { unsigned int irq; /* Comms information. */ enum blkif_protocol blk_protocol; - enum blkif_backend_type blk_backend_type; union blkif_back_rings blk_rings; void *blk_ring; /* The VBD attached to this interface. */ diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 24a2fb57e5d0..d417c13e027e 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -390,61 +390,43 @@ int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) { struct xenbus_device *dev = be->dev; struct xen_blkif *blkif = be->blkif; - char *type; int err; int state = 0; + struct block_device *bdev = be->blkif->vbd.bdev; + struct request_queue *q = bdev_get_queue(bdev); - type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL); - if (!IS_ERR(type)) { - if (strncmp(type, "file", 4) == 0) { - state = 1; - blkif->blk_backend_type = BLKIF_BACKEND_FILE; + if (blk_queue_discard(q)) { + err = xenbus_printf(xbt, dev->nodename, + "discard-granularity", "%u", + q->limits.discard_granularity); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-granularity"); + goto out; } - if (strncmp(type, "phy", 3) == 0) { - struct block_device *bdev = be->blkif->vbd.bdev; - struct request_queue *q = bdev_get_queue(bdev); - if (blk_queue_discard(q)) { - err = xenbus_printf(xbt, dev->nodename, - "discard-granularity", "%u", - q->limits.discard_granularity); - if (err) { - xenbus_dev_fatal(dev, err, - "writing discard-granularity"); - goto kfree; - } - err = xenbus_printf(xbt, dev->nodename, - "discard-alignment", "%u", - q->limits.discard_alignment); - if (err) { - xenbus_dev_fatal(dev, err, - "writing discard-alignment"); - goto kfree; - } - state = 1; - blkif->blk_backend_type = BLKIF_BACKEND_PHY; - } - /* Optional. */ - err = xenbus_printf(xbt, dev->nodename, - "discard-secure", "%d", - blkif->vbd.discard_secure); - if (err) { - xenbus_dev_fatal(dev, err, + err = xenbus_printf(xbt, dev->nodename, + "discard-alignment", "%u", + q->limits.discard_alignment); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-alignment"); + goto out; + } + state = 1; + /* Optional. */ + err = xenbus_printf(xbt, dev->nodename, + "discard-secure", "%d", + blkif->vbd.discard_secure); + if (err) { + xenbus_dev_fatal(dev, err, "writting discard-secure"); - goto kfree; - } + goto out; } - } else { - err = PTR_ERR(type); - xenbus_dev_fatal(dev, err, "reading type"); - goto out; } - err = xenbus_printf(xbt, dev->nodename, "feature-discard", "%d", state); if (err) xenbus_dev_fatal(dev, err, "writing feature-discard"); -kfree: - kfree(type); out: return err; } From 3389bb8bf76180eecaffdfa7dd5b35fa4a2ce9b5 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 14 Mar 2012 13:04:00 -0400 Subject: [PATCH 013/438] xen/blkback: Make optional features be really optional. They were using the xenbus_dev_fatal() function which would change the state of the connection immediately. Which is not what we want when we advertise optional features. So make 'feature-discard','feature-barrier','feature-flush-cache' optional. Suggested-by: Jan Beulich [v1: Made the discard function void and static] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/xenbus.c | 37 ++++++++++++------------------ 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index d417c13e027e..89860f34a7ec 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -381,12 +381,12 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache", "%d", state); if (err) - xenbus_dev_fatal(dev, err, "writing feature-flush-cache"); + dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err); return err; } -int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) +static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) { struct xenbus_device *dev = be->dev; struct xen_blkif *blkif = be->blkif; @@ -400,17 +400,15 @@ int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) "discard-granularity", "%u", q->limits.discard_granularity); if (err) { - xenbus_dev_fatal(dev, err, - "writing discard-granularity"); - goto out; + dev_warn(&dev->dev, "writing discard-granularity (%d)", err); + return; } err = xenbus_printf(xbt, dev->nodename, "discard-alignment", "%u", q->limits.discard_alignment); if (err) { - xenbus_dev_fatal(dev, err, - "writing discard-alignment"); - goto out; + dev_warn(&dev->dev, "writing discard-alignment (%d)", err); + return; } state = 1; /* Optional. */ @@ -418,17 +416,14 @@ int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) "discard-secure", "%d", blkif->vbd.discard_secure); if (err) { - xenbus_dev_fatal(dev, err, - "writting discard-secure"); - goto out; + dev_warn(dev-dev, "writing discard-secure (%d)", err); + return; } } err = xenbus_printf(xbt, dev->nodename, "feature-discard", "%d", state); if (err) - xenbus_dev_fatal(dev, err, "writing feature-discard"); -out: - return err; + dev_warn(&dev->dev, "writing feature-discard (%d)", err); } int xen_blkbk_barrier(struct xenbus_transaction xbt, struct backend_info *be, int state) @@ -439,7 +434,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-barrier", "%d", state); if (err) - xenbus_dev_fatal(dev, err, "writing feature-barrier"); + dev_warn(&dev->dev, "writing feature-barrier (%d)", err); return err; } @@ -671,14 +666,12 @@ again: return; } - err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); - if (err) - goto abort; - - err = xen_blkbk_discard(xbt, be); - /* If we can't advertise it is OK. */ - err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); + xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); + + xen_blkbk_discard(xbt, be); + + xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", (unsigned long long)vbd_sz(&be->blkif->vbd)); From e9986f303dc0f285401de28cf96f42f4dd23a4a1 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 29 Mar 2012 10:09:44 +0200 Subject: [PATCH 014/438] virtio-blk: Call revalidate_disk() upon online disk resize If a virtio disk is open in guest and a disk resize operation is done, (virsh blockresize), new size is not visible to tools like "fdisk -l". This seems to be happening as we update only part->nr_sects and not bdev->bd_inode size. Call revalidate_disk() which should take care of it. I tested growing disk size of already open disk and it works for me. Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe --- drivers/block/virtio_blk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c4a60badf252..0e4ef3de9d5d 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -351,6 +351,7 @@ static void virtblk_config_changed_work(struct work_struct *work) cap_str_10, cap_str_2); set_capacity(vblk->disk, capacity); + revalidate_disk(vblk->disk); done: mutex_unlock(&vblk->config_lock); } From 8bcb6c7d48eb341b1f49f814cdcbe05eb6f15680 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 30 Mar 2012 12:33:28 +0200 Subject: [PATCH 015/438] block: use lockdep_assert_held for queue locking Instead of an ugly open coded variant. Cc: axboe@kernel.dk Signed-off-by: Andi Kleen Signed-off-by: Jens Axboe --- block/blk-throttle.c | 2 +- include/linux/blkdev.h | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 5eed6a76721d..f2ddb94626bd 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q) struct bio_list bl; struct bio *bio; - WARN_ON_ONCE(!queue_is_locked(q)); + queue_lockdep_assert_held(q); bio_list_init(&bl); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 606cf339bb56..2aa24664a5b5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -426,14 +426,10 @@ struct request_queue { (1 << QUEUE_FLAG_SAME_COMP) | \ (1 << QUEUE_FLAG_ADD_RANDOM)) -static inline int queue_is_locked(struct request_queue *q) +static inline void queue_lockdep_assert_held(struct request_queue *q) { -#ifdef CONFIG_SMP - spinlock_t *lock = q->queue_lock; - return lock && spin_is_locked(lock); -#else - return 1; -#endif + if (q->queue_lock) + lockdep_assert_held(q->queue_lock); } static inline void queue_flag_set_unlocked(unsigned int flag, @@ -445,7 +441,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag, static inline int queue_flag_test_and_clear(unsigned int flag, struct request_queue *q) { - WARN_ON_ONCE(!queue_is_locked(q)); + queue_lockdep_assert_held(q); if (test_bit(flag, &q->queue_flags)) { __clear_bit(flag, &q->queue_flags); @@ -458,7 +454,7 @@ static inline int queue_flag_test_and_clear(unsigned int flag, static inline int queue_flag_test_and_set(unsigned int flag, struct request_queue *q) { - WARN_ON_ONCE(!queue_is_locked(q)); + queue_lockdep_assert_held(q); if (!test_bit(flag, &q->queue_flags)) { __set_bit(flag, &q->queue_flags); @@ -470,7 +466,7 @@ static inline int queue_flag_test_and_set(unsigned int flag, static inline void queue_flag_set(unsigned int flag, struct request_queue *q) { - WARN_ON_ONCE(!queue_is_locked(q)); + queue_lockdep_assert_held(q); __set_bit(flag, &q->queue_flags); } @@ -487,7 +483,7 @@ static inline int queue_in_flight(struct request_queue *q) static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) { - WARN_ON_ONCE(!queue_is_locked(q)); + queue_lockdep_assert_held(q); __clear_bit(flag, &q->queue_flags); } From 2cee5715a926ad23d3f52ffd7da3ad38f54664dd Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Fri, 30 Mar 2012 15:26:57 +0200 Subject: [PATCH 016/438] HID: tivo: fix support for bluetooth version of tivo Slide The device is a bluetooth device, but one occurence by mistake had marked it as USB. Reported-by: Joshua Dillon Signed-off-by: Jiri Kosina --- drivers/hid/hid-tivo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c index de47039c708c..9f85f827607f 100644 --- a/drivers/hid/hid-tivo.c +++ b/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id tivo_devices[] = { /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ - { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, { } }; From aa2bf9bc6414b6972b9e51903c1ce7b1f057aee2 Mon Sep 17 00:00:00 2001 From: Sasikantha babu Date: Wed, 21 Mar 2012 20:10:54 +0530 Subject: [PATCH 017/438] itimer: Schedule silent NULL pointer fixup in setitimer() for removal setitimer() should return -EFAULT if called with an invalid pointer for value. The current code excludes a NULL pointer from this rule and silently uses it to stop the timer. This violates the spec. Warn about user space apps which rely on that feature and schedule it for removal. [ tglx: Massaged changelog, warn message and Doc entry ] Signed-off-by: Sasikantha babu Link: http://lkml.kernel.org/r/1332340854-26053-1-git-send-email-sasikanth.v19@gmail.com Signed-off-by: Thomas Gleixner --- Documentation/feature-removal-schedule.txt | 8 ++++++++ kernel/itimer.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 0cad4803ffac..32fae81228f2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -529,3 +529,11 @@ When: 3.5 Why: The old kmap_atomic() with two arguments is deprecated, we only keep it for backward compatibility for few cycles and then drop it. Who: Cong Wang + +---------------------------- + +What: setitimer accepts user NULL pointer (value) +When: 3.6 +Why: setitimer is not returning -EFAULT if user pointer is NULL. This + violates the spec. +Who: Sasikantha Babu diff --git a/kernel/itimer.c b/kernel/itimer.c index 22000c3db0dd..c70369a74b5a 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -284,8 +284,11 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, if (value) { if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) return -EFAULT; - } else + } else { memset((char *) &set_buffer, 0, sizeof(set_buffer)); + WARN_ONCE(1, "setitimer: new_value pointer is NULL." + " Misfeature support will be removed\n"); + } error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); if (error || !ovalue) From cb85a6ed67e979c59a29b7b4e8217e755b951cf4 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 30 Mar 2012 12:23:08 +0200 Subject: [PATCH 018/438] proc: stats: Use arch_idle_time for idle and iowait times if available Git commit a25cac5198d4ff28 "proc: Consider NO_HZ when printing idle and iowait times" changes the code for /proc/stat to use get_cpu_idle_time_us and get_cpu_iowait_time_us if the system is running with nohz enabled. For architectures which define arch_idle_time (currently s390 only) this is a change for the worse. The result of arch_idle_time is supposed to be the exact sleep time of the target cpu and should be used instead of the value kept by the scheduler. Signed-off-by: Martin Schwidefsky Reviewed-by: Michal Hocko Reviewed-by: Srivatsa S. Bhat Link: http://lkml.kernel.org/r/20120330122308.18720283@de.ibm.com Signed-off-by: Thomas Gleixner --- fs/proc/stat.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 6a0c62d6e442..64c3b3172367 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c @@ -18,19 +18,39 @@ #ifndef arch_irq_stat #define arch_irq_stat() 0 #endif -#ifndef arch_idle_time -#define arch_idle_time(cpu) 0 -#endif + +#ifdef arch_idle_time + +static cputime64_t get_idle_time(int cpu) +{ + cputime64_t idle; + + idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; + if (cpu_online(cpu) && !nr_iowait_cpu(cpu)) + idle += arch_idle_time(cpu); + return idle; +} + +static cputime64_t get_iowait_time(int cpu) +{ + cputime64_t iowait; + + iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; + if (cpu_online(cpu) && nr_iowait_cpu(cpu)) + iowait += arch_idle_time(cpu); + return iowait; +} + +#else static u64 get_idle_time(int cpu) { u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); - if (idle_time == -1ULL) { + if (idle_time == -1ULL) /* !NO_HZ so we can rely on cpustat.idle */ idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; - idle += arch_idle_time(cpu); - } else + else idle = usecs_to_cputime64(idle_time); return idle; @@ -49,6 +69,8 @@ static u64 get_iowait_time(int cpu) return iowait; } +#endif + static int show_stat(struct seq_file *p, void *v) { int i, j; From 327ef2e9048a5e39bf84d7f17f78a87e7a068742 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 23 Mar 2012 13:05:48 +0530 Subject: [PATCH 019/438] spi/pL022: include types.h to remove compilation warnings linux/pl022.h uses definitions like, u8, u16, etc, which have dependency of types.h file, which isn't included in it. So, we get compilation warnings. This patch includes types.h there to fix these warnings. Signed-off-by: Viresh Kumar Acked-by: Linus Walleij Signed-off-by: Grant Likely --- include/linux/amba/pl022.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index b8c51124ed19..76dd1b199a1b 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -25,6 +25,8 @@ #ifndef _SSP_PL022_H #define _SSP_PL022_H +#include + /** * whether SSP is in loopback mode or not */ From 9232b9b1b57dc5c01f435433e70e26c122bf4e44 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Tue, 20 Mar 2012 16:10:09 +0530 Subject: [PATCH 020/438] spi/davinci: Fix DMA API usage in davinci The driver uses NULL for dma_unmap_single instead of the struct device that the API expects. Signed-off-by: Shubhrajyoti D Tested-by: Akshay Shankarmurthy Signed-off-by: Grant Likely --- drivers/spi/spi-davinci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 31bfba805cf4..9b2901feaf78 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -653,7 +653,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n", rx_buf_count); if (t->tx_buf) - dma_unmap_single(NULL, t->tx_dma, t->len, + dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE); return -ENOMEM; } @@ -692,10 +692,10 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) if (spicfg->io_type == SPI_IO_TYPE_DMA) { if (t->tx_buf) - dma_unmap_single(NULL, t->tx_dma, t->len, + dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE); - dma_unmap_single(NULL, t->rx_dma, rx_buf_count, + dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count, DMA_FROM_DEVICE); clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN); From 5039a86973cd35bdb2f64d28ee12f13fe2bb5a4c Mon Sep 17 00:00:00 2001 From: Kenth Eriksson Date: Fri, 30 Mar 2012 17:05:30 +0200 Subject: [PATCH 021/438] spi/mpc83xx: fix NULL pdata dereference bug Commit 178db7d3, "spi: Fix device unregistration when unregistering the bus master", changed device initialization to be children of the bus master, not children of the bus masters parent device. The pdata pointer used in fsl_spi_chipselect must updated to reflect the changed initialization. Signed-off-by: Kenth Eriksson Acked-by: Joakim Tjernlund Signed-off-by: Grant Likely --- drivers/spi/spi-fsl-spi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 24cacff57786..5f748c0d96bd 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -139,10 +139,12 @@ static void fsl_spi_change_mode(struct spi_device *spi) static void fsl_spi_chipselect(struct spi_device *spi, int value) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; + struct fsl_spi_platform_data *pdata; bool pol = spi->mode & SPI_CS_HIGH; struct spi_mpc8xxx_cs *cs = spi->controller_state; + pdata = spi->dev.parent->parent->platform_data; + if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) pdata->cs_control(spi, !pol); From cc4d22ae541ccd989ef163c46a38afde131e1644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 29 Mar 2012 21:54:18 +0200 Subject: [PATCH 022/438] spi/imx: mark base member in spi_imx_data as __iomem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes 36 sparse warnings like: drivers/spi/spi-imx.c:143:1: warning: incorrect type in argument 1 (different address spaces) drivers/spi/spi-imx.c:143:1: expected void const volatile [noderef] * drivers/spi/spi-imx.c:143:1: got void * Signed-off-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 31054e3de4c1..373f4fff9358 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -83,7 +83,7 @@ struct spi_imx_data { struct spi_bitbang bitbang; struct completion xfer_done; - void *base; + void __iomem *base; int irq; struct clk *clk; unsigned long spi_clk; From 3872c48b14259d8c0a00c9fff06a4a4123f7f4eb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 31 Mar 2012 12:45:43 +0200 Subject: [PATCH 023/438] tick: Document TICK_ONESHOT config option This option has been selected from arch code as it was assumed that it's necessary to support oneshot mode clockevent devices. But it's just a core internal helper to compile tick-oneshot.c if NOHZ or HIG_RES_TIMERS are selected. Reported-by: Russell King Signed-off-by: Thomas Gleixner --- kernel/time/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 2cf9cc7aa103..a20dc8a3c949 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -1,6 +1,10 @@ # # Timer subsystem related configuration options # + +# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is +# only related to the tick functionality. Oneshot clockevent devices +# are supported independ of this. config TICK_ONESHOT bool From 5bf14c0727a07ded1bd9fa6d77923d7e6dc32833 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Sun, 1 Apr 2012 14:33:39 -0700 Subject: [PATCH 024/438] block: Make cfq_target_latency tunable through sysfs. In cfq, when we calculate a time slice for a process(or a cfqq to be precise), we have to consider the cfq_target_latency so that all the sync request have an estimated latency(300ms) and it is controlled by cfq_target_latency. But in some hadoop test, we have found that if there are many processes doing sequential read(24 for example), the throughput is bad because every process can only work for about 25ms and the cfqq is switched. That leads to a higher disk seek. We can achive the good throughput by setting low_latency=0, but then some read's latency is too much for the application. So this patch makes cfq_target_latency tunable through sysfs so that we can tune it and find some magic number which is not bad for both the throughput and the read latency. Cc: Jens Axboe Signed-off-by: Tao Ma Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 457295253566..3c38536bd52c 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -295,6 +295,7 @@ struct cfq_data { unsigned int cfq_slice_idle; unsigned int cfq_group_idle; unsigned int cfq_latency; + unsigned int cfq_target_latency; /* * Fallback dummy cfqq for extreme OOM conditions @@ -604,7 +605,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg) { struct cfq_rb_root *st = &cfqd->grp_service_tree; - return cfq_target_latency * cfqg->weight / st->total_weight; + return cfqd->cfq_target_latency * cfqg->weight / st->total_weight; } static inline unsigned @@ -2271,7 +2272,8 @@ new_workload: * to have higher weight. A more accurate thing would be to * calculate system wide asnc/sync ratio. */ - tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg); + tmp = cfqd->cfq_target_latency * + cfqg_busy_async_queues(cfqd, cfqg); tmp = tmp/cfqd->busy_queues; slice = min_t(unsigned, slice, tmp); @@ -3737,6 +3739,7 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_back_penalty = cfq_back_penalty; cfqd->cfq_slice[0] = cfq_slice_async; cfqd->cfq_slice[1] = cfq_slice_sync; + cfqd->cfq_target_latency = cfq_target_latency; cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; cfqd->cfq_group_idle = cfq_group_idle; @@ -3788,6 +3791,7 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); +SHOW_FUNCTION(cfq_target_latency_show, cfqd->cfq_target_latency, 1); #undef SHOW_FUNCTION #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ @@ -3821,6 +3825,7 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); +STORE_FUNCTION(cfq_target_latency_store, &cfqd->cfq_target_latency, 1, UINT_MAX, 1); #undef STORE_FUNCTION #define CFQ_ATTR(name) \ @@ -3838,6 +3843,7 @@ static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(slice_idle), CFQ_ATTR(group_idle), CFQ_ATTR(low_latency), + CFQ_ATTR(target_latency), __ATTR_NULL }; From 407ac95e2271a310016ced97f407676e79c53c06 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Sun, 1 Apr 2012 14:33:40 -0700 Subject: [PATCH 025/438] Documentation: Add sysfs ABI change for cfq's target latency. Cc: Jens Axboe Cc: Greg Kroah-Hartman Signed-off-by: Tao Ma Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-cfq-target-latency | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-cfq-target-latency diff --git a/Documentation/ABI/testing/sysfs-cfq-target-latency b/Documentation/ABI/testing/sysfs-cfq-target-latency new file mode 100644 index 000000000000..df0f7828c5e3 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-cfq-target-latency @@ -0,0 +1,8 @@ +What: /sys/block//iosched/target_latency +Date: March 2012 +contact: Tao Ma +Description: + The /sys/block//iosched/target_latency only exists + when the user sets cfq to /sys/block//scheduler. + It contains an estimated latency time for the cfq. cfq will + use it to calculate the time slice used for every task. From 7b78f13603c6fcb64e020a0bbe31a651ea2b657b Mon Sep 17 00:00:00 2001 From: Markus Trippelsdorf Date: Wed, 4 Apr 2012 10:45:27 +0200 Subject: [PATCH 026/438] perf tools: Fix getrusage() related build failure on glibc trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a system running glibc trunk perf doesn't build: CC builtin-sched.o builtin-sched.c: In function ‘get_cpu_usage_nsec_parent’: builtin-sched.c:399:16: error: storage size of ‘ru’ isn’t known builtin-sched.c:403:2: error: implicit declaration of function ‘getrusage’ [-Werror=implicit-function-declaration] [...] Fix it by including sys/resource.h. Signed-off-by: Markus Trippelsdorf Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120404084527.GA294@x4 Signed-off-by: Ingo Molnar --- tools/perf/builtin-sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index fb8b5f83b4a0..1cad3af4bf4c 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -17,6 +17,7 @@ #include "util/debug.h" #include +#include #include #include From 25c3d30c918207556ae1d6e663150ebdf902186b Mon Sep 17 00:00:00 2001 From: Kent Yoder Date: Thu, 5 Apr 2012 20:34:20 +0800 Subject: [PATCH 027/438] crypto: sha512 - Fix byte counter overflow in SHA-512 The current code only increments the upper 64 bits of the SHA-512 byte counter when the number of bytes hashed happens to hit 2^64 exactly. This patch increments the upper 64 bits whenever the lower 64 bits overflows. Signed-off-by: Kent Yoder Cc: stable@kernel.org Signed-off-by: Herbert Xu --- crypto/sha512_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 107f6f7be5e1..dd30f40af9f5 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) index = sctx->count[0] & 0x7f; /* Update number of bytes */ - if (!(sctx->count[0] += len)) + if ((sctx->count[0] += len) < len) sctx->count[1]++; part_len = 128 - index; From 75258723dadd99a214f00bff34fa0fc6e7b6d463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Wr=C3=B3bel?= Date: Thu, 5 Apr 2012 20:34:21 +0800 Subject: [PATCH 028/438] crypto: ixp4xx - include fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before commit de47725421ad5627a5c905f4e40bb844ebc06d29 ("include: replace linux/module.h with "struct module" wherever possible") was implicitly included through -> . Signed-off-by: Michał Wróbel Signed-off-by: Herbert Xu --- drivers/crypto/ixp4xx_crypto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 0053d7ebb5ca..8f3f74ce8c7f 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include From 6d27f09a6398ee086b11804aa3a16609876f0c7c Mon Sep 17 00:00:00 2001 From: Ryosuke Saito Date: Thu, 5 Apr 2012 08:09:34 -0600 Subject: [PATCH 029/438] mtip32xx: fix error handling in mtip_init() Ensure that block device is properly unregistered, if pci_register_driver() fails. Signed-off-by: Ryosuke Saito Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 04f69e6da1fe..c37073ddf7d4 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -3605,18 +3605,25 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl); */ static int __init mtip_init(void) { + int error; + printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); /* Allocate a major block device number to use with this driver. */ - mtip_major = register_blkdev(0, MTIP_DRV_NAME); - if (mtip_major < 0) { + error = register_blkdev(0, MTIP_DRV_NAME); + if (error <= 0) { printk(KERN_ERR "Unable to register block device (%d)\n", - mtip_major); + error); return -EBUSY; } + mtip_major = error; /* Register our PCI operations. */ - return pci_register_driver(&mtip_pci_driver); + error = pci_register_driver(&mtip_pci_driver); + if (error) + unregister_blkdev(mtip_major, MTIP_DRV_NAME); + + return error; } /* From 4bea8b5cf8c6e875fa43e617cd52858a07ae8ea8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Apr 2012 11:16:24 -0300 Subject: [PATCH 030/438] perf top: Add intel_idle to the skip list TODO: Accrue the cycles in the skip_list to an idle total, and show this on the 'top' UI, as suggested by Steven. Cc: Eric Dumazet Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-9nfecmgghgl5747rjxqpc28f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e3c63aef8efc..fab0a1c7e872 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -615,6 +615,7 @@ process_hotkey: /* Tag samples to be skipped. */ static const char *skip_symbols[] = { + "intel_idle", "default_idle", "native_safe_halt", "cpu_idle", From 8b84a568117fde9b77575f2060274eddab424c32 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 5 Apr 2012 16:15:59 -0300 Subject: [PATCH 031/438] perf annotate: Fix hist decay We were only decaying the entries for the offsets that were associated with an objdump line. That way, when we accrued the whole instruction addr range, more than 100% was appearing in some cases in the live annotation TUI. Fix it by not traversing the source code line at all, just iterate thru the complete addr range decaying each one. Reported-by: Mike Galbraith Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-hcae5oxa22syjrnalsxz7s6n@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 199f69ec656f..70f5a4dc17e9 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -561,16 +561,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); - struct objdump_line *pos; - int len = sym->end - sym->start; + int len = sym->end - sym->start, offset; h->sum = 0; - - list_for_each_entry(pos, ¬es->src->source, node) { - if (pos->offset != -1 && pos->offset < len) { - h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; - h->sum += h->addr[pos->offset]; - } + for (offset = 0; offset < len; ++offset) { + h->addr[offset] = h->addr[offset] * 7 / 8; + h->sum += h->addr[offset]; } } From 63fa471dd49e9c9ce029d910d1024330d9b1b145 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 27 Mar 2012 03:14:18 -0400 Subject: [PATCH 032/438] perf hists: Catch and handle out-of-date hist entry maps. When a process exec()'s, all the maps are retired, but we keep the hist entries around which hold references to those outdated maps. If the same library gets mapped in for which we have hist entries, a new map will be created. But when we take a perf entry hit within that map, we'll find the existing hist entry with the older map. This causes symbol translations to be done incorrectly. For example, the perf entry processing will lookup the correct uptodate map entry and use that to calculate the symbol and DSO relative address. But later when we update the histogram we'll translate the address using the outdated map file instead leading to conditions such as out-of-range offsets in symbol__inc_addr_samples(). Therefore, update the map of the hist_entry dynamically at lookup/ creation time. Signed-off-by: David S. Miller Cc: stable@kernel.org Link: http://lkml.kernel.org/r/20120327.031418.1220315351537060808.davem@davemloft.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2ec4b60aff6c..9f6d630d5316 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!cmp) { he->period += period; ++he->nr_events; + + /* If the map of an existing hist_entry has + * become out-of-date due to an exec() or + * similar, update it. Otherwise we will + * mis-adjust symbol addresses when computing + * the history counter to increment. + */ + if (he->ms.map != entry->ms.map) { + he->ms.map = entry->ms.map; + if (he->ms.map) + he->ms.map->referenced = true; + } goto out; } From 8493fe1daf15324eb13a4cc2f94e258716daa568 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 4 Apr 2012 22:21:31 +0200 Subject: [PATCH 033/438] perf hists browser: Fix NULL deref in hists browsing code If there's an event with no samples in data file, the perf report command can segfault after entering the event details menu. Following steps reproduce the issue: # ./perf record -e syscalls:sys_enter_kexec_load,syscalls:sys_enter_mmap ls # ./perf report # enter '0 syscalls:sys_enter_kexec_load' menu # pres ENTER twice Above steps are valid assuming ls wont run kexec.. ;) The check for sellection to be NULL is missing. The fix makes sure it's being check. Above steps now endup with menu being displayed allowing 'Exit' as the only option. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1333570898-10505-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/hists.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index d7a1c4afe28b..2f83e5dc9967 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -125,6 +125,9 @@ static int callchain__count_rows(struct rb_root *chain) static bool map_symbol__toggle_fold(struct map_symbol *self) { + if (!self) + return false; + if (!self->has_children) return false; From 31d68e7b66f168e623902e194af1e52b8cf75d71 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Mar 2012 12:55:57 -0300 Subject: [PATCH 034/438] perf annotate: Validate addr in symbol__inc_addr_samples This routine was checking only if the provided address was after sym->end, not if it was before sym->start. Fix that by checking for both and return in both cases -ERANGE, so that tools can communicate this to the user properly, or if they chose so, to abort. This problem was reported previously but the fixes involved either doing what was being done for the > end case, i.e. silently drop the sample, returning 0, or aborting at this function, which is in a lib (or better, is slated to be at some point) and shouldn't abort. The 'report' tool already checks this value and uses pr_debug to warn the user. This patch makes the 'top' tool check it too and warn once per map where such range problem takes place. Reported-by: David Miller Reported-by: Sorin Dumitru Reported-by: Stephane Eranian Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-lw8gs7p9i9nhldilo82tzpne@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 35 ++++++++++++++++++++++++++++++++++- tools/perf/util/annotate.c | 4 ++-- tools/perf/util/map.c | 1 + tools/perf/util/map.h | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index fab0a1c7e872..8ef59f8262bb 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -42,6 +42,7 @@ #include "util/debug.h" #include +#include #include #include @@ -59,6 +60,7 @@ #include #include #include +#include #include #include @@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he) symbol__annotate_zero_histograms(sym); } +static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) +{ + struct utsname uts; + int err = uname(&uts); + + ui__warning("Out of bounds address found:\n\n" + "Addr: %" PRIx64 "\n" + "DSO: %s %c\n" + "Map: %" PRIx64 "-%" PRIx64 "\n" + "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n" + "Arch: %s\n" + "Kernel: %s\n" + "Tools: %s\n\n" + "Not all samples will be on the annotation output.\n\n" + "Please report to linux-kernel@vger.kernel.org\n", + ip, map->dso->long_name, dso__symtab_origin(map->dso), + map->start, map->end, sym->start, sym->end, + sym->binding == STB_GLOBAL ? 'g' : + sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, + err ? "[unknown]" : uts.machine, + err ? "[unknown]" : uts.release, perf_version_string); + if (use_browser <= 0) + sleep(5); + + map->erange_warned = true; +} + static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, int counter, u64 ip) { struct annotation *notes; struct symbol *sym; + int err; if (he == NULL || he->ms.sym == NULL || ((top->sym_filter_entry == NULL || @@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top, } ip = he->ms.map->map_ip(he->ms.map, ip); - symbol__inc_addr_samples(sym, he->ms.map, counter, ip); + err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); pthread_mutex_unlock(¬es->lock); + + if (err == -ERANGE && !he->ms.map->erange_warned) + ui__warn_map_erange(he->ms.map, sym, ip); } static void perf_top__show_details(struct perf_top *top) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 70f5a4dc17e9..08c6d138a655 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); - if (addr > sym->end) - return 0; + if (addr < sym->start || addr > sym->end) + return -ERANGE; offset = addr - sym->start; h = annotation__histogram(notes, evidx); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index dea6d1c1a954..35ae56864e4f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type, RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; + self->erange_warned = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index b100c20b7f94..81371bad4ef0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -33,6 +33,7 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; + bool erange_warned; u32 priv; u64 pgoff; From 46ed99d1b7c92920ce9e313152522847647aae4f Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Sun, 1 Apr 2012 20:48:04 +0200 Subject: [PATCH 035/438] x86: vsyscall: Use NULL instead 0 for a pointer argument This patch silences the following sparse warning: arch/x86/kernel/vsyscall_64.c:250:34: warning: Using plain integer as NULL pointer Signed-off-by: Emil Goode Acked-by: Andy Lutomirski Cc: john.stultz@linaro.org Link: http://lkml.kernel.org/r/1333306084-3776-1-git-send-email-emilgoode@gmail.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/vsyscall_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index f386dc49f988..7515cf0e1805 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) current_thread_info()->sig_on_uaccess_error = 1; /* - * 0 is a valid user pointer (in the access_ok sense) on 32-bit and + * NULL is a valid user pointer (in the access_ok sense) on 32-bit and * 64-bit, so we don't need to special-case it here. For all the - * vsyscalls, 0 means "don't write anything" not "write it at + * vsyscalls, NULL means "don't write anything" not "write it at * address 0". */ ret = -EFAULT; @@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) ret = sys_getcpu((unsigned __user *)regs->di, (unsigned __user *)regs->si, - 0); + NULL); break; } From 6f103929f8979d2638e58d7f7fda0beefcb8ee7e Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Tue, 27 Mar 2012 15:09:37 -0400 Subject: [PATCH 036/438] nohz: Fix stale jiffies update in tick_nohz_restart() Fix tick_nohz_restart() to not use a stale ktime_t "now" value when calling tick_do_update_jiffies64(now). If we reach this point in the loop it means that we crossed a tick boundary since we grabbed the "now" timestamp, so at this point "now" refers to a time in the old jiffy, so using the old value for "now" is incorrect, and is likely to give us a stale jiffies value. In particular, the first time through the loop the tick_do_update_jiffies64(now) call is always a no-op, since the caller, tick_nohz_restart_sched_tick(), will have already called tick_do_update_jiffies64(now) with that "now" value. Note that tick_nohz_stop_sched_tick() already uses the correct approach: when we notice we cross a jiffy boundary, grab a new timestamp with ktime_get(), and *then* update jiffies. Signed-off-by: Neal Cardwell Cc: Ben Segall Cc: Ingo Molnar Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1332875377-23014-1-git-send-email-ncardwell@google.com Signed-off-by: Thomas Gleixner --- kernel/time/tick-sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 3526038f2836..6a3a5b9ff561 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) hrtimer_get_expires(&ts->sched_timer), 0)) break; } - /* Update jiffies and reread time */ - tick_do_update_jiffies64(now); + /* Reread time and update jiffies */ now = ktime_get(); + tick_do_update_jiffies64(now); } } From 2ca052a3710fac208eee690faefdeb8bbd4586a1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 2 Apr 2012 16:15:33 -0700 Subject: [PATCH 037/438] x86: Use correct byte-sized register constraint in __xchg_op() x86-64 can access the low half of any register, but i386 can only do it with a subset of registers. 'r' causes compilation failures on i386, but 'q' expresses the constraint properly. Signed-off-by: Jeremy Fitzhardinge Link: http://lkml.kernel.org/r/4F7A3315.501@goop.org Reported-by: Leigh Scott Tested-by: Thomas Reitmayr Signed-off-by: H. Peter Anvin Cc: v3.3 --- arch/x86/include/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index b3b733262909..bc18d0ed459a 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -43,7 +43,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock #op "b %b0, %1\n" \ - : "+r" (__ret), "+m" (*(ptr)) \ + : "+q" (__ret), "+m" (*(ptr)) \ : : "memory", "cc"); \ break; \ case __X86_CASE_W: \ From 8c91c5325e107ec17e40a59a47c6517387d64eb7 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 6 Apr 2012 09:30:57 -0700 Subject: [PATCH 038/438] x86: Use correct byte-sized register constraint in __add() Similar to: 2ca052a x86: Use correct byte-sized register constraint in __xchg_op() ... the __add() macro also needs to use a "q" constraint in the byte-sized case, lest we try to generate an illegal register. Link: http://lkml.kernel.org/r/4F7A3315.501@goop.org Signed-off-by: H. Peter Anvin Cc: Jeremy Fitzhardinge Cc: Leigh Scott Cc: Thomas Reitmayr Cc: v3.3 --- arch/x86/include/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index bc18d0ed459a..99480e55973d 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -173,7 +173,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock "addb %b1, %0\n" \ - : "+m" (*(ptr)) : "ri" (inc) \ + : "+m" (*(ptr)) : "qi" (inc) \ : "memory", "cc"); \ break; \ case __X86_CASE_W: \ From 1b2e19f17ed327af6add02978efdf354e4f8e4df Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 6 Apr 2012 11:37:47 -0600 Subject: [PATCH 039/438] block: make auto block plug flush threshold per-disk based We do auto block plug flush to reduce latency, the threshold is 16 requests. This works well if the task is accessing one or two drives. The problem is if the task is accessing a raid 0 device and the raid disk number is big, say 8 or 16, 16/8 = 2 or 16/16=1, we will have heavy lock contention. This patch makes the threshold per-disk based. The latency should be still ok accessing one or two drives. The setup with application accessing a lot of drives in the meantime uaually is big machine, avoiding lock contention is more important, because any contention will actually increase latency. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe --- block/blk-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 414e8224588f..1f61b74867e4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1277,7 +1277,8 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio, list_for_each_entry_reverse(rq, &plug->list, queuelist) { int el_ret; - (*request_count)++; + if (rq->q == q) + (*request_count)++; if (rq->q != q || !blk_rq_merge_ok(rq, bio)) continue; From a8edc42a11e1d7b7e158d4026670fd83854dfcc2 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 22 Mar 2012 14:01:07 -0700 Subject: [PATCH 040/438] usb: Put USB Kconfig items back under USB. commit 53c6bc24fdc8db87109a5760579cbb060fa644cf (usb: Don't make USB_ARCH_HAS_{XHCI,OHCI,EHCI} depend on USB_SUPPORT.) Removed the dependency of the USB_ARCH_HAS_* symbols on USB_SUPPORT. However the resulting Kconfig somehow caused many of the USB configuration items to appear under the top level devices menu. To fix this we reunite the 'menuconfig USB_SUPPORT' with the 'if USB_SUPPORT', and the config items magically go back to their desired location. Reported-by: Julian Wollrath Reported-by: Nobuhiro Iwamatsu Reported-by: Borislav Petkov Reported-by: Rupesh Gujare Reported-by: Feng King Reported-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: David Daney Tested-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index cbd8f5f80596..76316a33061b 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -2,14 +2,6 @@ # USB device configuration # -menuconfig USB_SUPPORT - bool "USB support" - depends on HAS_IOMEM - default y - ---help--- - This option adds core support for Universal Serial Bus (USB). - You will also need drivers from the following menu to make use of it. - # many non-PCI SOC chips embed OHCI config USB_ARCH_HAS_OHCI boolean @@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI boolean default PCI +menuconfig USB_SUPPORT + bool "USB support" + depends on HAS_IOMEM + default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. + if USB_SUPPORT config USB_COMMON From 2e8dc2f2c1f669401f4bb07ccdb92ae8e44a9f00 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sat, 17 Mar 2012 15:23:49 +0100 Subject: [PATCH 041/438] usb/usbmon: correct the data interpretation of usbmon's output The doc says that the data | 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 is the SCSI command 0x5e. According to the usbmon source, it dumps one byte after the other. The first 4 bytes are US_BULK_CB_SIGN which is correct. After that we see the TAG which is 0x5e. The cdb is 0x00 in this example. In order to correct this, I change the example to a READ_10 command which is 0x28 so it is not just a zero somewhere in the stream. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/usbmon.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt index 5335fa8b06eb..c42bb9cd3b43 100644 --- a/Documentation/usb/usbmon.txt +++ b/Documentation/usb/usbmon.txt @@ -183,10 +183,10 @@ An input control transfer to get a port status. d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 -An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper -to a storage device at address 5: +An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte +Bulk wrapper to a storage device at address 5: -dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 +dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 dd65f0e8 4128379808 C Bo:1:005:2 0 31 > * Raw binary format and API From c825bab0cef8b90bab8b63eb5686b8c8eb22e798 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 19 Mar 2012 15:20:57 +0800 Subject: [PATCH 042/438] usb: storage: fix lockdep warning inside usb_stor_pre_reset(v2) This patch fixes one lockdep warning[1] inside usb_stor_pre_reset. If the current configuration includes multiple mass storage interfaces, the 'AA' lockdep warning will be triggered since the lock class of 'us->dev_mutex' is acquired two times in .reset path. It isn't a real deadlock, so just take the lockdep_set_class annotation to remove the warning. [1], lockdep warning log :[ INFO: possible recursive locking detected ] :3.3.0-0.rc5.git3.1.fc17.x86_64 #1 Tainted: G W :--------------------------------------------- :usb-storage/14846 is trying to acquire lock: : (&(us->dev_mutex)){+.+.+.}, at: [] usb_stor_pre_reset+0x1c/0x20 [usb_storage] :but task is already holding lock: : (&(us->dev_mutex)){+.+.+.}, at: [] usb_stor_pre_reset+0x1c/0x20 [usb_storage] :other info that might help us debug this: : Possible unsafe locking scenario: : CPU0 : ---- : lock(&(us->dev_mutex)); : lock(&(us->dev_mutex)); : *** DEADLOCK *** : May be due to missing lock nesting notation :2 locks held by usb-storage/14846: : #0: (&__lockdep_no_validate__){......}, at: [] usb_lock_device_for_reset+0x95/0x100 : #1: (&(us->dev_mutex)){+.+.+.}, at: [] usb_stor_pre_reset+0x1c/0x20 [usb_storage] :stack backtrace: :Pid: 14846, comm: usb-storage Tainted: G W 3.3.0-0.rc5.git3.1.fc17.x86_64 #1 :Call Trace: : [] __lock_acquire+0x168f/0x1bb0 : [] ? native_sched_clock+0x13/0x80 : [] ? sched_clock+0x9/0x10 : [] ? sched_clock+0x9/0x10 : [] ? sched_clock_local+0x25/0xa0 : [] lock_acquire+0xa1/0x1e0 : [] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage] : [] mutex_lock_nested+0x76/0x3a0 : [] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage] : [] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage] : [] usb_stor_pre_reset+0x1c/0x20 [usb_storage] : [] usb_reset_device+0x7d/0x190 : [] usb_stor_port_reset+0x7c/0x80 [usb_storage] : [] usb_stor_invoke_transport+0x94/0x560 [usb_storage] : [] ? mark_held_locks+0xb2/0x130 : [] ? _raw_spin_unlock_irq+0x30/0x50 : [] usb_stor_transparent_scsi_command+0xe/0x10 [usb_storage] : [] usb_stor_control_thread+0x173/0x280 [usb_storage] : [] ? fill_inquiry_response+0x20/0x20 [usb_storage] : [] kthread+0xb7/0xc0 : [] kernel_thread_helper+0x4/0x10 : [] ? retint_restore_args+0x13/0x13 : [] ? kthread_worker_fn+0x1a0/0x1a0 : [] ? gs_change+0x13/0x13 Reported-By: Dave Jones Signed-off-by: Ming Lei Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c18538e4a6db..2653e73db623 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -132,6 +132,35 @@ static struct us_unusual_dev for_dynamic_ids = #undef COMPLIANT_DEV #undef USUAL_DEV +#ifdef CONFIG_LOCKDEP + +static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; + +static void us_set_lock_class(struct mutex *mutex, + struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_host_config *config = udev->actconfig; + int i; + + for (i = 0; i < config->desc.bNumInterfaces; i++) { + if (config->interface[i] == intf) + break; + } + + BUG_ON(i == config->desc.bNumInterfaces); + + lockdep_set_class(mutex, &us_interface_key[i]); +} + +#else + +static void us_set_lock_class(struct mutex *mutex, + struct usb_interface *intf) +{ +} + +#endif #ifdef CONFIG_PM /* Minimal support for suspend and resume */ @@ -895,6 +924,7 @@ int usb_stor_probe1(struct us_data **pus, *pus = us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); mutex_init(&(us->dev_mutex)); + us_set_lock_class(&us->dev_mutex, intf); init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); From bcf398537630bf20b4dbe59ba855b69f404c93cf Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 22 Mar 2012 11:00:21 -0400 Subject: [PATCH 043/438] USB: don't clear urb->dev in scatter-gather library This patch (as1517b) fixes an error in the USB scatter-gather library. The library code uses urb->dev to determine whether or nor an URB is currently active; the completion handler sets urb->dev to NULL. However the core unlinking routines need to use urb->dev. Since unlinking always racing with completion, the completion handler must not clear urb->dev -- it can lead to invalid memory accesses when a transfer has to be cancelled. This patch fixes the problem by getting rid of the lines that clear urb->dev after urb has been submitted. As a result we may end up trying to unlink an URB that failed in submission or that has already completed, so an extra check is added after each unlink to avoid printing an error message when this happens. The checks are updated in both sg_complete() and sg_cancel(), and the second is updated to match the first (currently it prints out unnecessary warning messages if a device is unplugged while a transfer is in progress). Signed-off-by: Alan Stern Reported-and-tested-by: Illia Zaitsev CC: Ming Lei CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b3bdfede45e6..aed3e07942d4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && - retval != -EBUSY) + retval != -EBUSY && + retval != -EIDRM) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); @@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } - urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: - io->urbs[i]->dev = NULL; retval = 0; yield(); break; @@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: - io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); @@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); - if (retval != -EINPROGRESS && retval != -EBUSY) + if (retval != -EINPROGRESS + && retval != -ENODEV + && retval != -EBUSY + && retval != -EIDRM) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } From da8bfb090c2b30af9f3879443355f7eb1d0fe10a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 28 Mar 2012 16:13:28 -0400 Subject: [PATCH 044/438] USB documentation: explain lifetime rules for unlinking URBs This patch (as1534c) updates the documentation for usb_unlink_urb and related functions. It explains that the caller must prevent the URB being unlinked from getting deallocated while the unlink is taking place. Signed-off-by: Alan Stern CC: Ming Lei Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/URB.txt | 22 ++++++++++++++++++++++ drivers/usb/core/urb.c | 12 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt index 8ffce746d496..00d2c644068e 100644 --- a/Documentation/usb/URB.txt +++ b/Documentation/usb/URB.txt @@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. +There is a lifetime issue to consider. An URB may complete at any +time, and the completion handler may free the URB. If this happens +while usb_unlink_urb or usb_kill_urb is running, it will cause a +memory-access violation. The driver is responsible for avoiding this, +which often means some sort of lock will be needed to prevent the URB +from being deallocated while it is still in use. + +On the other hand, since usb_unlink_urb may end up calling the +completion handler, the handler must not take any lock that is held +when usb_unlink_urb is invoked. The general solution to this problem +is to increment the URB's reference count while holding the lock, then +drop the lock and call usb_unlink_urb or usb_kill_urb, and then +decrement the URB's reference count. You increment the reference +count by calling + + struct urb *usb_get_urb(struct urb *urb) + +(ignore the return value; it is the same as the argument) and +decrement the reference count by calling usb_free_urb. Of course, +none of this is necessary if there's no danger of the URB being freed +by the completion handler. + 1.7. What about the completion handler? diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 7239a73c1b8c..cd9b3a2cd8a7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * never submitted, or it was unlinked before, or the hardware is already * finished with it), even if the completion handler has not yet run. * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual @@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). @@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). From a2457ee691edeffb511dbff9a69008f480192197 Mon Sep 17 00:00:00 2001 From: Michael BRIGHT Date: Thu, 22 Mar 2012 18:42:52 +0100 Subject: [PATCH 045/438] USB: remove compile warning on gadget/inode.c Removed unused "restart:" label, which was causing compiler warning. Signed-off-by: Michael BRIGHT Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 8793f32bab11..e58b16442971 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1574,7 +1574,6 @@ static void destroy_ep_files (struct dev_data *dev) DBG (dev, "%s %d\n", __func__, dev->state); /* dev->state must prevent interference */ -restart: spin_lock_irq (&dev->lock); while (!list_empty(&dev->epfiles)) { struct ep_data *ep; From c3d8b76f61586714cdc5f219ba45592a54caaa55 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 21 Mar 2012 20:15:18 +0100 Subject: [PATCH 046/438] serial: PL011: move interrupt clearing Commit 360f748b204275229f8398cb2f9f53955db1503b "serial: PL011: clear pending interrupts" attempts to clear interrupts by writing to a yet-unassigned memory address. This fixes the issue. The breaking patch is marked for stable so should be carried along with the other patch. Cc: Shreshtha Kumar Sahu Cc: Russell King Cc: stable Cc: Nicolas Pitre Reported-by: Viresh Kumar Signed-off-by: Linus Walleij Tested-by: Grant Likely Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 0c65c9e66986..3d569cd68f58 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1946,10 +1946,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto unmap; } - /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); - uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; @@ -1967,6 +1963,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.line = i; pl011_dma_probe(uap); + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); + snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); amba_ports[i] = uap; From ef798d0207e02e05bfabc7ba96e8a6f2cc07066e Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 21 Mar 2012 23:36:50 +0100 Subject: [PATCH 047/438] kyrofb: fix on x86_64 kyrofb is completely broken on x86_64 because the registers are defined as unsigned long. Change them to u32 to make the driver work. Tested with Hercules 3D Prophet 4000XT. Signed-off-by: Ondrej Zary Acked-by: Paul Mundt Signed-off-by: Florian Tobias Schandinat --- drivers/video/kyro/STG4000Reg.h | 332 ++++++++++++++++---------------- 1 file changed, 166 insertions(+), 166 deletions(-) diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/kyro/STG4000Reg.h index 5d6269882589..50f4670e9252 100644 --- a/drivers/video/kyro/STG4000Reg.h +++ b/drivers/video/kyro/STG4000Reg.h @@ -73,210 +73,210 @@ typedef enum _OVRL_PIX_FORMAT { /* Register Table */ typedef struct { /* 0h */ - volatile unsigned long Thread0Enable; /* 0x0000 */ - volatile unsigned long Thread1Enable; /* 0x0004 */ - volatile unsigned long Thread0Recover; /* 0x0008 */ - volatile unsigned long Thread1Recover; /* 0x000C */ - volatile unsigned long Thread0Step; /* 0x0010 */ - volatile unsigned long Thread1Step; /* 0x0014 */ - volatile unsigned long VideoInStatus; /* 0x0018 */ - volatile unsigned long Core2InSignStart; /* 0x001C */ - volatile unsigned long Core1ResetVector; /* 0x0020 */ - volatile unsigned long Core1ROMOffset; /* 0x0024 */ - volatile unsigned long Core1ArbiterPriority; /* 0x0028 */ - volatile unsigned long VideoInControl; /* 0x002C */ - volatile unsigned long VideoInReg0CtrlA; /* 0x0030 */ - volatile unsigned long VideoInReg0CtrlB; /* 0x0034 */ - volatile unsigned long VideoInReg1CtrlA; /* 0x0038 */ - volatile unsigned long VideoInReg1CtrlB; /* 0x003C */ - volatile unsigned long Thread0Kicker; /* 0x0040 */ - volatile unsigned long Core2InputSign; /* 0x0044 */ - volatile unsigned long Thread0ProgCtr; /* 0x0048 */ - volatile unsigned long Thread1ProgCtr; /* 0x004C */ - volatile unsigned long Thread1Kicker; /* 0x0050 */ - volatile unsigned long GPRegister1; /* 0x0054 */ - volatile unsigned long GPRegister2; /* 0x0058 */ - volatile unsigned long GPRegister3; /* 0x005C */ - volatile unsigned long GPRegister4; /* 0x0060 */ - volatile unsigned long SerialIntA; /* 0x0064 */ + volatile u32 Thread0Enable; /* 0x0000 */ + volatile u32 Thread1Enable; /* 0x0004 */ + volatile u32 Thread0Recover; /* 0x0008 */ + volatile u32 Thread1Recover; /* 0x000C */ + volatile u32 Thread0Step; /* 0x0010 */ + volatile u32 Thread1Step; /* 0x0014 */ + volatile u32 VideoInStatus; /* 0x0018 */ + volatile u32 Core2InSignStart; /* 0x001C */ + volatile u32 Core1ResetVector; /* 0x0020 */ + volatile u32 Core1ROMOffset; /* 0x0024 */ + volatile u32 Core1ArbiterPriority; /* 0x0028 */ + volatile u32 VideoInControl; /* 0x002C */ + volatile u32 VideoInReg0CtrlA; /* 0x0030 */ + volatile u32 VideoInReg0CtrlB; /* 0x0034 */ + volatile u32 VideoInReg1CtrlA; /* 0x0038 */ + volatile u32 VideoInReg1CtrlB; /* 0x003C */ + volatile u32 Thread0Kicker; /* 0x0040 */ + volatile u32 Core2InputSign; /* 0x0044 */ + volatile u32 Thread0ProgCtr; /* 0x0048 */ + volatile u32 Thread1ProgCtr; /* 0x004C */ + volatile u32 Thread1Kicker; /* 0x0050 */ + volatile u32 GPRegister1; /* 0x0054 */ + volatile u32 GPRegister2; /* 0x0058 */ + volatile u32 GPRegister3; /* 0x005C */ + volatile u32 GPRegister4; /* 0x0060 */ + volatile u32 SerialIntA; /* 0x0064 */ - volatile unsigned long Fill0[6]; /* GAP 0x0068 - 0x007C */ + volatile u32 Fill0[6]; /* GAP 0x0068 - 0x007C */ - volatile unsigned long SoftwareReset; /* 0x0080 */ - volatile unsigned long SerialIntB; /* 0x0084 */ + volatile u32 SoftwareReset; /* 0x0080 */ + volatile u32 SerialIntB; /* 0x0084 */ - volatile unsigned long Fill1[37]; /* GAP 0x0088 - 0x011C */ + volatile u32 Fill1[37]; /* GAP 0x0088 - 0x011C */ - volatile unsigned long ROMELQV; /* 0x011C */ - volatile unsigned long WLWH; /* 0x0120 */ - volatile unsigned long ROMELWL; /* 0x0124 */ + volatile u32 ROMELQV; /* 0x011C */ + volatile u32 WLWH; /* 0x0120 */ + volatile u32 ROMELWL; /* 0x0124 */ - volatile unsigned long dwFill_1; /* GAP 0x0128 */ + volatile u32 dwFill_1; /* GAP 0x0128 */ - volatile unsigned long IntStatus; /* 0x012C */ - volatile unsigned long IntMask; /* 0x0130 */ - volatile unsigned long IntClear; /* 0x0134 */ + volatile u32 IntStatus; /* 0x012C */ + volatile u32 IntMask; /* 0x0130 */ + volatile u32 IntClear; /* 0x0134 */ - volatile unsigned long Fill2[6]; /* GAP 0x0138 - 0x014C */ + volatile u32 Fill2[6]; /* GAP 0x0138 - 0x014C */ - volatile unsigned long ROMGPIOA; /* 0x0150 */ - volatile unsigned long ROMGPIOB; /* 0x0154 */ - volatile unsigned long ROMGPIOC; /* 0x0158 */ - volatile unsigned long ROMGPIOD; /* 0x015C */ + volatile u32 ROMGPIOA; /* 0x0150 */ + volatile u32 ROMGPIOB; /* 0x0154 */ + volatile u32 ROMGPIOC; /* 0x0158 */ + volatile u32 ROMGPIOD; /* 0x015C */ - volatile unsigned long Fill3[2]; /* GAP 0x0160 - 0x0168 */ + volatile u32 Fill3[2]; /* GAP 0x0160 - 0x0168 */ - volatile unsigned long AGPIntID; /* 0x0168 */ - volatile unsigned long AGPIntClassCode; /* 0x016C */ - volatile unsigned long AGPIntBIST; /* 0x0170 */ - volatile unsigned long AGPIntSSID; /* 0x0174 */ - volatile unsigned long AGPIntPMCSR; /* 0x0178 */ - volatile unsigned long VGAFrameBufBase; /* 0x017C */ - volatile unsigned long VGANotify; /* 0x0180 */ - volatile unsigned long DACPLLMode; /* 0x0184 */ - volatile unsigned long Core1VideoClockDiv; /* 0x0188 */ - volatile unsigned long AGPIntStat; /* 0x018C */ + volatile u32 AGPIntID; /* 0x0168 */ + volatile u32 AGPIntClassCode; /* 0x016C */ + volatile u32 AGPIntBIST; /* 0x0170 */ + volatile u32 AGPIntSSID; /* 0x0174 */ + volatile u32 AGPIntPMCSR; /* 0x0178 */ + volatile u32 VGAFrameBufBase; /* 0x017C */ + volatile u32 VGANotify; /* 0x0180 */ + volatile u32 DACPLLMode; /* 0x0184 */ + volatile u32 Core1VideoClockDiv; /* 0x0188 */ + volatile u32 AGPIntStat; /* 0x018C */ /* - volatile unsigned long Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 - volatile unsigned long Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table - volatile unsigned long Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 - volatile unsigned long Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 - volatile unsigned long Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC + volatile u32 Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 + volatile u32 Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table + volatile u32 Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 + volatile u32 Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 + volatile u32 Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC */ - volatile unsigned long Fill4[412]; /* 0x0190 - 0x07FC */ + volatile u32 Fill4[412]; /* 0x0190 - 0x07FC */ - volatile unsigned long TACtrlStreamBase; /* 0x0800 */ - volatile unsigned long TAObjDataBase; /* 0x0804 */ - volatile unsigned long TAPtrDataBase; /* 0x0808 */ - volatile unsigned long TARegionDataBase; /* 0x080C */ - volatile unsigned long TATailPtrBase; /* 0x0810 */ - volatile unsigned long TAPtrRegionSize; /* 0x0814 */ - volatile unsigned long TAConfiguration; /* 0x0818 */ - volatile unsigned long TAObjDataStartAddr; /* 0x081C */ - volatile unsigned long TAObjDataEndAddr; /* 0x0820 */ - volatile unsigned long TAXScreenClip; /* 0x0824 */ - volatile unsigned long TAYScreenClip; /* 0x0828 */ - volatile unsigned long TARHWClamp; /* 0x082C */ - volatile unsigned long TARHWCompare; /* 0x0830 */ - volatile unsigned long TAStart; /* 0x0834 */ - volatile unsigned long TAObjReStart; /* 0x0838 */ - volatile unsigned long TAPtrReStart; /* 0x083C */ - volatile unsigned long TAStatus1; /* 0x0840 */ - volatile unsigned long TAStatus2; /* 0x0844 */ - volatile unsigned long TAIntStatus; /* 0x0848 */ - volatile unsigned long TAIntMask; /* 0x084C */ + volatile u32 TACtrlStreamBase; /* 0x0800 */ + volatile u32 TAObjDataBase; /* 0x0804 */ + volatile u32 TAPtrDataBase; /* 0x0808 */ + volatile u32 TARegionDataBase; /* 0x080C */ + volatile u32 TATailPtrBase; /* 0x0810 */ + volatile u32 TAPtrRegionSize; /* 0x0814 */ + volatile u32 TAConfiguration; /* 0x0818 */ + volatile u32 TAObjDataStartAddr; /* 0x081C */ + volatile u32 TAObjDataEndAddr; /* 0x0820 */ + volatile u32 TAXScreenClip; /* 0x0824 */ + volatile u32 TAYScreenClip; /* 0x0828 */ + volatile u32 TARHWClamp; /* 0x082C */ + volatile u32 TARHWCompare; /* 0x0830 */ + volatile u32 TAStart; /* 0x0834 */ + volatile u32 TAObjReStart; /* 0x0838 */ + volatile u32 TAPtrReStart; /* 0x083C */ + volatile u32 TAStatus1; /* 0x0840 */ + volatile u32 TAStatus2; /* 0x0844 */ + volatile u32 TAIntStatus; /* 0x0848 */ + volatile u32 TAIntMask; /* 0x084C */ - volatile unsigned long Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ + volatile u32 Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ - volatile unsigned long TextureAddrThresh; /* 0x0BFC */ - volatile unsigned long Core1Translation; /* 0x0C00 */ - volatile unsigned long TextureAddrReMap; /* 0x0C04 */ - volatile unsigned long RenderOutAGPRemap; /* 0x0C08 */ - volatile unsigned long _3DRegionReadTrans; /* 0x0C0C */ - volatile unsigned long _3DPtrReadTrans; /* 0x0C10 */ - volatile unsigned long _3DParamReadTrans; /* 0x0C14 */ - volatile unsigned long _3DRegionReadThresh; /* 0x0C18 */ - volatile unsigned long _3DPtrReadThresh; /* 0x0C1C */ - volatile unsigned long _3DParamReadThresh; /* 0x0C20 */ - volatile unsigned long _3DRegionReadAGPRemap; /* 0x0C24 */ - volatile unsigned long _3DPtrReadAGPRemap; /* 0x0C28 */ - volatile unsigned long _3DParamReadAGPRemap; /* 0x0C2C */ - volatile unsigned long ZBufferAGPRemap; /* 0x0C30 */ - volatile unsigned long TAIndexAGPRemap; /* 0x0C34 */ - volatile unsigned long TAVertexAGPRemap; /* 0x0C38 */ - volatile unsigned long TAUVAddrTrans; /* 0x0C3C */ - volatile unsigned long TATailPtrCacheTrans; /* 0x0C40 */ - volatile unsigned long TAParamWriteTrans; /* 0x0C44 */ - volatile unsigned long TAPtrWriteTrans; /* 0x0C48 */ - volatile unsigned long TAParamWriteThresh; /* 0x0C4C */ - volatile unsigned long TAPtrWriteThresh; /* 0x0C50 */ - volatile unsigned long TATailPtrCacheAGPRe; /* 0x0C54 */ - volatile unsigned long TAParamWriteAGPRe; /* 0x0C58 */ - volatile unsigned long TAPtrWriteAGPRe; /* 0x0C5C */ - volatile unsigned long SDRAMArbiterConf; /* 0x0C60 */ - volatile unsigned long SDRAMConf0; /* 0x0C64 */ - volatile unsigned long SDRAMConf1; /* 0x0C68 */ - volatile unsigned long SDRAMConf2; /* 0x0C6C */ - volatile unsigned long SDRAMRefresh; /* 0x0C70 */ - volatile unsigned long SDRAMPowerStat; /* 0x0C74 */ + volatile u32 TextureAddrThresh; /* 0x0BFC */ + volatile u32 Core1Translation; /* 0x0C00 */ + volatile u32 TextureAddrReMap; /* 0x0C04 */ + volatile u32 RenderOutAGPRemap; /* 0x0C08 */ + volatile u32 _3DRegionReadTrans; /* 0x0C0C */ + volatile u32 _3DPtrReadTrans; /* 0x0C10 */ + volatile u32 _3DParamReadTrans; /* 0x0C14 */ + volatile u32 _3DRegionReadThresh; /* 0x0C18 */ + volatile u32 _3DPtrReadThresh; /* 0x0C1C */ + volatile u32 _3DParamReadThresh; /* 0x0C20 */ + volatile u32 _3DRegionReadAGPRemap; /* 0x0C24 */ + volatile u32 _3DPtrReadAGPRemap; /* 0x0C28 */ + volatile u32 _3DParamReadAGPRemap; /* 0x0C2C */ + volatile u32 ZBufferAGPRemap; /* 0x0C30 */ + volatile u32 TAIndexAGPRemap; /* 0x0C34 */ + volatile u32 TAVertexAGPRemap; /* 0x0C38 */ + volatile u32 TAUVAddrTrans; /* 0x0C3C */ + volatile u32 TATailPtrCacheTrans; /* 0x0C40 */ + volatile u32 TAParamWriteTrans; /* 0x0C44 */ + volatile u32 TAPtrWriteTrans; /* 0x0C48 */ + volatile u32 TAParamWriteThresh; /* 0x0C4C */ + volatile u32 TAPtrWriteThresh; /* 0x0C50 */ + volatile u32 TATailPtrCacheAGPRe; /* 0x0C54 */ + volatile u32 TAParamWriteAGPRe; /* 0x0C58 */ + volatile u32 TAPtrWriteAGPRe; /* 0x0C5C */ + volatile u32 SDRAMArbiterConf; /* 0x0C60 */ + volatile u32 SDRAMConf0; /* 0x0C64 */ + volatile u32 SDRAMConf1; /* 0x0C68 */ + volatile u32 SDRAMConf2; /* 0x0C6C */ + volatile u32 SDRAMRefresh; /* 0x0C70 */ + volatile u32 SDRAMPowerStat; /* 0x0C74 */ - volatile unsigned long Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ + volatile u32 Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ - volatile unsigned long RAMBistData; /* 0x0C80 */ - volatile unsigned long RAMBistCtrl; /* 0x0C84 */ - volatile unsigned long FIFOBistKey; /* 0x0C88 */ - volatile unsigned long RAMBistResult; /* 0x0C8C */ - volatile unsigned long FIFOBistResult; /* 0x0C90 */ + volatile u32 RAMBistData; /* 0x0C80 */ + volatile u32 RAMBistCtrl; /* 0x0C84 */ + volatile u32 FIFOBistKey; /* 0x0C88 */ + volatile u32 RAMBistResult; /* 0x0C8C */ + volatile u32 FIFOBistResult; /* 0x0C90 */ /* - volatile unsigned long Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC - volatile unsigned long Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters + volatile u32 Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC + volatile u32 Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters */ - volatile unsigned long Fill7[16]; /* 0x0c94 - 0x0cd0 */ + volatile u32 Fill7[16]; /* 0x0c94 - 0x0cd0 */ - volatile unsigned long SDRAMAddrSign; /* 0x0CD4 */ - volatile unsigned long SDRAMDataSign; /* 0x0CD8 */ - volatile unsigned long SDRAMSignConf; /* 0x0CDC */ + volatile u32 SDRAMAddrSign; /* 0x0CD4 */ + volatile u32 SDRAMDataSign; /* 0x0CD8 */ + volatile u32 SDRAMSignConf; /* 0x0CDC */ /* DWFILL; //GAP 0x0CE0 */ - volatile unsigned long dwFill_2; + volatile u32 dwFill_2; - volatile unsigned long ISPSignature; /* 0x0CE4 */ + volatile u32 ISPSignature; /* 0x0CE4 */ - volatile unsigned long Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ + volatile u32 Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ - volatile unsigned long DACPrimAddress; /* 0x1400 */ - volatile unsigned long DACPrimSize; /* 0x1404 */ - volatile unsigned long DACCursorAddr; /* 0x1408 */ - volatile unsigned long DACCursorCtrl; /* 0x140C */ - volatile unsigned long DACOverlayAddr; /* 0x1410 */ - volatile unsigned long DACOverlayUAddr; /* 0x1414 */ - volatile unsigned long DACOverlayVAddr; /* 0x1418 */ - volatile unsigned long DACOverlaySize; /* 0x141C */ - volatile unsigned long DACOverlayVtDec; /* 0x1420 */ + volatile u32 DACPrimAddress; /* 0x1400 */ + volatile u32 DACPrimSize; /* 0x1404 */ + volatile u32 DACCursorAddr; /* 0x1408 */ + volatile u32 DACCursorCtrl; /* 0x140C */ + volatile u32 DACOverlayAddr; /* 0x1410 */ + volatile u32 DACOverlayUAddr; /* 0x1414 */ + volatile u32 DACOverlayVAddr; /* 0x1418 */ + volatile u32 DACOverlaySize; /* 0x141C */ + volatile u32 DACOverlayVtDec; /* 0x1420 */ - volatile unsigned long Fill9[9]; /* GAP 0x1424 - 0x1444 */ + volatile u32 Fill9[9]; /* GAP 0x1424 - 0x1444 */ - volatile unsigned long DACVerticalScal; /* 0x1448 */ - volatile unsigned long DACPixelFormat; /* 0x144C */ - volatile unsigned long DACHorizontalScal; /* 0x1450 */ - volatile unsigned long DACVidWinStart; /* 0x1454 */ - volatile unsigned long DACVidWinEnd; /* 0x1458 */ - volatile unsigned long DACBlendCtrl; /* 0x145C */ - volatile unsigned long DACHorTim1; /* 0x1460 */ - volatile unsigned long DACHorTim2; /* 0x1464 */ - volatile unsigned long DACHorTim3; /* 0x1468 */ - volatile unsigned long DACVerTim1; /* 0x146C */ - volatile unsigned long DACVerTim2; /* 0x1470 */ - volatile unsigned long DACVerTim3; /* 0x1474 */ - volatile unsigned long DACBorderColor; /* 0x1478 */ - volatile unsigned long DACSyncCtrl; /* 0x147C */ - volatile unsigned long DACStreamCtrl; /* 0x1480 */ - volatile unsigned long DACLUTAddress; /* 0x1484 */ - volatile unsigned long DACLUTData; /* 0x1488 */ - volatile unsigned long DACBurstCtrl; /* 0x148C */ - volatile unsigned long DACCrcTrigger; /* 0x1490 */ - volatile unsigned long DACCrcDone; /* 0x1494 */ - volatile unsigned long DACCrcResult1; /* 0x1498 */ - volatile unsigned long DACCrcResult2; /* 0x149C */ - volatile unsigned long DACLinecount; /* 0x14A0 */ + volatile u32 DACVerticalScal; /* 0x1448 */ + volatile u32 DACPixelFormat; /* 0x144C */ + volatile u32 DACHorizontalScal; /* 0x1450 */ + volatile u32 DACVidWinStart; /* 0x1454 */ + volatile u32 DACVidWinEnd; /* 0x1458 */ + volatile u32 DACBlendCtrl; /* 0x145C */ + volatile u32 DACHorTim1; /* 0x1460 */ + volatile u32 DACHorTim2; /* 0x1464 */ + volatile u32 DACHorTim3; /* 0x1468 */ + volatile u32 DACVerTim1; /* 0x146C */ + volatile u32 DACVerTim2; /* 0x1470 */ + volatile u32 DACVerTim3; /* 0x1474 */ + volatile u32 DACBorderColor; /* 0x1478 */ + volatile u32 DACSyncCtrl; /* 0x147C */ + volatile u32 DACStreamCtrl; /* 0x1480 */ + volatile u32 DACLUTAddress; /* 0x1484 */ + volatile u32 DACLUTData; /* 0x1488 */ + volatile u32 DACBurstCtrl; /* 0x148C */ + volatile u32 DACCrcTrigger; /* 0x1490 */ + volatile u32 DACCrcDone; /* 0x1494 */ + volatile u32 DACCrcResult1; /* 0x1498 */ + volatile u32 DACCrcResult2; /* 0x149C */ + volatile u32 DACLinecount; /* 0x14A0 */ - volatile unsigned long Fill10[151]; /*GAP 0x14A4 - 0x16FC */ + volatile u32 Fill10[151]; /*GAP 0x14A4 - 0x16FC */ - volatile unsigned long DigVidPortCtrl; /* 0x1700 */ - volatile unsigned long DigVidPortStat; /* 0x1704 */ + volatile u32 DigVidPortCtrl; /* 0x1700 */ + volatile u32 DigVidPortStat; /* 0x1704 */ /* - volatile unsigned long Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC - volatile unsigned long Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT + volatile u32 Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC + volatile u32 Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT */ - volatile unsigned long Fill11[1598]; + volatile u32 Fill11[1598]; /* DWFILL; //GAP 0x3000 ALUT 256MB offset */ - volatile unsigned long Fill_3; + volatile u32 Fill_3; } STG4000REG; From 93019734555f8df32239c5922fe2b770c0a08eaa Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Sat, 24 Mar 2012 11:38:02 +0100 Subject: [PATCH 048/438] fbdev: fix au1*fb builds Commit 1c16697bf9d5b206cb0d2b905a54de5e077296be ("drivers/video/au*fb.c: use devm_ functions) introduced 2 build failures in the au1100fb and au1200fb drivers, fix them. Signed-off-by: Manuel Lauss Signed-off-by: Florian Tobias Schandinat --- drivers/video/au1100fb.c | 5 +++-- drivers/video/au1200fb.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index befcbd8ef019..ffbce4525468 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -499,7 +499,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) au1100fb_fix.mmio_start = regs_res->start; au1100fb_fix.mmio_len = resource_size(regs_res); - if (!devm_request_mem_region(au1100fb_fix.mmio_start, + if (!devm_request_mem_region(&dev->dev, + au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, DRIVER_NAME)) { print_err("fail to lock memory region at 0x%08lx", @@ -516,7 +517,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; - fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev, + fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 3e9a773db09f..7ca79f02056e 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev, + fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { From 70499329202a68f7485415e009e04213672f6811 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 5 Apr 2012 15:48:25 -0700 Subject: [PATCH 049/438] ARM: S5PV210: fix unused LDO supply field from wm8994_pdata According to commit 719a4240("mfd: Remove unused LDO supply field from WM8994 pdata"), the LDO supply field should be removed from the initializer. Cc: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/mach-aquila.c | 4 ++-- arch/arm/mach-s5pv210/mach-goni.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index a9ea64e0da0d..48d018f2332b 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c @@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index 2cf5ed75f390..a8933de3d627 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -674,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ From 0d923490f7dd5d96bc894a09a178117442b8795b Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Thu, 5 Apr 2012 16:08:25 -0700 Subject: [PATCH 050/438] ARM: EXYNOS: Add missing definition for IRQ_I2S0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes following build error when sound support is selected on EXYNOS4 platform. sound/soc/samsung/idma.c: In function ‘idma_close’: sound/soc/samsung/idma.c:327:11: error: ‘IRQ_I2S0’ undeclared (first use in this function) Signed-off-by: Tushar Behera Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/irqs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index 9bee8535d9e0..591e78521a9f 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -212,6 +212,8 @@ #define IRQ_MFC EXYNOS4_IRQ_MFC #define IRQ_SDO EXYNOS4_IRQ_SDO +#define IRQ_I2S0 EXYNOS4_IRQ_I2S0 + #define IRQ_ADC EXYNOS4_IRQ_ADC0 #define IRQ_TC EXYNOS4_IRQ_PEN0 From 32db797f10d465365a52d269c0b313b6b702e711 Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Thu, 5 Apr 2012 22:31:31 -0700 Subject: [PATCH 051/438] ARM: EXYNOS: Fix compile error in exynos5250-cpufreq.c This patch is omitted in v2 patch of Jaecheol Lee. drivers/cpufreq/exynos5250-cpufreq.c: In function 'set_clkdiv': drivers/cpufreq/exynos5250-cpufreq.c:144: error: 'EXYNOS5_CLKDIV_STATCPU0' undeclared (first use in this function) drivers/cpufreq/exynos5250-cpufreq.c:144: error: (Each undeclared identifier is reported only once drivers/cpufreq/exynos5250-cpufreq.c:144: error: for each function it appears in.) drivers/cpufreq/exynos5250-cpufreq.c:150: error: 'EXYNOS5_CLKDIV_CPU1' undeclared (first use in this function) drivers/cpufreq/exynos5250-cpufreq.c:152: error: 'EXYNOS5_CLKDIV_STATCPU1' undeclared (first use in this function) drivers/cpufreq/exynos5250-cpufreq.c: In function 'set_apll': drivers/cpufreq/exynos5250-cpufreq.c:166: error: 'EXYNOS5_CLKMUX_STATCPU' undeclared (first use in this function) drivers/cpufreq/exynos5250-cpufreq.c:173: error: 'EXYNOS5_APLL_LOCK' undeclared (first use in this function) drivers/cpufreq/exynos5250-cpufreq.c: In function 'exynos5250_cpufreq_init': drivers/cpufreq/exynos5250-cpufreq.c:312: error: 'EXYNOS5_CLKDIV_CPU1' undeclared (first use in this function) Cc: Jaecheol Lee Signed-off-by: Jonghwan Choi Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/regs-clock.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index e141c1fd68d8..d9578a58ae7f 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -255,9 +255,15 @@ /* For EXYNOS5250 */ +#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000) #define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100) #define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200) +#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400) #define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500) +#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504) +#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) +#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) + #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) From 45038367c271f83b649b16551bf2d8174b203cb9 Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:38 +0200 Subject: [PATCH 052/438] mtip32xx: Add new bitwise flag 'dd_flag' * Merged the following flags into one variable 'dd_flag': * drv_cleanup_done * resumeflag * Added the following flags into 'dd_flag' * remove pending * init done * Removed 'ftlrebuildflag' (similar flag is already part of mti_port->flags) Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 211 +++++++++++++++++++++++------- drivers/block/mtip32xx/mtip32xx.h | 12 +- 2 files changed, 168 insertions(+), 55 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index c37073ddf7d4..34b395d2d98d 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -36,6 +36,7 @@ #include #include #include <../drivers/ata/ahci.h> +#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -44,6 +45,7 @@ #define HW_PORT_PRIV_DMA_SZ \ (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) +#define HOST_CAP_NZDMA (1 << 19) #define HOST_HSORG 0xFC #define HSORG_DISABLE_SLOTGRP_INTR (1<<24) #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) @@ -139,6 +141,12 @@ static void mtip_command_cleanup(struct driver_data *dd) int group = 0, commandslot = 0, commandindex = 0; struct mtip_cmd *command; struct mtip_port *port = dd->port; + static int in_progress; + + if (in_progress) + return; + + in_progress = 1; for (group = 0; group < 4; group++) { for (commandslot = 0; commandslot < 32; commandslot++) { @@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd) up(&port->cmd_slot); - atomic_set(&dd->drv_cleanup_done, true); + set_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag); + in_progress = 0; } /* @@ -262,6 +271,9 @@ static int hba_reset_nosleep(struct driver_data *dd) && time_before(jiffies, timeout)) mdelay(1); + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) + return -1; + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) return -1; @@ -451,6 +463,9 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + return; + /* * Chip quirk: escalate to hba reset if * PxCMD.CR not clear after 500 ms @@ -479,6 +494,9 @@ static void mtip_restart_port(struct mtip_port *port) while (time_before(jiffies, timeout)) ; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + return; + /* Clear PxSCTL.DET */ writel(readl(port->mmio + PORT_SCR_CTL) & ~1, port->mmio + PORT_SCR_CTL); @@ -490,6 +508,9 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + return; + if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) dev_warn(&port->dd->pdev->dev, "COM reset failed\n"); @@ -520,7 +541,7 @@ static void mtip_timeout_function(unsigned long int data) if (unlikely(!port)) return; - if (atomic_read(&port->dd->resumeflag) == true) { + if (test_bit(MTIP_DD_FLAG_RESUME_BIT, &port->dd->dd_flag)) { mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(30000)); return; @@ -970,6 +991,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) /* don't proceed further */ return IRQ_HANDLED; } + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &dd->dd_flag)) + return rv; mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); } @@ -1040,6 +1064,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) msleep(20); continue; /* svc thd is actively issuing commands */ } + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) + return -EFAULT; /* * Ignore s_active bit 0 of array element 0. * This bit will always be set @@ -1161,6 +1188,12 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command did not complete [%d] " "within timeout of %lu ms\n", atomic, timeout); + if (mtip_check_surprise_removal(port->dd->pdev) || + test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + rv = -ENXIO; + goto exec_ic_exit; + } rv = -EAGAIN; } @@ -1168,6 +1201,15 @@ static int mtip_exec_internal_command(struct mtip_port *port, & (1 << MTIP_TAG_INTERNAL)) { dev_warn(&port->dd->pdev->dev, "Retiring internal command but CI is 1.\n"); + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + hba_reset_nosleep(port->dd); + rv = -ENXIO; + } else { + mtip_restart_port(port); + rv = -EAGAIN; + } + goto exec_ic_exit; } } else { @@ -1177,8 +1219,14 @@ static int mtip_exec_internal_command(struct mtip_port *port, while ((readl( port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) - && time_before(jiffies, timeout)) - ; + && time_before(jiffies, timeout)) { + if (mtip_check_surprise_removal(port->dd->pdev) || + test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + rv = -ENXIO; + goto exec_ic_exit; + } + } if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { @@ -1186,9 +1234,17 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command did not complete [%d]\n", atomic); rv = -EAGAIN; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + hba_reset_nosleep(port->dd); + rv = -ENXIO; + } else { + mtip_restart_port(port); + rv = -EAGAIN; + } } } - +exec_ic_exit: /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); @@ -1242,6 +1298,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) int rv = 0; struct host_to_dev_fis fis; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + return -EFAULT; + /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1507,9 +1566,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) fis.device = command[6] & ~0x10; /* Clear the dev bit*/ - dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, " - "nsect %x, sect %x, lcyl %x, " - "hcyl %x, sel %x\n", + dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", __func__, command[0], command[1], @@ -1536,8 +1593,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) command[4] = reply->cyl_low; command[5] = reply->cyl_hi; - dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, " - "err %x , cyl_lo %x cyl_hi %x\n", + dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", __func__, command[0], command[1], @@ -2082,14 +2138,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, struct host_to_dev_fis *fis; struct mtip_port *port = dd->port; struct mtip_cmd *command = &port->commands[tag]; + int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; /* Map the scatter list for DMA access */ - if (dir == READ) - nents = dma_map_sg(&dd->pdev->dev, command->sg, - nents, DMA_FROM_DEVICE); - else - nents = dma_map_sg(&dd->pdev->dev, command->sg, - nents, DMA_TO_DEVICE); + nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); command->scatter_ents = nents; @@ -2129,7 +2181,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, */ command->comp_data = dd; command->comp_func = mtip_async_complete; - command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + command->direction = dma_dir; /* * Set the completion function and data for the command passed @@ -2193,6 +2245,10 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, down(&dd->port->cmd_slot); *tag = get_slot(dd->port); + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { + up(&dd->port->cmd_slot); + return NULL; + } if (unlikely(*tag < 0)) return NULL; @@ -2209,7 +2265,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t hw_show_registers(struct device *dev, +static ssize_t mtip_hw_show_registers(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2255,7 +2311,7 @@ static ssize_t hw_show_registers(struct device *dev, return size; } -static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); +static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); /* * Create the sysfs related attributes. @@ -2386,10 +2442,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) "FTL rebuild in progress. Polling for completion.\n"); start = jiffies; - dd->ftlrebuildflag = 1; timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); do { + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &dd->dd_flag))) + return -EFAULT; if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; @@ -2410,22 +2468,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) dev_warn(&dd->pdev->dev, "FTL rebuild complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); - dd->ftlrebuildflag = 0; mtip_block_initialize(dd); - break; + return 0; } ssleep(10); } while (time_before(jiffies, timeout)); /* Check for timeout */ - if (dd->ftlrebuildflag) { - dev_err(&dd->pdev->dev, + dev_err(&dd->pdev->dev, "Timed out waiting for FTL rebuild to complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); - return -EFAULT; - } - - return 0; + return -EFAULT; } /* @@ -2456,6 +2509,9 @@ static int mtip_service_thread(void *data) if (kthread_should_stop()) break; + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + &dd->dd_flag))) + break; set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; @@ -2515,6 +2571,7 @@ static int mtip_hw_init(struct driver_data *dd) int i; int rv; unsigned int num_command_slots; + unsigned long timeout, timetaken; dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; @@ -2625,14 +2682,43 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->mmio + i*0x80 + PORT_SDBV; } - /* Reset the HBA. */ - if (mtip_hba_reset(dd) < 0) { - dev_err(&dd->pdev->dev, - "Card did not reset within timeout\n"); - rv = -EIO; + timetaken = jiffies; + timeout = jiffies + msecs_to_jiffies(30000); + while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) && + time_before(jiffies, timeout)) { + mdelay(100); + } + if (unlikely(mtip_check_surprise_removal(dd->pdev))) { + timetaken = jiffies - timetaken; + dev_warn(&dd->pdev->dev, + "Surprise removal detected at %u ms\n", + jiffies_to_msecs(timetaken)); + rv = -ENODEV; + goto out2 ; + } + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { + timetaken = jiffies - timetaken; + dev_warn(&dd->pdev->dev, + "Removal detected at %u ms\n", + jiffies_to_msecs(timetaken)); + rv = -EFAULT; goto out2; } + /* Conditionally reset the HBA. */ + if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) { + if (mtip_hba_reset(dd) < 0) { + dev_err(&dd->pdev->dev, + "Card did not reset within timeout\n"); + rv = -EIO; + goto out2; + } + } else { + /* Clear any pending interrupts on the HBA */ + writel(readl(dd->mmio + HOST_IRQ_STAT), + dd->mmio + HOST_IRQ_STAT); + } + mtip_init_port(dd->port); mtip_start_port(dd->port); @@ -2662,6 +2748,12 @@ static int mtip_hw_init(struct driver_data *dd) mod_timer(&dd->port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); + + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { + rv = -EFAULT; + goto out3; + } + if (mtip_get_identify(dd->port, NULL) < 0) { rv = -EFAULT; goto out3; @@ -2714,9 +2806,12 @@ static int mtip_hw_exit(struct driver_data *dd) * Send standby immediate (E0h) to the drive so that it * saves its state. */ - if (atomic_read(&dd->drv_cleanup_done) != true) { + if (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { - mtip_standby_immediate(dd->port); + if (test_bit(MTIP_FLAG_REBUILD_BIT, &dd->dd_flag)) + if (mtip_standby_immediate(dd->port)) + dev_warn(&dd->pdev->dev, + "STANDBY IMMEDIATE failed\n"); /* de-initialize the port. */ mtip_deinit_port(dd->port); @@ -2894,6 +2989,9 @@ static int mtip_block_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) + return -ENOTTY; + switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -2929,6 +3027,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; + if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) + return -ENOTTY; + switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -3051,6 +3152,11 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) int nents = 0; int tag = 0; + if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { + bio_endio(bio, -ENXIO); + return; + } + if (unlikely(!bio_has_data(bio))) { blk_queue_flush(queue, 0); bio_endio(bio, 0); @@ -3063,7 +3169,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { dev_warn(&dd->pdev->dev, - "Maximum number of SGL entries exceeded"); + "Maximum number of SGL entries exceeded\n"); bio_io_error(bio); mtip_hw_release_scatterlist(dd, tag); return; @@ -3212,8 +3318,10 @@ skip_create_disk: kobject_put(kobj); } - if (dd->mtip_svc_handler) + if (dd->mtip_svc_handler) { + set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); return rv; /* service thread created for handling rebuild */ + } start_service_thread: sprintf(thd_name, "mtip_svc_thd_%02d", index); @@ -3228,6 +3336,9 @@ start_service_thread: goto kthread_run_error; } + if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) + rv = wait_for_rebuild; + return rv; kthread_run_error: @@ -3274,10 +3385,12 @@ static int mtip_block_remove(struct driver_data *dd) } /* Clean up the sysfs attributes managed by the protocol layer. */ - kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); - if (kobj) { - mtip_hw_sysfs_exit(dd, kobj); - kobject_put(kobj); + if (test_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag)) { + kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); + if (kobj) { + mtip_hw_sysfs_exit(dd, kobj); + kobject_put(kobj); + } } /* @@ -3361,8 +3474,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, return -ENOMEM; } - atomic_set(&dd->resumeflag, false); - /* Attach the private data to this PCI device. */ pci_set_drvdata(pdev, dd); @@ -3419,7 +3530,8 @@ static int mtip_pci_probe(struct pci_dev *pdev, * instance number. */ instance++; - + if (rv != MTIP_FTL_REBUILD_MAGIC) + set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); goto done; block_initialize_err: @@ -3433,9 +3545,6 @@ iomap_err: pci_set_drvdata(pdev, NULL); return rv; done: - /* Set the atomic variable as 0 */ - atomic_set(&dd->drv_cleanup_done, false); - return rv; } @@ -3451,8 +3560,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; + set_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag); + if (mtip_check_surprise_removal(pdev)) { - while (atomic_read(&dd->drv_cleanup_done) == false) { + while (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { counter++; msleep(20); if (counter == 10) { @@ -3490,7 +3601,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) return -EFAULT; } - atomic_set(&dd->resumeflag, true); + set_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); /* Disable ports & interrupts then send standby immediate */ rv = mtip_block_suspend(dd); @@ -3556,7 +3667,7 @@ static int mtip_pci_resume(struct pci_dev *pdev) dev_err(&pdev->dev, "Unable to resume\n"); err: - atomic_set(&dd->resumeflag, false); + clear_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); return rv; } diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index e0554a8f2233..f4e46cc81d55 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -121,6 +121,12 @@ #define MTIP_FLAG_REBUILD_BIT 5 #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 +/* below are bit numbers in 'dd_flag' defined in driver_data */ +#define MTIP_DD_FLAG_REMOVE_PENDING_BIT 1 +#define MTIP_DD_FLAG_RESUME_BIT 2 +#define MTIP_DD_FLAG_CLEANUP_BIT 3 +#define MTIP_DD_FLAG_INIT_DONE_BIT 4 + /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { /* @@ -404,13 +410,9 @@ struct driver_data { unsigned slot_groups; /* number of slot groups the product supports */ - atomic_t drv_cleanup_done; /* Atomic variable for SRSI */ - unsigned long index; /* Index to determine the disk name */ - unsigned int ftlrebuildflag; /* FTL rebuild flag */ - - atomic_t resumeflag; /* Atomic variable to track suspend/resume */ + unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ }; From dad40f16ff683a10f4f2bea55a0b9fd86d3db58e Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:38 +0200 Subject: [PATCH 053/438] mtip32xx: make setting comp_time as common Moved setting completion time into mtip_issue_ncq_command() Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 34b395d2d98d..aaa82453ae74 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -306,6 +306,10 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); spin_unlock_irqrestore(&port->cmd_issue_lock, flags); + + /* Set the command's timeout value.*/ + port->commands[tag].comp_time = jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); } /* @@ -824,10 +828,6 @@ static void mtip_handle_tfe(struct driver_data *dd) set_bit(tag, tagaccum); - /* Update the timeout value. */ - port->commands[tag].comp_time = - jiffies + msecs_to_jiffies( - MTIP_NCQ_COMMAND_TIMEOUT_MS); /* Re-issue the command. */ mtip_issue_ncq_command(port, tag); @@ -2204,9 +2204,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, /* Issue the command to the hardware */ mtip_issue_ncq_command(port, tag); - /* Set the command's timeout value.*/ - port->commands[tag].comp_time = jiffies + msecs_to_jiffies( - MTIP_NCQ_COMMAND_TIMEOUT_MS); + return; } /* @@ -2538,10 +2536,6 @@ static int mtip_service_thread(void *data) /* Issue the command to the hardware */ mtip_issue_ncq_command(port, slot); - /* Set the command's timeout value.*/ - port->commands[slot].comp_time = jiffies + - msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS); - clear_bit(slot, port->cmds_to_issue); } From f65872177d838a33e90cbae25625b9bec05134ca Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:38 +0200 Subject: [PATCH 054/438] mtip32xx: Add new sysfs entry 'status' * Add support for detecting the following device status - write protect - over temp (thermal shutdown) * Add new sysfs entry 'status', possible values - online, write_protect, thermal_shutdown * Add new file 'sysfs-block-rssd' to document ABI (Reported-by: Greg Kroah-Hartman) Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-block-rssd | 18 ++ drivers/block/mtip32xx/mtip32xx.c | 323 +++++++++++++++++++-- drivers/block/mtip32xx/mtip32xx.h | 19 ++ 3 files changed, 331 insertions(+), 29 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-block-rssd diff --git a/Documentation/ABI/testing/sysfs-block-rssd b/Documentation/ABI/testing/sysfs-block-rssd new file mode 100644 index 000000000000..d535757799fe --- /dev/null +++ b/Documentation/ABI/testing/sysfs-block-rssd @@ -0,0 +1,18 @@ +What: /sys/block/rssd*/registers +Date: March 2012 +KernelVersion: 3.3 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps below driver information and + hardware registers. + - S ACTive + - Command Issue + - Allocated + - Completed + - PORT IRQ STAT + - HOST IRQ STAT + +What: /sys/block/rssd*/status +Date: April 2012 +KernelVersion: 3.4 +Contact: Asai Thambi S P +Description: This is a read-only file. Indicates the status of the device. diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index aaa82453ae74..79fdb063f9c0 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -725,6 +725,10 @@ static void print_tags(struct driver_data *dd, dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count); } +static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, + dma_addr_t buffer_dma, unsigned int sectors); +static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, + struct smart_attr *attrib); /* * Handle an error. * @@ -735,12 +739,15 @@ static void print_tags(struct driver_data *dd, */ static void mtip_handle_tfe(struct driver_data *dd) { - int group, tag, bit, reissue; + int group, tag, bit, reissue, rv; struct mtip_port *port; - struct mtip_cmd *command; + struct mtip_cmd *cmd; u32 completed; struct host_to_dev_fis *fis; unsigned long tagaccum[SLOTBITS_IN_LONGS]; + unsigned char *buf; + char *fail_reason = NULL; + int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0; dev_warn(&dd->pdev->dev, "Taskfile error\n"); @@ -772,13 +779,13 @@ static void mtip_handle_tfe(struct driver_data *dd) if (tag == MTIP_TAG_INTERNAL) continue; - command = &port->commands[tag]; - if (likely(command->comp_func)) { + cmd = &port->commands[tag]; + if (likely(cmd->comp_func)) { set_bit(tag, tagaccum); - atomic_set(&port->commands[tag].active, 0); - command->comp_func(port, + atomic_set(&cmd->active, 0); + cmd->comp_func(port, tag, - command->comp_data, + cmd->comp_data, 0); } else { dev_err(&port->dd->pdev->dev, @@ -798,6 +805,38 @@ static void mtip_handle_tfe(struct driver_data *dd) mdelay(20); mtip_restart_port(port); + /* Trying to determine the cause of the error */ + rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, + dd->port->log_buf, + dd->port->log_buf_dma, 1); + if (rv) { + dev_warn(&dd->pdev->dev, + "Error in READ LOG EXT (10h) command\n"); + /* non-critical error, don't fail the load */ + } else { + buf = (unsigned char *)dd->port->log_buf; + if (buf[259] & 0x1) { + dev_info(&dd->pdev->dev, + "Write protect bit is set.\n"); + set_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag); + fail_all_ncq_write = 1; + fail_reason = "write protect"; + } + if (buf[288] == 0xF7) { + dev_info(&dd->pdev->dev, + "Exceeded Tmax, drive in thermal shutdown.\n"); + set_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag); + fail_all_ncq_cmds = 1; + fail_reason = "thermal shutdown"; + } + if (buf[288] == 0xBF) { + dev_info(&dd->pdev->dev, + "Drive indicates rebuild has failed.\n"); + fail_all_ncq_cmds = 1; + fail_reason = "rebuild failed"; + } + } + /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); @@ -806,25 +845,44 @@ static void mtip_handle_tfe(struct driver_data *dd) for (bit = 0; bit < 32; bit++) { reissue = 1; tag = (group << 5) + bit; + cmd = &port->commands[tag]; /* If the active bit is set re-issue the command */ - if (atomic_read(&port->commands[tag].active) == 0) + if (atomic_read(&cmd->active) == 0) continue; - fis = (struct host_to_dev_fis *) - port->commands[tag].command; + fis = (struct host_to_dev_fis *)cmd->command; /* Should re-issue? */ if (tag == MTIP_TAG_INTERNAL || fis->command == ATA_CMD_SET_FEATURES) reissue = 0; + else { + if (fail_all_ncq_cmds || + (fail_all_ncq_write && + fis->command == ATA_CMD_FPDMA_WRITE)) { + dev_warn(&dd->pdev->dev, + " Fail: %s w/tag %d [%s].\n", + fis->command == ATA_CMD_FPDMA_WRITE ? + "write" : "read", + tag, + fail_reason != NULL ? + fail_reason : "unknown"); + atomic_set(&cmd->active, 0); + if (cmd->comp_func) { + cmd->comp_func(port, tag, + cmd->comp_data, + -ENODATA); + } + continue; + } + } /* * First check if this command has * exceeded its retries. */ - if (reissue && - (port->commands[tag].retries-- > 0)) { + if (reissue && (cmd->retries-- > 0)) { set_bit(tag, tagaccum); @@ -837,13 +895,13 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Retire a command that will not be reissued */ dev_warn(&port->dd->pdev->dev, "retiring tag %d\n", tag); - atomic_set(&port->commands[tag].active, 0); + atomic_set(&cmd->active, 0); - if (port->commands[tag].comp_func) - port->commands[tag].comp_func( + if (cmd->comp_func) + cmd->comp_func( port, tag, - port->commands[tag].comp_data, + cmd->comp_data, PORT_IRQ_TF_ERR); else dev_warn(&port->dd->pdev->dev, @@ -1374,6 +1432,7 @@ static int mtip_standby_immediate(struct mtip_port *port) { int rv; struct host_to_dev_fis fis; + unsigned long start; /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); @@ -1381,15 +1440,150 @@ static int mtip_standby_immediate(struct mtip_port *port) fis.opts = 1 << 7; fis.command = ATA_CMD_STANDBYNOW1; - /* Execute the command. Use a 15-second timeout for large drives. */ + start = jiffies; rv = mtip_exec_internal_command(port, &fis, 5, 0, 0, 0, - GFP_KERNEL, + GFP_ATOMIC, 15000); + dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n", + jiffies_to_msecs(jiffies - start)); + if (rv) + dev_warn(&port->dd->pdev->dev, + "STANDBY IMMEDIATE command failed.\n"); + + return rv; +} + +/* + * Issue a READ LOG EXT command to the device. + * + * @port pointer to the port structure. + * @page page number to fetch + * @buffer pointer to buffer + * @buffer_dma dma address corresponding to @buffer + * @sectors page length to fetch, in sectors + * + * return value + * @rv return value from mtip_exec_internal_command() + */ +static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, + dma_addr_t buffer_dma, unsigned int sectors) +{ + struct host_to_dev_fis fis; + + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = ATA_CMD_READ_LOG_EXT; + fis.sect_count = sectors & 0xFF; + fis.sect_cnt_ex = (sectors >> 8) & 0xFF; + fis.lba_low = page; + fis.lba_mid = 0; + fis.device = ATA_DEVICE_OBS; + + memset(buffer, 0, sectors * ATA_SECT_SIZE); + + return mtip_exec_internal_command(port, + &fis, + 5, + buffer_dma, + sectors * ATA_SECT_SIZE, + 0, + GFP_ATOMIC, + MTIP_INTERNAL_COMMAND_TIMEOUT_MS); +} + +/* + * Issue a SMART READ DATA command to the device. + * + * @port pointer to the port structure. + * @buffer pointer to buffer + * @buffer_dma dma address corresponding to @buffer + * + * return value + * @rv return value from mtip_exec_internal_command() + */ +static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer, + dma_addr_t buffer_dma) +{ + struct host_to_dev_fis fis; + + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = ATA_CMD_SMART; + fis.features = 0xD0; + fis.sect_count = 1; + fis.lba_mid = 0x4F; + fis.lba_hi = 0xC2; + fis.device = ATA_DEVICE_OBS; + + return mtip_exec_internal_command(port, + &fis, + 5, + buffer_dma, + ATA_SECT_SIZE, + 0, + GFP_ATOMIC, + 15000); +} + +/* + * Get the value of a smart attribute + * + * @port pointer to the port structure + * @id attribute number + * @attrib pointer to return attrib information corresponding to @id + * + * return value + * -EINVAL NULL buffer passed or unsupported attribute @id. + * -EPERM Identify data not valid, SMART not supported or not enabled + */ +static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, + struct smart_attr *attrib) +{ + int rv, i; + struct smart_attr *pattr; + + if (!attrib) + return -EINVAL; + + if (!port->identify_valid) { + dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n"); + return -EPERM; + } + if (!(port->identify[82] & 0x1)) { + dev_warn(&port->dd->pdev->dev, "SMART not supported\n"); + return -EPERM; + } + if (!(port->identify[85] & 0x1)) { + dev_warn(&port->dd->pdev->dev, "SMART not enabled\n"); + return -EPERM; + } + + memset(port->smart_buf, 0, ATA_SECT_SIZE); + rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma); + if (rv) { + dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n"); + return rv; + } + + pattr = (struct smart_attr *)(port->smart_buf + 2); + for (i = 0; i < 29; i++, pattr++) + if (pattr->attr_id == id) { + memcpy(attrib, pattr, sizeof(struct smart_attr)); + break; + } + + if (i == 29) { + dev_warn(&port->dd->pdev->dev, + "Query for invalid SMART attribute ID\n"); + rv = -EINVAL; + } return rv; } @@ -2272,7 +2466,7 @@ static ssize_t mtip_hw_show_registers(struct device *dev, int size = 0; int n; - size += sprintf(&buf[size], "%s:\ns_active:\n", __func__); + size += sprintf(&buf[size], "S ACTive:\n"); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", @@ -2296,20 +2490,39 @@ static ssize_t mtip_hw_show_registers(struct device *dev, group_allocated); } - size += sprintf(&buf[size], "completed:\n"); + size += sprintf(&buf[size], "Completed:\n"); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", readl(dd->port->completed[n])); - size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n", + size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n", + size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n", readl(dd->mmio + HOST_IRQ_STAT)); return size; } + +static ssize_t mtip_hw_show_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; + + if (test_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "thermal_shutdown\n"); + else if (test_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "write_protect\n"); + else + size += sprintf(buf, "%s", "online\n"); + + return size; +} + static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); +static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); /* * Create the sysfs related attributes. @@ -2328,7 +2541,10 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (sysfs_create_file(kobj, &dev_attr_registers.attr)) dev_warn(&dd->pdev->dev, - "Error creating registers sysfs entry\n"); + "Error creating 'registers' sysfs entry\n"); + if (sysfs_create_file(kobj, &dev_attr_status.attr)) + dev_warn(&dd->pdev->dev, + "Error creating 'status' sysfs entry\n"); return 0; } @@ -2348,6 +2564,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) return -EINVAL; sysfs_remove_file(kobj, &dev_attr_registers.attr); + sysfs_remove_file(kobj, &dev_attr_status.attr); return 0; } @@ -2566,6 +2783,8 @@ static int mtip_hw_init(struct driver_data *dd) int rv; unsigned int num_command_slots; unsigned long timeout, timetaken; + unsigned char *buf; + struct smart_attr attr242; dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; @@ -2600,7 +2819,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Allocate memory for the command list. */ dd->port->command_list = dmam_alloc_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), &dd->port->command_list_dma, GFP_KERNEL); if (!dd->port->command_list) { @@ -2613,7 +2832,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Clear the memory we have allocated. */ memset(dd->port->command_list, 0, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2)); + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4)); /* Setup the addresse of the RX FIS. */ dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ; @@ -2629,10 +2848,19 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->identify_dma = dd->port->command_tbl_dma + HW_CMD_TBL_AR_SZ; - /* Setup the address of the sector buffer. */ + /* Setup the address of the sector buffer - for some non-ncq cmds */ dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE; dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE; + /* Setup the address of the log buf - for read log command */ + dd->port->log_buf = (void *)dd->port->sector_buffer + ATA_SECT_SIZE; + dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE; + + /* Setup the address of the smart buf - for smart read data command */ + dd->port->smart_buf = (void *)dd->port->log_buf + ATA_SECT_SIZE; + dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE; + + /* Point the command headers at the command tables. */ for (i = 0; i < num_command_slots; i++) { dd->port->commands[i].command_header = @@ -2759,6 +2987,43 @@ static int mtip_hw_init(struct driver_data *dd) return MTIP_FTL_REBUILD_MAGIC; } mtip_dump_identify(dd->port); + + /* check write protect, over temp and rebuild statuses */ + rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, + dd->port->log_buf, + dd->port->log_buf_dma, 1); + if (rv) { + dev_warn(&dd->pdev->dev, + "Error in READ LOG EXT (10h) command\n"); + /* non-critical error, don't fail the load */ + } else { + buf = (unsigned char *)dd->port->log_buf; + if (buf[259] & 0x1) { + dev_info(&dd->pdev->dev, + "Write protect bit is set.\n"); + set_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag); + } + if (buf[288] == 0xF7) { + dev_info(&dd->pdev->dev, + "Exceeded Tmax, drive in thermal shutdown.\n"); + set_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag); + } + if (buf[288] == 0xBF) { + dev_info(&dd->pdev->dev, + "Drive indicates rebuild has failed.\n"); + /* TODO */ + } + } + + /* get write protect progess */ + memset(&attr242, 0, sizeof(struct smart_attr)); + if (mtip_get_smart_attr(dd->port, 242, &attr242)) + dev_warn(&dd->pdev->dev, + "Unable to check write protect progress\n"); + else + dev_info(&dd->pdev->dev, + "Write protect progress: %d%% (%d blocks)\n", + attr242.cur, attr242.data); return rv; out3: @@ -2776,7 +3041,7 @@ out2: /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), dd->port->command_list, dd->port->command_list_dma); out1: @@ -2825,7 +3090,7 @@ static int mtip_hw_exit(struct driver_data *dd) /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), dd->port->command_list, dd->port->command_list_dma); /* Free the memory allocated for the for structure. */ @@ -3378,7 +3643,7 @@ static int mtip_block_remove(struct driver_data *dd) kthread_stop(dd->mtip_svc_handler); } - /* Clean up the sysfs attributes managed by the protocol layer. */ + /* Clean up the sysfs attributes, if created */ if (test_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag)) { kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); if (kobj) { diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index f4e46cc81d55..ea5c7e7cb50d 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -127,6 +127,19 @@ #define MTIP_DD_FLAG_CLEANUP_BIT 3 #define MTIP_DD_FLAG_INIT_DONE_BIT 4 +#define MTIP_DD_FLAG_WRITE_PROTECT_BIT 5 +#define MTIP_DD_FLAG_OVER_TEMP_BIT 6 +#define MTIP_DD_FLAG_REBUILD_FAILED_BIT 7 + +__packed struct smart_attr{ + u8 attr_id; + u16 flags; + u8 cur; + u8 worst; + u32 data; + u8 res[3]; +}; + /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { /* @@ -351,6 +364,12 @@ struct mtip_port { * when the command slot and all associated data structures * are no longer needed. */ + u16 *log_buf; + dma_addr_t log_buf_dma; + + u8 *smart_buf; + dma_addr_t smart_buf_dma; + unsigned long allocated[SLOTBITS_IN_LONGS]; /* * used to queue commands when an internal command is in progress From 8182b495281764ca518781e876c91900e75088d2 Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:38 +0200 Subject: [PATCH 055/438] mtip32xx: misc changes * Handle the interrupt completion of polled internal commands * Do not check remove pending flag for standby command * On rebuild failure, - set corresponding bit dd_flag - do not send standby command * Free ida index in remove path Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 66 ++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 79fdb063f9c0..be96626accec 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -708,6 +708,14 @@ static void mtip_completion(struct mtip_port *port, complete(waiting); } +static void mtip_null_completion(struct mtip_port *port, + int tag, + void *data, + int status) +{ + return; +} + /* * Helper function for tag logging */ @@ -992,8 +1000,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) } } - dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat); - return; } @@ -1161,7 +1167,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) * -EAGAIN Time out waiting for command to complete. */ static int mtip_exec_internal_command(struct mtip_port *port, - void *fis, + struct host_to_dev_fis *fis, int fis_len, dma_addr_t buffer, int buf_len, @@ -1190,14 +1196,17 @@ static int mtip_exec_internal_command(struct mtip_port *port, set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { - /* wait for io to complete if non atomic */ - if (mtip_quiesce_io(port, 5000) < 0) { - dev_warn(&port->dd->pdev->dev, - "Failed to quiesce IO\n"); - release_slot(port, MTIP_TAG_INTERNAL); - clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); - return -EBUSY; + if (fis->command != ATA_CMD_STANDBYNOW1) { + /* wait for io to complete if non atomic */ + if (mtip_quiesce_io(port, 5000) < 0) { + dev_warn(&port->dd->pdev->dev, + "Failed to quiesce IO\n"); + release_slot(port, MTIP_TAG_INTERNAL); + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, + &port->flags); + wake_up_interruptible(&port->svc_wait); + return -EBUSY; + } } /* Set the completion function and data for the command. */ @@ -1207,7 +1216,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, } else { /* Clear completion - we're going to poll */ int_cmd->comp_data = NULL; - int_cmd->comp_func = NULL; + int_cmd->comp_func = mtip_null_completion; } /* Copy the command to the command table */ @@ -1273,12 +1282,14 @@ static int mtip_exec_internal_command(struct mtip_port *port, } else { /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); - - while ((readl( - port->cmd_issue[MTIP_TAG_INTERNAL]) - & (1 << MTIP_TAG_INTERNAL)) - && time_before(jiffies, timeout)) { - if (mtip_check_surprise_removal(port->dd->pdev) || + while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) + && time_before(jiffies, timeout)) { + if (mtip_check_surprise_removal(port->dd->pdev)) { + rv = -ENXIO; + goto exec_ic_exit; + } + if ((fis->command != ATA_CMD_STANDBYNOW1) && test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { rv = -ENXIO; @@ -1289,8 +1300,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { dev_err(&port->dd->pdev->dev, - "Internal command did not complete [%d]\n", - atomic); + "Internal command did not complete [atomic]\n"); rv = -EAGAIN; if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { @@ -2758,7 +2768,9 @@ static int mtip_service_thread(void *data) clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) { - mtip_ftl_rebuild_poll(dd); + if (!mtip_ftl_rebuild_poll(dd)) + set_bit(MTIP_DD_FLAG_REBUILD_FAILED_BIT, + &dd->dd_flag); clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags); } clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); @@ -3067,7 +3079,7 @@ static int mtip_hw_exit(struct driver_data *dd) */ if (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { - if (test_bit(MTIP_FLAG_REBUILD_BIT, &dd->dd_flag)) + if (!test_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags)) if (mtip_standby_immediate(dd->port)) dev_warn(&dd->pdev->dev, "STANDBY IMMEDIATE failed\n"); @@ -3657,6 +3669,11 @@ static int mtip_block_remove(struct driver_data *dd) * from /dev */ del_gendisk(dd->disk); + + spin_lock(&rssd_index_lock); + ida_remove(&rssd_index_ida, dd->index); + spin_unlock(&rssd_index_lock); + blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; @@ -3686,6 +3703,11 @@ static int mtip_block_shutdown(struct driver_data *dd) /* Delete our gendisk structure, and cleanup the blk queue. */ del_gendisk(dd->disk); + + spin_lock(&rssd_index_lock); + ida_remove(&rssd_index_ida, dd->index); + spin_unlock(&rssd_index_lock); + blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; From 8a857a880bd83ba4f217d55dd4a623a7e4b5cb47 Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:38 +0200 Subject: [PATCH 056/438] mtip32xx: Shorten macro names Shortened macros used to represent mtip_port->flags and dd->dd_flag Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 124 +++++++++++++++--------------- drivers/block/mtip32xx/mtip32xx.h | 26 +++---- 2 files changed, 74 insertions(+), 76 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index be96626accec..e57864a7912e 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -173,7 +173,7 @@ static void mtip_command_cleanup(struct driver_data *dd) up(&port->cmd_slot); - set_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); in_progress = 0; } @@ -271,7 +271,7 @@ static int hba_reset_nosleep(struct driver_data *dd) && time_before(jiffies, timeout)) mdelay(1); - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) return -1; if (readl(dd->mmio + HOST_CTL) & HOST_RESET) @@ -467,7 +467,7 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) return; /* @@ -498,7 +498,7 @@ static void mtip_restart_port(struct mtip_port *port) while (time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) return; /* Clear PxSCTL.DET */ @@ -512,7 +512,7 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) return; if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) @@ -545,7 +545,7 @@ static void mtip_timeout_function(unsigned long int data) if (unlikely(!port)) return; - if (test_bit(MTIP_DD_FLAG_RESUME_BIT, &port->dd->dd_flag)) { + if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(30000)); return; @@ -572,7 +572,7 @@ static void mtip_timeout_function(unsigned long int data) cmdto_cnt++; if (cmdto_cnt == 1) - set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); /* * Clear the completed bit. This should prevent @@ -610,7 +610,7 @@ static void mtip_timeout_function(unsigned long int data) "%d commands timed out: restarting port", cmdto_cnt); mtip_restart_port(port); - clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); } @@ -765,7 +765,7 @@ static void mtip_handle_tfe(struct driver_data *dd) del_timer(&port->cmd_timer); /* Set eh_active */ - set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); /* Loop through all the groups */ for (group = 0; group < dd->slot_groups; group++) { @@ -826,14 +826,14 @@ static void mtip_handle_tfe(struct driver_data *dd) if (buf[259] & 0x1) { dev_info(&dd->pdev->dev, "Write protect bit is set.\n"); - set_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); fail_all_ncq_write = 1; fail_reason = "write protect"; } if (buf[288] == 0xF7) { dev_info(&dd->pdev->dev, "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); fail_all_ncq_cmds = 1; fail_reason = "thermal shutdown"; } @@ -920,7 +920,7 @@ static void mtip_handle_tfe(struct driver_data *dd) print_tags(dd, "TFE tags reissued:", tagaccum); /* clear eh_active */ - clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); mod_timer(&port->cmd_timer, @@ -988,7 +988,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) struct mtip_port *port = dd->port; struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; - if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && + if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL))) { if (cmd->comp_func) { @@ -1055,7 +1055,7 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) /* don't proceed further */ return IRQ_HANDLED; } - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) return rv; @@ -1123,13 +1123,12 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) to = jiffies + msecs_to_jiffies(timeout); do { - if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) && - test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { + if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && + test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { msleep(20); continue; /* svc thd is actively issuing commands */ } - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) return -EFAULT; /* * Ignore s_active bit 0 of array element 0. @@ -1193,7 +1192,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command already active\n"); return -EBUSY; } - set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { if (fis->command != ATA_CMD_STANDBYNOW1) { @@ -1202,8 +1201,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, dev_warn(&port->dd->pdev->dev, "Failed to quiesce IO\n"); release_slot(port, MTIP_TAG_INTERNAL); - clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, - &port->flags); + clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); return -EBUSY; } @@ -1256,7 +1254,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, "within timeout of %lu ms\n", atomic, timeout); if (mtip_check_surprise_removal(port->dd->pdev) || - test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; @@ -1268,7 +1266,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, & (1 << MTIP_TAG_INTERNAL)) { dev_warn(&port->dd->pdev->dev, "Retiring internal command but CI is 1.\n"); - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { hba_reset_nosleep(port->dd); rv = -ENXIO; @@ -1290,7 +1288,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, goto exec_ic_exit; } if ((fis->command != ATA_CMD_STANDBYNOW1) && - test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; @@ -1302,7 +1300,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, dev_err(&port->dd->pdev->dev, "Internal command did not complete [atomic]\n"); rv = -EAGAIN; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) { hba_reset_nosleep(port->dd); rv = -ENXIO; @@ -1316,7 +1314,7 @@ exec_ic_exit: /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); - clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); return rv; @@ -1366,7 +1364,7 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) int rv = 0; struct host_to_dev_fis fis; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) return -EFAULT; /* Build the FIS. */ @@ -2398,10 +2396,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, * To prevent this command from being issued * if an internal command is in progress or error handling is active. */ - if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) || - test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) { + if (unlikely(test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) || + test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags))) { set_bit(tag, port->cmds_to_issue); - set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); + set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); return; } @@ -2447,7 +2445,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, down(&dd->port->cmd_slot); *tag = get_slot(dd->port); - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { up(&dd->port->cmd_slot); return NULL; } @@ -2521,9 +2519,9 @@ static ssize_t mtip_hw_show_status(struct device *dev, struct driver_data *dd = dev_to_disk(dev)->private_data; int size = 0; - if (test_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag)) + if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag)) + else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) size += sprintf(buf, "%s", "write_protect\n"); else size += sprintf(buf, "%s", "online\n"); @@ -2670,7 +2668,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); do { - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) return -EFAULT; if (mtip_check_surprise_removal(dd->pdev)) @@ -2728,17 +2726,17 @@ static int mtip_service_thread(void *data) * is in progress nor error handling is active */ wait_event_interruptible(port->svc_wait, (port->flags) && - !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && - !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags)); + !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && + !test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)); if (kthread_should_stop()) break; - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) break; - set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { + set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); + if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; /* used to restrict the loop to one iteration */ slot_start = num_cmd_slots; @@ -2766,16 +2764,16 @@ static int mtip_service_thread(void *data) clear_bit(slot, port->cmds_to_issue); } - clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); - } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) { + clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); + } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { if (!mtip_ftl_rebuild_poll(dd)) - set_bit(MTIP_DD_FLAG_REBUILD_FAILED_BIT, + set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag); - clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags); + clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); } - clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags)) + if (test_bit(MTIP_PF_SVC_THD_SHOULD_STOP_BIT, &port->flags)) break; } return 0; @@ -2930,7 +2928,7 @@ static int mtip_hw_init(struct driver_data *dd) rv = -ENODEV; goto out2 ; } - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { timetaken = jiffies - timetaken; dev_warn(&dd->pdev->dev, "Removal detected at %u ms\n", @@ -2983,7 +2981,7 @@ static int mtip_hw_init(struct driver_data *dd) jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { rv = -EFAULT; goto out3; } @@ -2995,7 +2993,7 @@ static int mtip_hw_init(struct driver_data *dd) if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == MTIP_FTL_REBUILD_MAGIC) { - set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags); + set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); return MTIP_FTL_REBUILD_MAGIC; } mtip_dump_identify(dd->port); @@ -3013,12 +3011,12 @@ static int mtip_hw_init(struct driver_data *dd) if (buf[259] & 0x1) { dev_info(&dd->pdev->dev, "Write protect bit is set.\n"); - set_bit(MTIP_DD_FLAG_WRITE_PROTECT_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); } if (buf[288] == 0xF7) { dev_info(&dd->pdev->dev, "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DD_FLAG_OVER_TEMP_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); } if (buf[288] == 0xBF) { dev_info(&dd->pdev->dev, @@ -3077,9 +3075,9 @@ static int mtip_hw_exit(struct driver_data *dd) * Send standby immediate (E0h) to the drive so that it * saves its state. */ - if (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { + if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { - if (!test_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags)) + if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) if (mtip_standby_immediate(dd->port)) dev_warn(&dd->pdev->dev, "STANDBY IMMEDIATE failed\n"); @@ -3260,7 +3258,7 @@ static int mtip_block_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) return -ENOTTY; switch (cmd) { @@ -3298,7 +3296,7 @@ static int mtip_block_compat_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) return -ENOTTY; switch (cmd) { @@ -3423,7 +3421,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) int nents = 0; int tag = 0; - if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { bio_endio(bio, -ENXIO); return; } @@ -3590,7 +3588,7 @@ skip_create_disk: } if (dd->mtip_svc_handler) { - set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); return rv; /* service thread created for handling rebuild */ } @@ -3650,13 +3648,13 @@ static int mtip_block_remove(struct driver_data *dd) struct kobject *kobj; if (dd->mtip_svc_handler) { - set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); + set_bit(MTIP_PF_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); wake_up_interruptible(&dd->port->svc_wait); kthread_stop(dd->mtip_svc_handler); } /* Clean up the sysfs attributes, if created */ - if (test_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag)) { + if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) { kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); if (kobj) { mtip_hw_sysfs_exit(dd, kobj); @@ -3812,7 +3810,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, */ instance++; if (rv != MTIP_FTL_REBUILD_MAGIC) - set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); goto done; block_initialize_err: @@ -3841,10 +3839,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; - set_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); if (mtip_check_surprise_removal(pdev)) { - while (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { + while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { counter++; msleep(20); if (counter == 10) { @@ -3882,7 +3880,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) return -EFAULT; } - set_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); /* Disable ports & interrupts then send standby immediate */ rv = mtip_block_suspend(dd); @@ -3948,7 +3946,7 @@ static int mtip_pci_resume(struct pci_dev *pdev) dev_err(&pdev->dev, "Unable to resume\n"); err: - clear_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); + clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); return rv; } diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index ea5c7e7cb50d..5ad2d79f7c4b 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -114,22 +114,22 @@ #define __force_bit2int (unsigned int __force) /* below are bit numbers in 'flags' defined in mtip_port */ -#define MTIP_FLAG_IC_ACTIVE_BIT 0 -#define MTIP_FLAG_EH_ACTIVE_BIT 1 -#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 -#define MTIP_FLAG_ISSUE_CMDS_BIT 4 -#define MTIP_FLAG_REBUILD_BIT 5 -#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 +#define MTIP_PF_IC_ACTIVE_BIT 0 +#define MTIP_PF_EH_ACTIVE_BIT 1 +#define MTIP_PF_SVC_THD_ACTIVE_BIT 2 +#define MTIP_PF_ISSUE_CMDS_BIT 4 +#define MTIP_PF_REBUILD_BIT 5 +#define MTIP_PF_SVC_THD_SHOULD_STOP_BIT 8 /* below are bit numbers in 'dd_flag' defined in driver_data */ -#define MTIP_DD_FLAG_REMOVE_PENDING_BIT 1 -#define MTIP_DD_FLAG_RESUME_BIT 2 -#define MTIP_DD_FLAG_CLEANUP_BIT 3 -#define MTIP_DD_FLAG_INIT_DONE_BIT 4 +#define MTIP_DDF_REMOVE_PENDING_BIT 1 +#define MTIP_DDF_RESUME_BIT 2 +#define MTIP_DDF_CLEANUP_BIT 3 +#define MTIP_DDF_INIT_DONE_BIT 4 -#define MTIP_DD_FLAG_WRITE_PROTECT_BIT 5 -#define MTIP_DD_FLAG_OVER_TEMP_BIT 6 -#define MTIP_DD_FLAG_REBUILD_FAILED_BIT 7 +#define MTIP_DDF_WRITE_PROTECT_BIT 5 +#define MTIP_DDF_OVER_TEMP_BIT 6 +#define MTIP_DDF_REBUILD_FAILED_BIT 7 __packed struct smart_attr{ u8 attr_id; From c74b0f586fa3cbc92ca451836fd75ae7a3fa85ac Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:39 +0200 Subject: [PATCH 057/438] mtip32xx: fix handling of commands in various scenarios * If a ncq command time out and a non-ncq command is active, skip restart port * Queue(pause) ncq commands during operations spanning more than one non-ncq commands - secure erase, download microcode * When a non-ncq command is active, allow incoming non-ncq commands to wait instead of failing back * Changed timeout for download microcode and smart commands * If the device in write protect mode, fail all writes (do not send to device) * Set maximum retries to 2 Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 144 ++++++++++++++++++++++-------- drivers/block/mtip32xx/mtip32xx.h | 39 +++++--- 2 files changed, 132 insertions(+), 51 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index e57864a7912e..47404ef5749f 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -436,7 +436,8 @@ static void mtip_init_port(struct mtip_port *port) writel(0xFFFFFFFF, port->completed[i]); /* Clear any pending interrupts for this port */ - writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); + writel(readl(port->dd->mmio + PORT_IRQ_STAT), + port->dd->mmio + PORT_IRQ_STAT); /* Clear any pending interrupts on the HBA. */ writel(readl(port->dd->mmio + HOST_IRQ_STAT), @@ -541,6 +542,7 @@ static void mtip_timeout_function(unsigned long int data) int tag, cmdto_cnt = 0; unsigned int bit, group; unsigned int num_command_slots = port->dd->slot_groups * 32; + unsigned long to; if (unlikely(!port)) return; @@ -605,7 +607,7 @@ static void mtip_timeout_function(unsigned long int data) } } - if (cmdto_cnt) { + if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { dev_warn(&port->dd->pdev->dev, "%d commands timed out: restarting port", cmdto_cnt); @@ -614,6 +616,21 @@ static void mtip_timeout_function(unsigned long int data) wake_up_interruptible(&port->svc_wait); } + if (port->ic_pause_timer) { + to = port->ic_pause_timer + msecs_to_jiffies(1000); + if (time_after(jiffies, to)) { + if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { + port->ic_pause_timer = 0; + clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); + } + + + } + } + /* Restart the timer */ mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); @@ -1105,6 +1122,39 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); } +static bool mtip_pause_ncq(struct mtip_port *port, + struct host_to_dev_fis *fis) +{ + struct host_to_dev_fis *reply; + unsigned long task_file_data; + + reply = port->rxfis + RX_FIS_D2H_REG; + task_file_data = readl(port->mmio+PORT_TFDATA); + + if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT)) + return false; + + if (fis->command == ATA_CMD_SEC_ERASE_PREP) { + set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); + port->ic_pause_timer = jiffies; + return true; + } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && + (fis->features == 0x03)) { + set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + port->ic_pause_timer = jiffies; + return true; + } else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) || + ((fis->command == 0xFC) && + (fis->features == 0x27 || fis->features == 0x72 || + fis->features == 0x62 || fis->features == 0x26))) { + /* Com reset after secure erase or lowlevel format */ + mtip_restart_port(port); + return false; + } + + return false; +} + /* * Wait for port to quiesce * @@ -1176,8 +1226,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, { struct mtip_cmd_sg *command_sg; DECLARE_COMPLETION_ONSTACK(wait); - int rv = 0; + int rv = 0, ready2go = 1; struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; + unsigned long to; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { @@ -1186,13 +1237,26 @@ static int mtip_exec_internal_command(struct mtip_port *port, return -EFAULT; } - /* Only one internal command should be running at a time */ - if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) { + to = jiffies + msecs_to_jiffies(timeout); + do { + ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL, + port->allocated); + if (ready2go) + break; + mdelay(100); + } while (time_before(jiffies, to)); + if (!ready2go) { dev_warn(&port->dd->pdev->dev, - "Internal command already active\n"); + "Internal cmd active. new cmd [%02X]\n", fis->command); return -EBUSY; } set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); + port->ic_pause_timer = 0; + + if (fis->command == ATA_CMD_SEC_ERASE_UNIT) + clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); + else if (fis->command == ATA_CMD_DOWNLOAD_MICRO) + clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { if (fis->command != ATA_CMD_STANDBYNOW1) { @@ -1314,6 +1378,10 @@ exec_ic_exit: /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); + if (rv >= 0 && mtip_pause_ncq(port, fis)) { + /* NCQ paused */ + return rv; + } clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); @@ -1767,8 +1835,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) fis.cyl_hi = command[5]; fis.device = command[6] & ~0x10; /* Clear the dev bit*/ - - dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", + dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", __func__, command[0], command[1], @@ -1795,7 +1862,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) command[4] = reply->cyl_low; command[5] = reply->cyl_hi; - dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", + dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", __func__, command[0], command[1], @@ -1838,7 +1905,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, } dbg_printk(MTIP_DRV_NAME - "%s: User Command: cmd %x, sect %x, " + " %s: User Command: cmd %x, sect %x, " "feat %x, sectcnt %x\n", __func__, command[0], @@ -1867,7 +1934,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, command[2] = command[3]; dbg_printk(MTIP_DRV_NAME - "%s: Completion Status: stat %x, " + " %s: Completion Status: stat %x, " "err %x, cmd %x\n", __func__, command[0], @@ -2070,9 +2137,10 @@ static int exec_drive_taskfile(struct driver_data *dd, } dbg_printk(MTIP_DRV_NAME - "taskfile: cmd %x, feat %x, nsect %x," + " %s: cmd %x, feat %x, nsect %x," " sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x," " head/dev %x\n", + __func__, fis.command, fis.features, fis.sect_count, @@ -2083,8 +2151,8 @@ static int exec_drive_taskfile(struct driver_data *dd, switch (fis.command) { case ATA_CMD_DOWNLOAD_MICRO: - /* Change timeout for Download Microcode to 60 seconds.*/ - timeout = 60000; + /* Change timeout for Download Microcode to 2 minutes */ + timeout = 120000; break; case ATA_CMD_SEC_ERASE_UNIT: /* Change timeout for Security Erase Unit to 4 minutes.*/ @@ -2100,8 +2168,8 @@ static int exec_drive_taskfile(struct driver_data *dd, timeout = 10000; break; case ATA_CMD_SMART: - /* Change timeout for vendor unique command to 10 secs */ - timeout = 10000; + /* Change timeout for vendor unique command to 15 secs */ + timeout = 15000; break; default: timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; @@ -2163,18 +2231,8 @@ static int exec_drive_taskfile(struct driver_data *dd, req_task->hob_ports[1] = reply->features_ex; req_task->hob_ports[2] = reply->sect_cnt_ex; } - - /* Com rest after secure erase or lowlevel format */ - if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) || - ((fis.command == 0xFC) && - (fis.features == 0x27 || fis.features == 0x72 || - fis.features == 0x62 || fis.features == 0x26))) && - !(reply->command & 1)) { - mtip_restart_port(dd->port); - } - dbg_printk(MTIP_DRV_NAME - "%s: Completion: stat %x," + " %s: Completion: stat %x," "err %x, sect_cnt %x, lbalo %x," "lbamid %x, lbahi %x, dev %x\n", __func__, @@ -2396,8 +2454,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, * To prevent this command from being issued * if an internal command is in progress or error handling is active. */ - if (unlikely(test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) || - test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags))) { + if (port->flags & MTIP_PF_PAUSE_IO) { set_bit(tag, port->cmds_to_issue); set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); return; @@ -2726,8 +2783,7 @@ static int mtip_service_thread(void *data) * is in progress nor error handling is active */ wait_event_interruptible(port->svc_wait, (port->flags) && - !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && - !test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)); + !(port->flags & MTIP_PF_PAUSE_IO)); if (kthread_should_stop()) break; @@ -2735,6 +2791,7 @@ static int mtip_service_thread(void *data) if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) break; + set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; @@ -2773,7 +2830,7 @@ static int mtip_service_thread(void *data) } clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_SVC_THD_SHOULD_STOP_BIT, &port->flags)) + if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) break; } return 0; @@ -3421,9 +3478,22 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) int nents = 0; int tag = 0; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { - bio_endio(bio, -ENXIO); - return; + if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { + if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, + &dd->dd_flag))) { + bio_endio(bio, -ENXIO); + return; + } + if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) { + bio_endio(bio, -ENODATA); + return; + } + if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT, + &dd->dd_flag) && + bio_data_dir(bio))) { + bio_endio(bio, -ENODATA); + return; + } } if (unlikely(!bio_has_data(bio))) { @@ -3599,7 +3669,7 @@ start_service_thread: dd, thd_name); if (IS_ERR(dd->mtip_svc_handler)) { - printk(KERN_ERR "mtip32xx: service thread failed to start\n"); + dev_err(&dd->pdev->dev, "service thread failed to start\n"); dd->mtip_svc_handler = NULL; rv = -EFAULT; goto kthread_run_error; @@ -3648,7 +3718,7 @@ static int mtip_block_remove(struct driver_data *dd) struct kobject *kobj; if (dd->mtip_svc_handler) { - set_bit(MTIP_PF_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); + set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); wake_up_interruptible(&dd->port->svc_wait); kthread_stop(dd->mtip_svc_handler); } diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 5ad2d79f7c4b..4ef58336310a 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -34,8 +34,8 @@ /* offset of Device Control register in PCIe extended capabilites space */ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 -/* # of times to retry timed out IOs */ -#define MTIP_MAX_RETRIES 5 +/* # of times to retry timed out/failed IOs */ +#define MTIP_MAX_RETRIES 2 /* Various timeout values in ms */ #define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 @@ -114,22 +114,32 @@ #define __force_bit2int (unsigned int __force) /* below are bit numbers in 'flags' defined in mtip_port */ -#define MTIP_PF_IC_ACTIVE_BIT 0 -#define MTIP_PF_EH_ACTIVE_BIT 1 -#define MTIP_PF_SVC_THD_ACTIVE_BIT 2 -#define MTIP_PF_ISSUE_CMDS_BIT 4 -#define MTIP_PF_REBUILD_BIT 5 -#define MTIP_PF_SVC_THD_SHOULD_STOP_BIT 8 +#define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */ +#define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */ +#define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */ +#define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */ +#define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ + (1 << MTIP_PF_EH_ACTIVE_BIT) | \ + (1 << MTIP_PF_SE_ACTIVE_BIT) | \ + (1 << MTIP_PF_DM_ACTIVE_BIT)) + +#define MTIP_PF_SVC_THD_ACTIVE_BIT 4 +#define MTIP_PF_ISSUE_CMDS_BIT 5 +#define MTIP_PF_REBUILD_BIT 6 +#define MTIP_PF_SVC_THD_STOP_BIT 8 /* below are bit numbers in 'dd_flag' defined in driver_data */ #define MTIP_DDF_REMOVE_PENDING_BIT 1 -#define MTIP_DDF_RESUME_BIT 2 -#define MTIP_DDF_CLEANUP_BIT 3 -#define MTIP_DDF_INIT_DONE_BIT 4 +#define MTIP_DDF_OVER_TEMP_BIT 2 +#define MTIP_DDF_WRITE_PROTECT_BIT 3 +#define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ + (1 << MTIP_DDF_OVER_TEMP_BIT) | \ + (1 << MTIP_DDF_WRITE_PROTECT_BIT)) -#define MTIP_DDF_WRITE_PROTECT_BIT 5 -#define MTIP_DDF_OVER_TEMP_BIT 6 -#define MTIP_DDF_REBUILD_FAILED_BIT 7 +#define MTIP_DDF_CLEANUP_BIT 5 +#define MTIP_DDF_RESUME_BIT 6 +#define MTIP_DDF_INIT_DONE_BIT 7 +#define MTIP_DDF_REBUILD_FAILED_BIT 8 __packed struct smart_attr{ u8 attr_id; @@ -393,6 +403,7 @@ struct mtip_port { * Timer used to complete commands that have been active for too long. */ struct timer_list cmd_timer; + unsigned long ic_pause_timer; /* * Semaphore used to block threads if there are no * command slots available. From 95fea2f1d90626498e2495a81fe5aab7fba9fb3f Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 9 Apr 2012 08:35:39 +0200 Subject: [PATCH 058/438] mtip32xx: dump tagmap on failure Dump tagmap on failure, instead of individual tags. Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 62 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 47404ef5749f..00f9fc992090 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -525,6 +525,25 @@ static void mtip_restart_port(struct mtip_port *port) } +/* + * Helper function for tag logging + */ +static void print_tags(struct driver_data *dd, + char *msg, + unsigned long *tagbits, + int cnt) +{ + unsigned char tagmap[128]; + int group, tagmap_len = 0; + + memset(tagmap, 0, sizeof(tagmap)); + for (group = SLOTBITS_IN_LONGS; group > 0; group--) + tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ", + tagbits[group-1]); + dev_warn(&dd->pdev->dev, + "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap); +} + /* * Called periodically to see if any read/write commands are * taking too long to complete. @@ -542,7 +561,7 @@ static void mtip_timeout_function(unsigned long int data) int tag, cmdto_cnt = 0; unsigned int bit, group; unsigned int num_command_slots = port->dd->slot_groups * 32; - unsigned long to; + unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; if (unlikely(!port)) return; @@ -552,6 +571,8 @@ static void mtip_timeout_function(unsigned long int data) jiffies + msecs_to_jiffies(30000)); return; } + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); for (tag = 0; tag < num_command_slots; tag++) { /* @@ -569,9 +590,7 @@ static void mtip_timeout_function(unsigned long int data) command = &port->commands[tag]; fis = (struct host_to_dev_fis *) command->command; - dev_warn(&port->dd->pdev->dev, - "Timeout for command tag %d\n", tag); - + set_bit(tag, tagaccum); cmdto_cnt++; if (cmdto_cnt == 1) set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); @@ -608,9 +627,8 @@ static void mtip_timeout_function(unsigned long int data) } if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - dev_warn(&port->dd->pdev->dev, - "%d commands timed out: restarting port", - cmdto_cnt); + print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); + mtip_restart_port(port); clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); @@ -733,23 +751,6 @@ static void mtip_null_completion(struct mtip_port *port, return; } -/* - * Helper function for tag logging - */ -static void print_tags(struct driver_data *dd, - char *msg, - unsigned long *tagbits) -{ - unsigned int tag, count = 0; - - for (tag = 0; tag < (dd->slot_groups) * 32; tag++) { - if (test_bit(tag, tagbits)) - count++; - } - if (count) - dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count); -} - static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, dma_addr_t buffer_dma, unsigned int sectors); static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, @@ -770,6 +771,7 @@ static void mtip_handle_tfe(struct driver_data *dd) u32 completed; struct host_to_dev_fis *fis; unsigned long tagaccum[SLOTBITS_IN_LONGS]; + unsigned int cmd_cnt = 0; unsigned char *buf; char *fail_reason = NULL; int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0; @@ -781,6 +783,9 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Stop the timer to prevent command timeouts. */ del_timer(&port->cmd_timer); + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + /* Set eh_active */ set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); @@ -791,9 +796,6 @@ static void mtip_handle_tfe(struct driver_data *dd) /* clear completed status register in the hardware.*/ writel(completed, port->completed[group]); - /* clear the tag accumulator */ - memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); - /* Process successfully completed commands */ for (bit = 0; bit < 32 && completed; bit++) { if (!(completed & (1<commands[tag]; if (likely(cmd->comp_func)) { set_bit(tag, tagaccum); + cmd_cnt++; atomic_set(&cmd->active, 0); cmd->comp_func(port, tag, @@ -824,7 +827,8 @@ static void mtip_handle_tfe(struct driver_data *dd) } } } - print_tags(dd, "TFE tags completed:", tagaccum); + + print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt); /* Restart the port */ mdelay(20); @@ -934,7 +938,7 @@ static void mtip_handle_tfe(struct driver_data *dd) tag); } } - print_tags(dd, "TFE tags reissued:", tagaccum); + print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); /* clear eh_active */ clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); From 511d63cb19329235bc9298b64010ec494b5e1408 Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Fri, 30 Mar 2012 17:49:53 +0300 Subject: [PATCH 059/438] crypto: talitos - properly lock access to global talitos registers Access to global talitos registers must be protected for the case when affinities are configured such that primary and secondary talitos irqs run on different cpus. Signed-off-by: Horia Geanta Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc641c796526..921039e56f87 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -124,6 +124,9 @@ struct talitos_private { void __iomem *reg; int irq[2]; + /* SEC global registers lock */ + spinlock_t reg_lock ____cacheline_aligned; + /* SEC version geometry (from device tree node) */ unsigned int num_channels; unsigned int chfifo_len; @@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data) \ { \ struct device *dev = (struct device *)data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ + unsigned long flags; \ \ if (ch_done_mask & 1) \ flush_channel(dev, 0, 0, 0); \ @@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data) \ out: \ /* At this point, all completed channels have been processed */ \ /* Unmask done interrupts for channels completed later on. */ \ + spin_lock_irqsave(&priv->reg_lock, flags); \ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ } DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ struct device *dev = data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ u32 isr, isr_lo; \ + unsigned long flags; \ \ + spin_lock_irqsave(&priv->reg_lock, flags); \ isr = in_be32(priv->reg + TALITOS_ISR); \ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ /* Acknowledge interrupt */ \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ \ - if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ - talitos_error(dev, isr, isr_lo); \ - else \ + if (unlikely(isr & ch_err_mask || isr_lo)) { \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ + talitos_error(dev, isr & ch_err_mask, isr_lo); \ + } \ + else { \ if (likely(isr & ch_done_mask)) { \ /* mask further done interrupts. */ \ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ /* done_task will unmask done interrupts at exit */ \ tasklet_schedule(&priv->done_task[tlet]); \ } \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ + } \ \ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ IRQ_NONE; \ @@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev) priv->ofdev = ofdev; + spin_lock_init(&priv->reg_lock); + err = talitos_probe_irq(ofdev); if (err) goto err_out; From b78f29ca0516266431688c5eb42d39ce42ec039a Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Sun, 1 Apr 2012 08:54:02 +0800 Subject: [PATCH 060/438] video:uvesafb: Fix oops that uvesafb try to execute NX-protected page This patch fix the oops below that catched in my machine [ 81.560602] uvesafb: NVIDIA Corporation, GT216 Board - 0696a290, Chip Rev , OEM: NVIDIA, VBE v3.0 [ 81.609384] uvesafb: protected mode interface info at c000:d350 [ 81.609388] uvesafb: pmi: set display start = c00cd3b3, set palette = c00cd40e [ 81.609390] uvesafb: pmi: ports = 3b4 3b5 3ba 3c0 3c1 3c4 3c5 3c6 3c7 3c8 3c9 3cc 3ce 3cf 3d0 3d1 3d2 3d3 3d4 3d5 3da [ 81.614558] uvesafb: VBIOS/hardware doesn't support DDC transfers [ 81.614562] uvesafb: no monitor limits have been set, default refresh rate will be used [ 81.614994] uvesafb: scrolling: ypan using protected mode interface, yres_virtual=4915 [ 81.744147] kernel tried to execute NX-protected page - exploit attempt? (uid: 0) [ 81.744153] BUG: unable to handle kernel paging request at c00cd3b3 [ 81.744159] IP: [] 0xc00cd3b2 [ 81.744167] *pdpt = 00000000016d6001 *pde = 0000000001c7b067 *pte = 80000000000cd163 [ 81.744171] Oops: 0011 [#1] SMP [ 81.744174] Modules linked in: uvesafb(+) cfbcopyarea cfbimgblt cfbfillrect [ 81.744178] [ 81.744181] Pid: 3497, comm: modprobe Not tainted 3.3.0-rc4NX+ #71 Acer Aspire 4741 /Aspire 4741 [ 81.744185] EIP: 0060:[] EFLAGS: 00010246 CPU: 0 [ 81.744187] EIP is at 0xc00cd3b3 [ 81.744189] EAX: 00004f07 EBX: 00000000 ECX: 00000000 EDX: 00000000 [ 81.744191] ESI: f763f000 EDI: f763f6e8 EBP: f57f3a0c ESP: f57f3a00 [ 81.744192] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 81.744195] Process modprobe (pid: 3497, ti=f57f2000 task=f748c600 task.ti=f57f2000) [ 81.744196] Stack: [ 81.744197] f82512c5 f759341c 00000000 f57f3a30 c124a9bc 00000001 00000001 000001e0 [ 81.744202] f8251280 f763f000 f7593400 00000000 f57f3a40 c12598dd f5c0c000 00000000 [ 81.744206] f57f3b10 c1255efe c125a21a 00000006 f763f09c 00000000 c1c6cb60 f7593400 [ 81.744210] Call Trace: [ 81.744215] [] ? uvesafb_pan_display+0x45/0x60 [uvesafb] [ 81.744222] [] fb_pan_display+0x10c/0x160 [ 81.744226] [] ? uvesafb_vbe_find_mode+0x180/0x180 [uvesafb] [ 81.744230] [] bit_update_start+0x1d/0x50 [ 81.744232] [] fbcon_switch+0x39e/0x550 [ 81.744235] [] ? bit_cursor+0x4ea/0x560 [ 81.744240] [] redraw_screen+0x12b/0x220 [ 81.744245] [] ? tty_do_resize+0x3b/0xc0 [ 81.744247] [] vc_do_resize+0x3d2/0x3e0 [ 81.744250] [] vc_resize+0x14/0x20 [ 81.744253] [] fbcon_init+0x29d/0x500 [ 81.744255] [] ? set_inverse_trans_unicode+0xe4/0x110 [ 81.744258] [] visual_init+0xb8/0x150 [ 81.744261] [] bind_con_driver+0x16c/0x360 [ 81.744264] [] ? register_con_driver+0x6e/0x190 [ 81.744267] [] take_over_console+0x41/0x50 [ 81.744269] [] fbcon_takeover+0x6a/0xd0 [ 81.744272] [] fbcon_event_notify+0x758/0x790 [ 81.744277] [] notifier_call_chain+0x42/0xb0 [ 81.744280] [] __blocking_notifier_call_chain+0x60/0x90 [ 81.744283] [] blocking_notifier_call_chain+0x1a/0x20 [ 81.744285] [] fb_notifier_call_chain+0x11/0x20 [ 81.744288] [] register_framebuffer+0x1d9/0x2b0 [ 81.744293] [] ? ioremap_wc+0x33/0x40 [ 81.744298] [] uvesafb_probe+0xaba/0xc40 [uvesafb] [ 81.744302] [] platform_drv_probe+0xf/0x20 [ 81.744306] [] driver_probe_device+0x68/0x170 [ 81.744309] [] __device_attach+0x41/0x50 [ 81.744313] [] bus_for_each_drv+0x48/0x70 [ 81.744316] [] device_attach+0x83/0xa0 [ 81.744319] [] ? __driver_attach+0x90/0x90 [ 81.744321] [] bus_probe_device+0x6f/0x90 [ 81.744324] [] device_add+0x5e5/0x680 [ 81.744329] [] ? kvasprintf+0x43/0x60 [ 81.744332] [] ? kobject_set_name_vargs+0x64/0x70 [ 81.744335] [] ? kobject_set_name_vargs+0x64/0x70 [ 81.744339] [] platform_device_add+0xff/0x1b0 [ 81.744343] [] uvesafb_init+0x50/0x9b [uvesafb] [ 81.744346] [] do_one_initcall+0x2f/0x170 [ 81.744350] [] ? uvesafb_is_valid_mode+0x66/0x66 [uvesafb] [ 81.744355] [] sys_init_module+0xf4/0x1410 [ 81.744359] [] ? vfsmount_lock_local_unlock_cpu+0x30/0x30 [ 81.744363] [] sysenter_do_call+0x12/0x36 [ 81.744365] Code: f5 00 00 00 32 f6 66 8b da 66 d1 e3 66 ba d4 03 8a e3 b0 1c 66 ef b0 1e 66 ef 8a e7 b0 1d 66 ef b0 1f 66 ef e8 fa 00 00 00 61 c3 <60> e8 c8 00 00 00 66 8b f3 66 8b da 66 ba d4 03 b0 0c 8a e5 66 [ 81.744388] EIP: [] 0xc00cd3b3 SS:ESP 0068:f57f3a00 [ 81.744391] CR2: 00000000c00cd3b3 [ 81.744393] ---[ end trace 18b2c87c925b54d6 ]--- Signed-off-by: Wang YanQing Cc: Michal Januszewski Cc: Alan Cox Signed-off-by: Florian Tobias Schandinat Cc: stable@vger.kernel.org --- drivers/video/uvesafb.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 260cca7ddb41..26e83d7fdd6f 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -815,8 +815,15 @@ static int __devinit uvesafb_vbe_init(struct fb_info *info) par->pmi_setpal = pmi_setpal; par->ypan = ypan; - if (par->pmi_setpal || par->ypan) - uvesafb_vbe_getpmi(task, par); + if (par->pmi_setpal || par->ypan) { + if (__supported_pte_mask & _PAGE_NX) { + par->pmi_setpal = par->ypan = 0; + printk(KERN_WARNING "uvesafb: NX protection is actively." + "We have better not to use the PMI.\n"); + } else { + uvesafb_vbe_getpmi(task, par); + } + } #else /* The protected mode interface is not available on non-x86. */ par->pmi_setpal = par->ypan = 0; From 388bc26226807fbcf4c626b81bb17a2e74aa4b1b Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Wed, 21 Mar 2012 17:22:22 +0530 Subject: [PATCH 061/438] omap-serial: Fix the error handling in the omap_serial probe The patch does the following - The pm_runtime_disable is called in the remove not in the error case of probe.The patch calls the pm_runtime_disable in the error case. - Calls pm_runtime_put in the error case. - The up is not freed in the error path. Fix the memory leak by using devm_* so that the memory need not be freed in the driver. - Also the iounmap is not called fix the same by calling using devm_ioremap. - Make the name of the error tags more meaningful. Cc: Mark Brown Cc: Govindraj.R Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 43 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 0121486ac4fa..d00b38eb268e 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1381,29 +1381,24 @@ static int serial_omap_probe(struct platform_device *pdev) return -ENODEV; } - if (!request_mem_region(mem->start, resource_size(mem), + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); - if (!dma_rx) { - ret = -EINVAL; - goto err; - } + if (!dma_rx) + return -ENXIO; dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); - if (!dma_tx) { - ret = -EINVAL; - goto err; - } + if (!dma_tx) + return -ENXIO; + + up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); + if (!up) + return -ENOMEM; - up = kzalloc(sizeof(*up), GFP_KERNEL); - if (up == NULL) { - ret = -ENOMEM; - goto do_release_region; - } up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; @@ -1423,16 +1418,17 @@ static int serial_omap_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; - goto err; + goto err_port_line; } sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; - up->port.membase = ioremap(mem->start, resource_size(mem)); + up->port.membase = devm_ioremap(&pdev->dev, mem->start, + resource_size(mem)); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; - goto err; + goto err_ioremap; } up->port.flags = omap_up_info->flags; @@ -1478,16 +1474,19 @@ static int serial_omap_probe(struct platform_device *pdev) ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) - goto do_release_region; + goto err_add_port; pm_runtime_put(&pdev->dev); platform_set_drvdata(pdev, up); return 0; -err: + +err_add_port: + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); +err_ioremap: +err_port_line: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); -do_release_region: - release_mem_region(mem->start, resource_size(mem)); return ret; } @@ -1499,8 +1498,6 @@ static int serial_omap_remove(struct platform_device *dev) pm_runtime_disable(&up->pdev->dev); uart_remove_one_port(&serial_omap_reg, &up->port); pm_qos_remove_request(&up->pm_qos_request); - - kfree(up); } platform_set_drvdata(dev, NULL); From ef37ea34cac19ef46173b26ee47a102f3b987d1e Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 25 Mar 2012 19:12:37 +0200 Subject: [PATCH 062/438] isdn/gigaset: use gig_dbg() for debugging output The "TTY buffer in tty_port" patchset introduced an opencoded debug message in the Gigaset tty device if_close() function. Change it to use the gig_dbg() macro like everywhere else in the driver. Signed-off-by: Tilman Schmidt Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/gigaset/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index b3d6ac17272d..a6d9fd2858f7 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -176,7 +176,7 @@ static void if_close(struct tty_struct *tty, struct file *filp) struct cardstate *cs = tty->driver_data; if (!cs) { /* happens if we didn't find cs in open */ - printk(KERN_DEBUG "%s: no cardstate\n", __func__); + gig_dbg(DEBUG_IF, "%s: no cardstate", __func__); return; } From acede70d6561f2d042d9dbb153d9a3469479c0ed Mon Sep 17 00:00:00 2001 From: Yuriy Kozlov Date: Thu, 29 Mar 2012 09:55:27 +0200 Subject: [PATCH 063/438] tty: serial: altera_uart: Check for NULL platform_data in probe. Follow altera_jtag_uart. This fixes a crash if there is a mistake in the DTS. Signed-off-by: Yuriy Kozlov Signed-off-by: Tobias Klauser Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index e7903751e058..1f0330915d5a 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -556,7 +556,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; - else if (platp->mapbase) + else if (platp) port->mapbase = platp->mapbase; else return -EINVAL; @@ -564,7 +564,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; - else if (platp->irq) + else if (platp) port->irq = platp->irq; /* Check platform data first so we can override device node data */ From 57c3686842114de3b0c00633591e9605c46fb769 Mon Sep 17 00:00:00 2001 From: "Siftar, Gabe" Date: Thu, 29 Mar 2012 15:40:05 +0200 Subject: [PATCH 064/438] tty/serial: atmel_serial: fix RS485 half-duplex problem On our custom board, we are using RS485 in half-duplex mode on an AT91SAM9G45. SER_RS485_RX_DURING_TX is not set as we do not want to receive the data we transmit (our transceiver will receive transmitted data). Although the current driver attempts to disable and enable the receiver at the appropriate points, incoming data is still loaded into the receive register causing our code to receive the very last byte that was sent once the receiver is enabled. I ran this by Atmel support and they wrote: "The issue comes from the fact that you disable the PDC/DMA Reception and not the USART Reception channel. In your case, the[n] you will still receive data into the USART_RHR register, and maybe you [h]ave the overrun flag set. So please disable the USART reception channel." The following patch should force the driver to enable/disable the receiver via RXEN/RXDIS fields of the USART control register. It fixed the issue I was having. Signed-off-by: Gabe Siftar [nicolas.ferre@atmel.com: slightly modify commit message] Signed-off-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index f9a6be7a9bed..3d7e1ee2fa57 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -389,6 +389,8 @@ static void atmel_start_rx(struct uart_port *port) { UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ + UART_PUT_CR(port, ATMEL_US_RXEN); + if (atmel_use_dma_rx(port)) { /* enable PDC controller */ UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | @@ -404,6 +406,8 @@ static void atmel_start_rx(struct uart_port *port) */ static void atmel_stop_rx(struct uart_port *port) { + UART_PUT_CR(port, ATMEL_US_RXDIS); + if (atmel_use_dma_rx(port)) { /* disable PDC receive */ UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); From 5da527aafed2834852fc4fe21daeaeadf7c61af3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 3 Apr 2012 03:18:23 +0200 Subject: [PATCH 065/438] printk(): add KERN_CONT where needed in hpet and vt code A prototype for kmsg records instead of a byte-stream buffer revealed a couple of missing printk(KERN_CONT ...) uses. Subsequent calls produce one record per printk() call, while all should have ended up in a single record. Instead of: ACPI: (supports S0 S5) ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11) hpet0: at MMIO 0xfed00000, IRQs 2 , 8 , 0 It prints: ACPI: (supports S0 S5 ) ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11 ) hpet0: at MMIO 0xfed00000, IRQs 2 , 8 , 0 Cc: Andrew Morton Cc: Len Brown Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/char/hpet.c | 4 ++-- drivers/tty/vt/vt.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 3845ab44c330..dfd7876f127c 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp) hpetp->hp_which, hdp->hd_phys_address, hpetp->hp_ntimer > 1 ? "s" : ""); for (i = 0; i < hpetp->hp_ntimer; i++) - printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); - printk("\n"); + printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); + printk(KERN_CONT "\n"); temp = hpetp->hp_tick_freq; remainder = do_div(temp, 1000000); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 3bdd4b19dd06..2156188db4a6 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2932,11 +2932,10 @@ static int __init con_init(void) gotoxy(vc, vc->vc_x, vc->vc_y); csi_J(vc, 0); update_screen(vc); - pr_info("Console: %s %s %dx%d", + pr_info("Console: %s %s %dx%d\n", vc->vc_can_do_color ? "colour" : "mono", display_desc, vc->vc_cols, vc->vc_rows); printable = 1; - printk("\n"); console_unlock(); From 7b246a1d0dfe75346a22bf6589b858a0389e6df1 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 3 Apr 2012 18:14:24 -0700 Subject: [PATCH 066/438] serial: samsung: fix omission initialize ulcon in reset port fn() Fix omission initialize ulcon in s3c24xx_serial_resetport(), reset port function in drivers/tty/serial/samsung.c. It has been happened from commit 0dfb3b41("serial: samsung: merge all SoC specific port reset functions") Signed-off-by: Kukjin Kim Cc: stable [3.3] Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index de249d265bec..d8b0aee35632 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -982,6 +982,7 @@ static void s3c24xx_serial_resetport(struct uart_port *port, ucon &= ucon_mask; wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); + wr_regl(port, S3C2410_ULCON, cfg->ulcon); /* reset both fifos */ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); From d8c4019b41aaf4d6401a4ceb3819b8e1afe21595 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 2 Apr 2012 16:32:17 -0600 Subject: [PATCH 067/438] tty/serial/omap: console can only be built-in When the omap serial driver is built as a module, we must not allow the console driver to be selected, because consoles can not be loadable modules. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Acked-by: Govindraj.R Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 665beb68f670..070b442c1f81 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1041,7 +1041,7 @@ config SERIAL_OMAP config SERIAL_OMAP_CONSOLE bool "Console on OMAP serial port" - depends on SERIAL_OMAP + depends on SERIAL_OMAP=y select SERIAL_CORE_CONSOLE help Select this option if you would like to use omap serial port as From 3579812373aba92b2f3b632bdf99329bc3c05d62 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2012 11:49:37 -0700 Subject: [PATCH 068/438] Revert "serial/8250_pci: init-quirk msi support for kt serial controller" This reverts commit e86ff4a63c9fdd875ba8492577cd1ad2252f525c. This tried to enforce the semantics of one interrupt per iir read of the THRE (transmit-hold empty) status, but events from other sources (particularly modem status) defeat this guarantee. This change also broke 8250_pci suspend/resume support as pciserial_resume_ports() re-runs .init() quirks, but does not run .exit() quirks in pciserial_suspend_ports() leading to reports like: sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:16.3/msi_irqs' ...and a subsequent crash. The mismatch of init/exit at suspend/resume seems like a bug in its own right. [stable: 3.3.x] Cc: stable Acked-by: Alan Cox Cc: Sudhakar Mamillapalli Reported-by: Nhan H Mai Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index da2b0b0a183f..1d4ccf8c8874 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1118,18 +1118,6 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } -static int try_enable_msi(struct pci_dev *dev) -{ - /* use msi if available, but fallback to legacy otherwise */ - pci_enable_msi(dev); - return 0; -} - -static void disable_msi(struct pci_dev *dev) -{ - pci_disable_msi(dev); -} - #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1249,9 +1237,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .init = try_enable_msi, .setup = kt_serial_setup, - .exit = disable_msi, }, /* * ITE From 49b532f96fda23663f8be35593d1c1372c0f91e0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2012 11:49:44 -0700 Subject: [PATCH 069/438] Revert "serial/8250_pci: setup-quirk workaround for the kt serial controller" This reverts commit 448ac154c957c4580531fa0c8f2045816fe2f0e7. The semantic of UPF_IIR_ONCE is only guaranteed to workaround the race condition in the kt serial's iir register if the only source of interrupts is THRE (fifo-empty) events. An modem status event at the wrong time can again cause an iir read to drop the 'empty' status leading to a hang. So, revert this in preparation for using the existing "I don't trust my iir register" workaround in the 8250 core (UART_BUG_THRE). [stable: 3.3.x] Cc: stable Acked-by: Alan Cox Cc: Sudhakar Mamillapalli Reported-by: Nhan H Mai Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.c | 4 +--- drivers/tty/serial/8250/8250_pci.c | 17 +---------------- include/linux/serial_core.h | 1 - 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 5b149b466ec8..56492d208a7a 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -1572,13 +1572,11 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) do { struct uart_8250_port *up; struct uart_port *port; - bool skip; up = list_entry(l, struct uart_8250_port, list); port = &up->port; - skip = pass_counter && up->port.flags & UPF_IIR_ONCE; - if (!skip && port->handle_irq(port)) { + if (port->handle_irq(port)) { handled = 1; end = NULL; } else if (end == NULL) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 1d4ccf8c8874..105dcfbd3d33 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1092,14 +1092,6 @@ static int skip_tx_en_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } -static int kt_serial_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_port *port, int idx) -{ - port->flags |= UPF_IIR_ONCE; - return skip_tx_en_setup(priv, board, port, idx); -} - static int pci_eg20t_init(struct pci_dev *dev) { #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) @@ -1118,6 +1110,7 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +/* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1147,7 +1140,6 @@ pci_xr17c154_setup(struct serial_private *priv, #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 -#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1232,13 +1224,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = ce4100_serial_setup, }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = kt_serial_setup, - }, /* * ITE */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f51bf2e70c69..882f1d61aa56 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -357,7 +357,6 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) -#define UPF_IIR_ONCE ((__force upf_t) (1 << 26)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) From bc02d15a3452fdf9276e8fb89c5e504a88df888a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2012 11:49:50 -0700 Subject: [PATCH 070/438] serial/8250_pci: add a "force background timer" flag and use it for the "kt" serial port Workaround dropped notifications in the iir register. Register reads coincident with new interrupt notifications sometimes result in this device clearing the interrupt event without reporting it in the read data. The serial core already has a heuristic for determining when a device has an untrustworthy iir register. In this case when we apriori know that the iir is faulty use a flag (UPF_BUG_THRE) to bypass the test and force usage of the background timer. [stable: 3.3.x] Acked-by: Alan Cox Cc: stable Reported-by: Nhan H Mai Reported-by: Sudhakar Mamillapalli Tested-by: Nhan H Mai Tested-by: Sudhakar Mamillapalli Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.c | 8 +++++--- drivers/tty/serial/8250/8250_pci.c | 17 ++++++++++++++++- include/linux/serial_core.h | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 56492d208a7a..5c27f7e6c9f1 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -2035,10 +2035,12 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); /* - * If the interrupt is not reasserted, setup a timer to - * kick the UART on a regular basis. + * If the interrupt is not reasserted, or we otherwise + * don't trust the iir, setup a timer to kick the UART + * on a regular basis. */ - if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { + if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || + up->port.flags & UPF_BUG_THRE) { up->bugs |= UART_BUG_THRE; pr_debug("ttyS%d - using backup timer\n", serial_index(port)); diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 105dcfbd3d33..858dca865d6a 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int kt_serial_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_port *port, int idx) +{ + port->flags |= UPF_BUG_THRE; + return skip_tx_en_setup(priv, board, port, idx); +} + static int pci_eg20t_init(struct pci_dev *dev) { #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) @@ -1110,7 +1118,6 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } -/* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1140,6 +1147,7 @@ pci_xr17c154_setup(struct serial_private *priv, #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 +#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1224,6 +1232,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = ce4100_serial_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = kt_serial_setup, + }, /* * ITE */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 882f1d61aa56..2db407a40051 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -357,6 +357,7 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) +#define UPF_BUG_THRE ((__force upf_t) (1 << 26)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) From 867c902e07d5677e2a5b54c0435e589513abde48 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Mon, 2 Apr 2012 14:36:22 +0900 Subject: [PATCH 071/438] pch_uart: Fix MSI setting issue The following patch (MSI setting) is not enough. commit e463595fd9c752fa4bf06b47df93ef9ade3c7cf0 Author: Alexander Stein Date: Mon Jul 4 08:58:31 2011 +0200 pch_uart: Add MSI support Signed-off-by: Alexander Stein Signed-off-by: Greg Kroah-Hartman To enable MSI mode, PCI bus-mastering must be enabled. This patch enables the setting. cc: Alexander Stein Signed-off-by: Tomoya MORINAGA Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index e825460478be..afa060fde110 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1655,6 +1655,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, } pci_enable_msi(pdev); + pci_set_master(pdev); iobase = pci_resource_start(pdev, 0); mapbase = pci_resource_start(pdev, 1); From 9a637e19213496b756662155ef26394e189b320a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Apr 2012 23:23:30 +0300 Subject: [PATCH 072/438] ARM: OMAP1: mux: add missing include Fix the following build breakage in v3.4-rc2 that happens with CONFIG_OMAP_MUX=y: arch/arm/mach-omap1/mux.c:89:1: error: 'FUNC_MUX_CTRL_9' undeclared here (not in a function) arch/arm/mach-omap1/mux.c:89:1: error: 'PULL_DWN_CTRL_2' undeclared here (not in a function) arch/arm/mach-omap1/mux.c:93:1: error: 'FUNC_MUX_CTRL_C' undeclared here (not in a function) Signed-off-by: Aaro Koskinen Acked-by: Jarkko Nikula [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/mux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 087dba0df47e..e9cc52d4cb28 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -27,6 +27,7 @@ #include #include +#include #include From 11bbd5b6dae49fd7072ebf5eb63735827bd72f42 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 23 Mar 2012 11:06:37 +0100 Subject: [PATCH 073/438] pch_uart: Add Kontron COMe-mTT10 uart clock quirk Add UART clock quirk for the Kontron COMe-mTT10 module. The board has previously been called nanoETXexpress-TT, therefore this is also checked. As suggested by Darren Hart the comparison in this patch version is placed after the FRI2 checks to ensure it will also work with possible upcoming changes to the FRI2 firmware. This patch follows the patchset submitted by Darren Hart at commit a46f5533ecfc7bbdd646d84fdab8656031a715c6. Signed-off-by: Michael Brunner Acked-by: Darren Hart Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index afa060fde110..8a18eb045300 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -210,6 +210,7 @@ enum { #define CMITC_UARTCLK 192000000 /* 192.0000 MHz */ #define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */ #define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */ +#define NTC1_UARTCLK 64000000 /* 64.0000 MHz */ struct pch_uart_buffer { unsigned char *buf; @@ -388,6 +389,12 @@ static int pch_uart_get_uartclk(void) if (cmp && strstr(cmp, "Fish River Island II")) return FRI2_48_UARTCLK; + /* Kontron COMe-mTT10 (nanoETXexpress-TT) */ + cmp = dmi_get_system_info(DMI_BOARD_NAME); + if (cmp && (strstr(cmp, "COMe-mTT") || + strstr(cmp, "nanoETXexpress-TT"))) + return NTC1_UARTCLK; + return DEFAULT_UARTCLK; } From 8528e07edfc6ac5a793509f305b9c3c4fb3672c0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 28 Mar 2012 08:35:26 -0700 Subject: [PATCH 074/438] hwmon: (smsc47b397) Fix compiler warning Some configurations produce the following compiler warning: drivers/hwmon/smsc47b397.c: In function 'smsc47b397_init': drivers/hwmon/smsc47b397.c:385: warning: 'address' may be used uninitialized in this function While this is a false positive, it can easily be fixed by overloading the return value from smsc47b397_find with both address and error return code (the address is an unsigned short and thus never negative). This also reduces module size by a few bytes (64 bytes for x86_64). Cc: Mark M. Hoffman Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson Acked-by: Jean Delvare --- drivers/hwmon/smsc47b397.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index d3b778da3f86..c5f6be478bad 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -343,10 +343,11 @@ exit: return err; } -static int __init smsc47b397_find(unsigned short *addr) +static int __init smsc47b397_find(void) { u8 id, rev; char *name; + unsigned short addr; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -370,14 +371,14 @@ static int __init smsc47b397_find(unsigned short *addr) rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); - *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) + addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", - name, *addr, rev); + name, addr, rev); superio_exit(); - return 0; + return addr; } static int __init smsc47b397_init(void) @@ -385,9 +386,10 @@ static int __init smsc47b397_init(void) unsigned short address; int ret; - ret = smsc47b397_find(&address); - if (ret) + ret = smsc47b397_find(); + if (ret < 0) return ret; + address = ret; ret = platform_driver_register(&smsc47b397_driver); if (ret) From 776cdc11b3b0fc21e34600e22abe1c8209d2f3f0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 28 Mar 2012 09:03:26 -0700 Subject: [PATCH 075/438] hwmon: (acpi_power_meter) Fix compiler warning seen in some configurations In some configurations, BUG() does not result in an endless loop but returns to the caller. This results in the following compiler warning: drivers/hwmon/acpi_power_meter.c: In function 'show_str': drivers/hwmon/acpi_power_meter.c:380: warning: 'val' may be used uninitialized in this function Fix the warning by setting val to an empty string after BUG(). Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson --- drivers/hwmon/acpi_power_meter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 145f13580ff0..9140236a0182 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -391,6 +391,7 @@ static ssize_t show_str(struct device *dev, break; default: BUG(); + val = ""; } return sprintf(buf, "%s\n", val); From 1d0045ee4a220872b65147b5b290e4a4852386d9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 28 Mar 2012 08:55:12 -0700 Subject: [PATCH 076/438] hwmon: (smsc47m1) Fix compiler warning Some configurations produce the following compiler warning: drivers/hwmon/smsc47m1.c: In function 'sm_smsc47m1_init': drivers/hwmon/smsc47m1.c:938: warning: 'address' may be used uninitialized in this function While this is a false positive, it can easily be fixed by overloading the return value from smsc47m1_find with both address and error return code (the address is an unsigned short and thus never negative). This also reduces module size by a few bytes (46 bytes for x86_64). Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson --- drivers/hwmon/smsc47m1.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index c590c1469793..b5aa38dd7ab9 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(unsigned short *addr, - struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) { u8 val; + unsigned short addr; superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -546,9 +546,9 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_select(); - *addr = (superio_inb(SUPERIO_REG_BASE) << 8) + addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - if (*addr == 0) { + if (addr == 0) { pr_info("Device address not set, will not use\n"); superio_exit(); return -ENODEV; @@ -565,7 +565,7 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_exit(); - return 0; + return addr; } /* Restore device to its initial state */ @@ -938,13 +938,15 @@ static int __init sm_smsc47m1_init(void) unsigned short address; struct smsc47m1_sio_data sio_data; - if (smsc47m1_find(&address, &sio_data)) - return -ENODEV; + err = smsc47m1_find(&sio_data); + if (err < 0) + return err; + address = err; /* Sets global pdev as a side effect */ err = smsc47m1_device_add(address, &sio_data); if (err) - goto exit; + return err; err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) @@ -955,7 +957,6 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); smsc47m1_restore(&sio_data); -exit: return err; } From d7ee11157f1fce02632e2f3a56b99b2afd9e5f93 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 28 Mar 2012 09:14:03 -0700 Subject: [PATCH 077/438] hwmon: (pmbus_core) Fix compiler warning Some configurations produce the following compiler warning: drivers/hwmon/pmbus/pmbus_core.c: In function 'pmbus_show_boolean': drivers/hwmon/pmbus/pmbus_core.c:752: warning: 'val' may be used uninitialized in this function While this is a false positive, it can easily be fixed by overloading the return value from pmbus_get_boolean with both val and error return code (val is a boolean and thus never negative). Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson --- drivers/hwmon/pmbus/pmbus_core.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index be51037363c8..29b319db573e 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data, * If a negative value is stored in any of the referenced registers, this value * reflects an error code which will be returned. */ -static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) +static int pmbus_get_boolean(struct pmbus_data *data, int index) { u8 s1 = (index >> 24) & 0xff; u8 s2 = (index >> 16) & 0xff; u8 reg = (index >> 8) & 0xff; u8 mask = index & 0xff; - int status; + int ret, status; u8 regval; status = data->status[reg]; @@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) regval = status & mask; if (!s1 && !s2) - *val = !!regval; + ret = !!regval; else { long v1, v2; struct pmbus_sensor *sensor1, *sensor2; @@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) v1 = pmbus_reg2data(data, sensor1); v2 = pmbus_reg2data(data, sensor2); - *val = !!(regval && v1 >= v2); + ret = !!(regval && v1 >= v2); } - return 0; + return ret; } static ssize_t pmbus_show_boolean(struct device *dev, @@ -750,11 +750,10 @@ static ssize_t pmbus_show_boolean(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct pmbus_data *data = pmbus_update_device(dev); int val; - int err; - err = pmbus_get_boolean(data, attr->index, &val); - if (err) - return err; + val = pmbus_get_boolean(data, attr->index); + if (val < 0) + return val; return snprintf(buf, PAGE_SIZE, "%d\n", val); } From 33cb4f345687a27e3fece0a7fcf78ac2e7b0a7d6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 20 Mar 2012 16:32:39 +0800 Subject: [PATCH 078/438] drivers/base: Remove unneeded spin_lock_init call for soc_lock soc_lock is already initialized by DEFINE_SPINLOCK. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/base/soc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 05f150382da8..f49346b9e961 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -168,8 +168,6 @@ void soc_device_unregister(struct soc_device *soc_dev) static int __init soc_bus_register(void) { - spin_lock_init(&soc_lock); - return bus_register(&soc_bus_type); } core_initcall(soc_bus_register); From 3a4ffe930a2d2dad07604fe74d21b878decc6461 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Sat, 17 Mar 2012 09:17:49 +0000 Subject: [PATCH 079/438] drivers/base: fix compiler warning in SoC export driver - idr should be ida MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes: note: expected ‘struct ida *’ but argument is of type ‘struct idr *’ warning: passing argument 1 of ‘ida_pre_get’ from incompatible pointer type Reported-by: Arnd Bergman Cc: Greg Kroah-Hartman Signed-off-by: Lee Jones Signed-off-by: Axel Lin Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/base/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/soc.c b/drivers/base/soc.c index f49346b9e961..ba29b2e73d48 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -15,7 +15,7 @@ #include #include -static DEFINE_IDR(soc_ida); +static DEFINE_IDA(soc_ida); static DEFINE_SPINLOCK(soc_lock); static ssize_t soc_info_get(struct device *dev, From 70fa4a62e913dde2d100e0be2711562742f58bee Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 4 Apr 2012 12:06:20 -0700 Subject: [PATCH 080/438] sysfs: Update the name hash for an entry after changing the namespace This is needed to allow renaming network devices that have been moved to another network namespace. Signed-off-by: Tom Goff Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 2a7a3f5d1ca6..8ddc1021c79a 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -878,7 +878,6 @@ int sysfs_rename(struct sysfs_dirent *sd, dup_name = sd->s_name; sd->s_name = new_name; - sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); } /* Move to the appropriate place in the appropriate directories rbtree. */ @@ -886,6 +885,7 @@ int sysfs_rename(struct sysfs_dirent *sd, sysfs_get(new_parent_sd); sysfs_put(sd->s_parent); sd->s_ns = new_ns; + sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); sd->s_parent = new_parent_sd; sysfs_link_sibling(sd); From ce5c9851855bab190c9a142761d54ba583ab094c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 23 Mar 2012 15:23:18 +0100 Subject: [PATCH 081/438] USB: pl2303: fix DTR/RTS being raised on baud rate change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DTR/RTS should only be raised when changing baudrate from B0 and not on any baud rate change (> B0). Reported-by: Søren Holm Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ff4a174fa5de..a1a9062954c4 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty, control = priv->line_control; if ((cflag & CBAUD) == B0) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else + else if ((old_termios->c_cflag & CBAUD) == B0) priv->line_control |= (CONTROL_DTR | CONTROL_RTS); if (control != priv->line_control) { control = priv->line_control; From 9ac2feb22b5b821d81463bef92698ef7682a3145 Mon Sep 17 00:00:00 2001 From: Santiago Garcia Mantinan Date: Mon, 19 Mar 2012 18:17:00 +0100 Subject: [PATCH 082/438] USB: option: re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to option_id array Re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to option_id array Signed-off-by: Santiago Garcia Mantinan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 836cfa9a515f..f4465ccddc35 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -708,6 +708,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, From 3a450850e2bb0f92cacb12da90fe98eccd105468 Mon Sep 17 00:00:00 2001 From: Aleksey Babahin Date: Tue, 20 Mar 2012 00:46:31 +0400 Subject: [PATCH 083/438] USB: serial: metro-usb: Fix idProduct for Uni-Directional mode. The right idProduct for Metrologic Bar Code Scanner in Uni-Directional Serial Emulation mode is 0x0700. Also rename idProduct for Bi-Directional mode to be a bit more informative. Signed-off-by: Aleksey Babahin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/metro-usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 6e1622f2a297..08d16e8c002d 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -27,8 +27,8 @@ /* Product information. */ #define FOCUS_VENDOR_ID 0x0C2E -#define FOCUS_PRODUCT_ID 0x0720 -#define FOCUS_PRODUCT_ID_UNI 0x0710 +#define FOCUS_PRODUCT_ID_BI 0x0720 +#define FOCUS_PRODUCT_ID_UNI 0x0700 #define METROUSB_SET_REQUEST_TYPE 0x40 #define METROUSB_SET_MODEM_CTRL_REQUEST 10 @@ -47,7 +47,7 @@ struct metrousb_private { /* Device table list. */ static struct usb_device_id id_table[] = { - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) }, + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, { }, /* Terminating entry. */ }; From 891a3b1fddb24b4b53426685bd0390bb74c9b5b3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 28 Mar 2012 16:10:49 -0400 Subject: [PATCH 084/438] USB: fix bug in serial driver unregistration This patch (as1536) fixes a bug in the USB serial core. Unloading and reloading a serial driver while a serial device is plugged in causes errors because of the code in usb_serial_disconnect() that tries to make sure the port_remove method is called. With the new order of driver registration introduced in the 3.4 kernel, this is definitely not the right thing to do (if indeed it ever was). The patch removes that whole section code, along with the mechanism for keeping track of each port's registration state, which is no longer needed. The driver core can handle all that stuff for us. Note: This has been tested only with one or two USB serial drivers. In theory, other drivers might still run into trouble. But if they do, it will be the fault of the drivers, not of this patch -- that is, the drivers will need to be fixed. Signed-off-by: Alan Stern Reported-and-tested-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/bus.c | 5 ----- drivers/usb/serial/usb-serial.c | 23 ++--------------------- include/linux/usb/serial.h | 8 -------- 3 files changed, 2 insertions(+), 34 deletions(-) diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 7f547dc3a590..ed8adb052ca7 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -60,8 +60,6 @@ static int usb_serial_device_probe(struct device *dev) retval = -ENODEV; goto exit; } - if (port->dev_state != PORT_REGISTERING) - goto exit; driver = port->serial->type; if (driver->port_probe) { @@ -98,9 +96,6 @@ static int usb_serial_device_remove(struct device *dev) if (!port) return -ENODEV; - if (port->dev_state != PORT_UNREGISTERING) - return retval; - device_remove_file(&port->dev, &dev_attr_port_number); driver = port->serial->type; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 69230f01056a..5413bd500781 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1070,17 +1070,12 @@ int usb_serial_probe(struct usb_interface *interface, port = serial->port[i]; dev_set_name(&port->dev, "ttyUSB%d", port->number); dbg ("%s - registering %s", __func__, dev_name(&port->dev)); - port->dev_state = PORT_REGISTERING; device_enable_async_suspend(&port->dev); retval = device_add(&port->dev); - if (retval) { + if (retval) dev_err(&port->dev, "Error registering port device, " "continuing\n"); - port->dev_state = PORT_UNREGISTERED; - } else { - port->dev_state = PORT_REGISTERED; - } } usb_serial_console_init(debug, minor); @@ -1124,22 +1119,8 @@ void usb_serial_disconnect(struct usb_interface *interface) } kill_traffic(port); cancel_work_sync(&port->work); - if (port->dev_state == PORT_REGISTERED) { - - /* Make sure the port is bound so that the - * driver's port_remove method is called. - */ - if (!port->dev.driver) { - int rc; - - port->dev.driver = - &serial->type->driver; - rc = device_bind_driver(&port->dev); - } - port->dev_state = PORT_UNREGISTERING; + if (device_is_registered(&port->dev)) device_del(&port->dev); - port->dev_state = PORT_UNREGISTERED; - } } } serial->type->disconnect(serial); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index fbb666b1b670..474283888233 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -28,13 +28,6 @@ /* parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) -enum port_dev_state { - PORT_UNREGISTERED, - PORT_REGISTERING, - PORT_REGISTERED, - PORT_UNREGISTERING, -}; - /* USB serial flags */ #define USB_SERIAL_WRITE_BUSY 0 @@ -124,7 +117,6 @@ struct usb_serial_port { char throttle_req; unsigned long sysrq; /* sysrq timeout */ struct device dev; - enum port_dev_state dev_state; }; #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) From cd4376e23a59a2adf3084cb5f4a523e6d5fd4e49 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 28 Mar 2012 15:56:17 -0400 Subject: [PATCH 085/438] USB: don't ignore suspend errors for root hubs This patch (as1532) fixes a mistake in the USB suspend code. When the system is going to sleep, we should ignore errors in powering down USB devices, because they don't really matter. The devices will go to low power anyway when the entire USB bus gets suspended (except for SuperSpeed devices; maybe they will need special treatment later). However we should not ignore errors in suspending root hubs, especially if the error indicates that the suspend raced with a wakeup request. Doing so might leave the bus powered on while the system was supposed to be asleep, or it might cause the suspend of the root hub's parent controller device to fail, or it might cause a wakeup request to be ignored. The patch fixes the problem by ignoring errors only when the device in question is not a root hub. Signed-off-by: Alan Stern Reported-by: Chen Peter CC: Tested-by: Chen Peter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f8e2d6d52e5c..9a56635dc19c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1189,8 +1189,13 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) if (status == 0) { status = usb_suspend_device(udev, msg); - /* Again, ignore errors during system sleep transitions */ - if (!PMSG_IS_AUTO(msg)) + /* + * Ignore errors from non-root-hub devices during + * system sleep transitions. For the most part, + * these devices should go to low power anyway when + * the entire bus is suspended. + */ + if (udev->parent && !PMSG_IS_AUTO(msg)) status = 0; } From fca5430d48d53eaf103498c33fd0d1984b9f448b Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Mon, 26 Mar 2012 21:19:40 +0100 Subject: [PATCH 086/438] USB: ftdi_sio: fix status line change handling for TIOCMIWAIT and TIOCGICOUNT Handling of TIOCMIWAIT was changed by commit 1d749f9afa657f6ee9336b2bc1fcd750a647d157 USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers FTDI_STATUS_B0_MASK does not indicate the changed modem status lines, it indicates the value of the current modem status lines. An xor is still required to determine which lines have changed. The count was only being incremented if the line was high. The only reason TIOCMIWAIT still worked was because the status packet is repeated every 1ms, so the count was always changing. The wakeup itself still ran based on the status lines changing. This change fixes handling of updates to the modem status lines and allows multiple processes to use TIOCMIWAIT concurrently. Tested with two processes waiting on different status lines being toggled independently. Signed-off-by: Simon Arlott Cc: Uwe Bonnes Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ff8605b4b4be..c02e4602d90a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -75,7 +75,7 @@ struct ftdi_private { unsigned long last_dtr_rts; /* saved modem control outputs */ struct async_icount icount; wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - char prev_status, diff_status; /* Used for TIOCMIWAIT */ + char prev_status; /* Used for TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ struct usb_serial_port *port; __u16 interface; /* FT2232C, FT2232H or FT4232H port interface @@ -1982,17 +1982,19 @@ static int ftdi_process_packet(struct tty_struct *tty, N.B. packet may be processed more than once, but differences are only processed once. */ status = packet[0] & FTDI_STATUS_B0_MASK; - if (status & FTDI_RS0_CTS) - priv->icount.cts++; - if (status & FTDI_RS0_DSR) - priv->icount.dsr++; - if (status & FTDI_RS0_RI) - priv->icount.rng++; - if (status & FTDI_RS0_RLSD) - priv->icount.dcd++; if (status != priv->prev_status) { - priv->diff_status |= status ^ priv->prev_status; - wake_up_interruptible(&priv->delta_msr_wait); + char diff_status = status ^ priv->prev_status; + + if (diff_status & FTDI_RS0_CTS) + priv->icount.cts++; + if (diff_status & FTDI_RS0_DSR) + priv->icount.dsr++; + if (diff_status & FTDI_RS0_RI) + priv->icount.rng++; + if (diff_status & FTDI_RS0_RLSD) + priv->icount.dcd++; + + wake_up_interruptible_all(&priv->delta_msr_wait); priv->prev_status = status; } From 876ae50d94b02f3f523aa451b45ec5fb9c25d221 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Mon, 26 Mar 2012 23:27:59 +0100 Subject: [PATCH 087/438] USB: ftdi_sio: fix race condition in TIOCMIWAIT, and abort of TIOCMIWAIT when the device is removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two issues here, one is that the device is generating spurious very fast modem status line changes somewhere: CTS becomes high then low 18µs later: [121226.924373] ftdi_process_packet: prev rng=0 dsr=10 dcd=0 cts=6 [121226.924378] ftdi_process_packet: status=10 prev=00 diff=10 [121226.924382] ftdi_process_packet: now rng=0 dsr=10 dcd=0 cts=7 (wake_up_interruptible is called) [121226.924391] ftdi_process_packet: prev rng=0 dsr=10 dcd=0 cts=7 [121226.924394] ftdi_process_packet: status=00 prev=10 diff=10 [121226.924397] ftdi_process_packet: now rng=0 dsr=10 dcd=0 cts=8 (wake_up_interruptible is called) This wakes up the task in TIOCMIWAIT: [121226.924405] ftdi_ioctl: 19451 rng=0->0 dsr=10->10 dcd=0->0 cts=6->8 (wait from 20:51:46 returns and observes both changes) Which then calls TIOCMIWAIT again: 20:51:46.400239 ioctl(3, TIOCMIWAIT, 0x20) = 0 22:11:09.441818 ioctl(3, TIOCMGET, [TIOCM_DTR|TIOCM_RTS]) = 0 22:11:09.442812 ioctl(3, TIOCMIWAIT, 0x20) = -1 EIO (Input/output error) (the second wake_up_interruptible takes effect and an I/O error occurs) The other issue is that TIOCMIWAIT will wait forever (unless the task is interrupted) if the device is removed. This change removes the -EIO return that occurs if the counts don't appear to have changed. Multiple counts may have been processed as one or the waiting task may have started waiting after recording the current count. It adds a bool to indicate that the device has been removed so that TIOCMIWAIT doesn't wait forever, and wakes up any tasks so that they can return -EIO. Signed-off-by: Simon Arlott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c02e4602d90a..02e7f2d32d52 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -76,6 +76,7 @@ struct ftdi_private { struct async_icount icount; wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ char prev_status; /* Used for TIOCMIWAIT */ + bool dev_gone; /* Used to abort TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ struct usb_serial_port *port; __u16 interface; /* FT2232C, FT2232H or FT4232H port interface @@ -1681,6 +1682,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) init_waitqueue_head(&priv->delta_msr_wait); priv->flags = ASYNC_LOW_LATENCY; + priv->dev_gone = false; if (quirk && quirk->port_probe) quirk->port_probe(priv); @@ -1839,6 +1841,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) dbg("%s", __func__); + priv->dev_gone = true; + wake_up_interruptible_all(&priv->delta_msr_wait); + remove_sysfs_attrs(port); kref_put(&priv->kref, ftdi_sio_priv_release); @@ -2397,15 +2402,12 @@ static int ftdi_ioctl(struct tty_struct *tty, */ case TIOCMIWAIT: cprev = priv->icount; - while (1) { + while (!priv->dev_gone) { interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; cnow = priv->icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || @@ -2414,7 +2416,7 @@ static int ftdi_ioctl(struct tty_struct *tty, } cprev = cnow; } - /* not reached */ + return -EIO; break; case TIOCSERGETLSR: return get_lsr_info(port, (struct serial_struct __user *)arg); From c5d703dcc776cb542b41665f2b7e2ba054efb4a7 Mon Sep 17 00:00:00 2001 From: Anton Samokhvalov Date: Wed, 4 Apr 2012 22:26:01 +0400 Subject: [PATCH 088/438] USB: sierra: add support for Sierra Wireless MC7710 Just add new device id. 3G works fine, LTE not tested. Signed-off-by: Anton Samokhvalov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f14465a83dd1..fdd5aa2c8d82 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -289,6 +289,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ + { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */ /* Sierra Wireless C885 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ From 879d38e6bc36d73b0ac40ec9b0d839fda9fa8b1a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 3 Apr 2012 15:24:18 -0400 Subject: [PATCH 089/438] USB: fix race between root-hub suspend and remote wakeup This patch (as1533) fixes a race between root-hub suspend and remote wakeup. If a wakeup event occurs while a root hub is suspending, it might not cause the suspend to fail. Although the host controller drivers check for pending wakeup events at the start of their bus_suspend routines, they generally do not check for wakeup events while the routines are running. In addition, if a wakeup event occurs any time after khubd is frozen and before the root hub is fully suspended, it might not cause a system sleep transition to fail. For example, the host controller drivers do not fail root-hub suspends when a connect-change event is pending. To fix both these issues, this patch causes hcd_bus_suspend() to query the controller driver's hub_status_data method after a root hub is suspended, if the root hub is enabled for wakeup. Any pending status changes will count as wakeup events, causing the root hub to be resumed and the overall suspend to fail with -EBUSY. A significant point is that not all events are reflected immediately in the status bits. Both EHCI and UHCI controllers notify the CPU when remote wakeup begins on a port, but the port's suspend-change status bit doesn't get set until after the port has completed the transition out of the suspend state, some 25 milliseconds later. Consequently, the patch will interpret any nonzero return value from hub_status_data as indicating a pending event, even if none of the status bits are set in the data buffer. Follow-up patches make the necessary changes to ehci-hcd and uhci-hcd. Signed-off-by: Alan Stern CC: Sarah Sharp CC: Chen Peter-B29397 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9d7fc9a39933..140d3e11f212 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) if (status == 0) { usb_set_device_state(rhdev, USB_STATE_SUSPENDED); hcd->state = HC_STATE_SUSPENDED; + + /* Did we race with a root-hub wakeup event? */ + if (rhdev->do_remote_wakeup) { + char buffer[6]; + + status = hcd->driver->hub_status_data(hcd, buffer); + if (status != 0) { + dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n"); + hcd_bus_resume(rhdev, PMSG_AUTO_RESUME); + status = -EBUSY; + } + } } else { spin_lock_irq(&hcd_root_hub_lock); if (!HCD_DEAD(hcd)) { From a448e4dc25303fe551e4dafe16c8c7c34f1b9d82 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 3 Apr 2012 15:24:30 -0400 Subject: [PATCH 090/438] EHCI: keep track of ports being resumed and indicate in hub_status_data This patch (as1537) adds a bit-array to ehci-hcd for keeping track of which ports are undergoing a resume transition. If any of the bits are set when ehci_hub_status_data() is called, the routine will return a nonzero value even if no ports have any status changes pending. This will allow usbcore to handle races between root-hub suspend and port wakeup. Signed-off-by: Alan Stern CC: Sarah Sharp CC: Chen Peter-B29397 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 3 +++ drivers/usb/host/ehci-hub.c | 31 ++++++++++++++++--------------- drivers/usb/host/ehci-tegra.c | 2 ++ drivers/usb/host/ehci.h | 2 ++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 057cdda7a489..806cc95317aa 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -347,6 +347,8 @@ static int ehci_reset (struct ehci_hcd *ehci) if (ehci->debug) dbgp_external_startup(); + ehci->port_c_suspend = ehci->suspended_ports = + ehci->resuming_ports = 0; return retval; } @@ -939,6 +941,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) * like usb_port_resume() does. */ ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); + set_bit(i, &ehci->resuming_ports); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); mod_timer(&hcd->rh_timer, ehci->reset_done[i]); } diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 256fbd42e48c..38fe07623152 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -223,15 +223,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) * remote wakeup, we must fail the suspend. */ if (hcd->self.root_hub->do_remote_wakeup) { - port = HCS_N_PORTS(ehci->hcs_params); - while (port--) { - if (ehci->reset_done[port] != 0) { - spin_unlock_irq(&ehci->lock); - ehci_dbg(ehci, "suspend failed because " - "port %d is resuming\n", - port + 1); - return -EBUSY; - } + if (ehci->resuming_ports) { + spin_unlock_irq(&ehci->lock); + ehci_dbg(ehci, "suspend failed because a port is resuming\n"); + return -EBUSY; } } @@ -554,16 +549,12 @@ static int ehci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 temp, status = 0; + u32 temp, status; u32 mask; int ports, i, retval = 1; unsigned long flags; u32 ppcd = 0; - /* if !USB_SUSPEND, root hub timers won't get shut down ... */ - if (ehci->rh_state != EHCI_RH_RUNNING) - return 0; - /* init status to no-changes */ buf [0] = 0; ports = HCS_N_PORTS (ehci->hcs_params); @@ -572,6 +563,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) retval++; } + /* Inform the core about resumes-in-progress by returning + * a non-zero value even if there are no status changes. + */ + status = ehci->resuming_ports; + /* Some boards (mostly VIA?) report bogus overcurrent indications, * causing massive log spam unless we completely ignore them. It * may be relevant that VIA VT8235 controllers, where PORT_POWER is @@ -846,6 +842,7 @@ static int ehci_hub_control ( ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESUME), status_reg); + clear_bit(wIndex, &ehci->resuming_ports); retval = handshake(ehci, status_reg, PORT_RESUME, 0, 2000 /* 2msec */); if (retval != 0) { @@ -864,6 +861,7 @@ static int ehci_hub_control ( ehci->reset_done[wIndex])) { status |= USB_PORT_STAT_C_RESET << 16; ehci->reset_done [wIndex] = 0; + clear_bit(wIndex, &ehci->resuming_ports); /* force reset to complete */ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), @@ -884,8 +882,10 @@ static int ehci_hub_control ( ehci_readl(ehci, status_reg)); } - if (!(temp & (PORT_RESUME|PORT_RESET))) + if (!(temp & (PORT_RESUME|PORT_RESET))) { ehci->reset_done[wIndex] = 0; + clear_bit(wIndex, &ehci->resuming_ports); + } /* transfer dedicated ports to the companion hc */ if ((temp & PORT_CONNECT) && @@ -920,6 +920,7 @@ static int ehci_hub_control ( status |= USB_PORT_STAT_SUSPEND; } else if (test_bit(wIndex, &ehci->suspended_ports)) { clear_bit(wIndex, &ehci->suspended_ports); + clear_bit(wIndex, &ehci->resuming_ports); ehci->reset_done[wIndex] = 0; if (temp & PORT_PE) set_bit(wIndex, &ehci->port_c_suspend); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 3de48a2d7955..73544bd440bd 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -224,6 +224,7 @@ static int tegra_ehci_hub_control( temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); /* start resume signalling */ ehci_writel(ehci, temp | PORT_RESUME, status_reg); + set_bit(wIndex-1, &ehci->resuming_ports); spin_unlock_irqrestore(&ehci->lock, flags); msleep(20); @@ -236,6 +237,7 @@ static int tegra_ehci_hub_control( pr_err("%s: timeout waiting for SUSPEND\n", __func__); ehci->reset_done[wIndex-1] = 0; + clear_bit(wIndex-1, &ehci->resuming_ports); tegra->port_resuming = 1; goto done; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 8f9acbc96fde..2694ed6558d2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -117,6 +117,8 @@ struct ehci_hcd { /* one per controller */ the change-suspend feature turned on */ unsigned long suspended_ports; /* which ports are suspended */ + unsigned long resuming_ports; /* which ports have + started to resume */ /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ From b446b96fd11b69b7c4ecd47d869cff9094fd8802 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 3 Apr 2012 15:24:43 -0400 Subject: [PATCH 091/438] UHCI: hub_status_data should indicate if ports are resuming This patch (as1538) causes uhci_hub_status_data() to return a nonzero value when any port is undergoing a resume transition while the root hub is suspended. This will allow usbcore to handle races between root-hub suspend and port wakeup. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 045cde4cbc3d..768d54295a20 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -196,11 +196,12 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) status = get_hub_status_data(uhci, buf); switch (uhci->rh_state) { - case UHCI_RH_SUSPENDING: case UHCI_RH_SUSPENDED: /* if port change, ask to be resumed */ - if (status || uhci->resuming_ports) + if (status || uhci->resuming_ports) { + status = 1; usb_hcd_resume_root_hub(hcd); + } break; case UHCI_RH_AUTO_STOPPED: From dff2aa7af8c96a11f75d858859f0e0c78b193d12 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Mon, 2 Apr 2012 18:19:49 +0100 Subject: [PATCH 092/438] ARM: 7368/1: fault.c: correct how the tsk->[maj|min]_flt gets incremented commit 8878a539ff19a43cf3729e7562cd528f490246ae was done by me to make the page fault handler retryable as well as interruptible. Due to this commit, there is a mistake in the way in which tsk->[maj|min]_flt counter gets incremented for VM_FAULT_ERROR: If VM_FAULT_ERROR is returned in the fault flags by handle_mm_fault, then either maj_flt or min_flt will get incremented. This is wrong as in the case of a VM_FAULT_ERROR we need to be skip ahead to the error handling code in do_page_fault. Added a check after the call to __do_page_fault() to check for (fault & VM_FAULT_ERROR). Signed-off-by: Kautuk Consul Signed-off-by: Russell King --- arch/arm/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 9055b5a84ec5..f07467533365 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -320,7 +320,7 @@ retry: */ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) { if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, From 34af657916332e89564566bc8d35e3e06cc0c236 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 5 Apr 2012 19:42:10 +0100 Subject: [PATCH 093/438] ARM: 7377/1: vic: re-read status register before dispatching each IRQ handler handle_IRQ may briefly cause interrupts to be re-enabled during soft IRQ processing on the exit path, leading to nested handling of VIC interrupts. Since the current code does not re-read the VIC_IRQ_STATUS register, this can lead to multiple invocations of the same interrupt handler and spurious interrupts to be reported. This patch changes the VIC interrupt dispatching code to re-read the status register each time, avoiding duplicate invocations of the same handler. Acked-and-Tested-by: H Hartley Sweeten Reviewed-by: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/common/vic.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 7a66311f3066..7e288f96cedf 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -427,19 +427,18 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) /* * Handle each interrupt in a single VIC. Returns non-zero if we've - * handled at least one interrupt. This does a single read of the - * status register and handles all interrupts in order from LSB first. + * handled at least one interrupt. This reads the status register + * before handling each interrupt, which is necessary given that + * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. */ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) { u32 stat, irq; int handled = 0; - stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); - while (stat) { + while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { irq = ffs(stat) - 1; handle_IRQ(irq_find_mapping(vic->domain, irq), regs); - stat &= ~(1 << irq); handled = 1; } From 9886f444129171569461d8c39983e16f4871e3b4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 10 Apr 2012 10:50:55 +0200 Subject: [PATCH 094/438] itimer: Use printk_once instead of WARN_ONCE David pointed out, that WARN_ONCE() to report usage of an deprecated misfeature make folks unhappy. Use printk_once() instead. Andrew told me to stop grumbling and to remove the silly typecast while touching the file. Reported-by: David Rientjes Cc: Andrew Morton Signed-off-by: Thomas Gleixner --- kernel/itimer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/itimer.c b/kernel/itimer.c index c70369a74b5a..8d262b467573 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -285,9 +285,10 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) return -EFAULT; } else { - memset((char *) &set_buffer, 0, sizeof(set_buffer)); - WARN_ONCE(1, "setitimer: new_value pointer is NULL." - " Misfeature support will be removed\n"); + memset(&set_buffer, 0, sizeof(set_buffer)); + printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer." + " Misfeature support will be removed\n", + current->comm); } error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); From 6d258a4c42089229b855fd706622029decf316d6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 15 Mar 2012 16:37:18 +0200 Subject: [PATCH 095/438] usb: gadget: udc-core: stop UDC on device-initiated disconnect When we want to do device-initiated disconnect, let's make sure we stop the UDC in order to e.g. allow lower power states to be achieved by turning off unnecessary clocks and/or stoping PHYs. When reconnecting, call ->udc_start() again to make sure UDC is reinitialized. Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 56da49f31d6c..c261887e05ae 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { + if (udc_is_newstyle(udc)) + usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { + if (udc_is_newstyle(udc)) + usb_gadget_udc_stop(udc->gadget, udc->driver); usb_gadget_disconnect(udc->gadget); } else { dev_err(dev, "unsupported command '%s'\n", buf); From 566ccdda07dc5898272b6fbad9c616fc44be305a Mon Sep 17 00:00:00 2001 From: Moiz Sonasath Date: Wed, 14 Mar 2012 00:44:56 -0500 Subject: [PATCH 096/438] usb: dwc3: ep0: Handle requests greater than wMaxPacketSize To allow ep0 out transfers of upto bounce buffer size instead of maxpacketsize, use the transfer size as multiple of ep0 maxpacket size. Cc: stable@vger.kernel.org Signed-off-by: Moiz Sonasath Signed-off-by: Partha Basak Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 25910e251c04..a40d3bb0f1c2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -559,8 +559,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { + unsigned transfer_size = ur->length; + unsigned maxp = ep0->endpoint.maxpacket; + + transfer_size += (maxp - (transfer_size % maxp)); transferred = min_t(u32, ur->length, - ep0->endpoint.maxpacket - length); + transfer_size - length); memcpy(ur->buf, dwc->ep0_bounce, transferred); dwc->ep0_bounced = false; } else { From cd423dd3634a5232a3019eb372b144619a61cd16 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 21 Mar 2012 11:44:00 +0200 Subject: [PATCH 097/438] usb: dwc3: ep0: increment "actual" on bounced ep0 case due to a HW limitation we have a bounce buffer for ep0 out transfers which are not aligned with MaxPacketSize. On such case we were not increment r->actual as we should. This patch fixes that mistake. Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index a40d3bb0f1c2..da43131be0e7 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -569,9 +569,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, dwc->ep0_bounced = false; } else { transferred = ur->length - length; - ur->actual += transferred; } + ur->actual += transferred; + if ((epnum & 1) && ur->actual < ur->length) { /* for some reason we did not get everything out */ From fa4da365bc7772c2cd6d5405bdf151612455f957 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Mon, 9 Apr 2012 15:41:44 -0700 Subject: [PATCH 098/438] clockevents: tTack broadcast device mode change in tick_broadcast_switch_to_oneshot() In the commit 77b0d60c5adf39c74039e2142a1d3cd1e4d53799, "clockevents: Leave the broadcast device in shutdown mode when not needed", we were bailing out too quickly in tick_broadcast_switch_to_oneshot(), with out tracking the broadcast device mode change to 'TICKDEV_MODE_ONESHOT'. This breaks the platforms which need broadcast device oneshot services during deep idle states. tick_broadcast_oneshot_control() thinks that it is in periodic mode and fails to take proper decisions based on the CLOCK_EVT_NOTIFY_BROADCAST_[ENTER, EXIT] notifications during deep idle entry/exit. Fix this by tracking the broadcast device mode as 'TICKDEV_MODE_ONESHOT', before leaving the broadcast HW device in shutdown mode if there are no active requests for the moment. Reported-and-tested-by: Santosh Shilimkar Signed-off-by: Suresh Siddha Cc: johnstul@us.ibm.com Link: http://lkml.kernel.org/r/1334011304.12400.81.camel@sbsiddha-desk.sc.intel.com Signed-off-by: Thomas Gleixner --- kernel/time/tick-broadcast.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index e883f57a3cd3..bf57abdc7bd0 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -575,10 +575,12 @@ void tick_broadcast_switch_to_oneshot(void) unsigned long flags; raw_spin_lock_irqsave(&tick_broadcast_lock, flags); + + tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; + if (cpumask_empty(tick_get_broadcast_mask())) goto end; - tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; bc = tick_broadcast_device.evtdev; if (bc) tick_broadcast_setup_oneshot(bc); From f19a0c2c2e6add90b7d6a1b7595abebfe2e4c37a Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 9 Apr 2012 17:38:35 +0300 Subject: [PATCH 099/438] KVM: PMU emulation: GLOBAL_CTRL MSR should be enabled on reset On reset all MPU counters should be enabled in GLOBAL_CTRL MSR. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/pmu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 173df38dbda5..2e88438ffd83 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1); if (pmu->version == 1) { - pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1; - return; + pmu->nr_arch_fixed_counters = 0; + } else { + pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), + X86_PMC_MAX_FIXED); + pmu->counter_bitmask[KVM_PMC_FIXED] = + ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; } - pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), - X86_PMC_MAX_FIXED); - pmu->counter_bitmask[KVM_PMC_FIXED] = - ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; - pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1) - | (((1ull << pmu->nr_arch_fixed_counters) - 1) - << X86_PMC_IDX_FIXED)); + pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | + (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); + pmu->global_ctrl_mask = ~pmu->global_ctrl; } void kvm_pmu_init(struct kvm_vcpu *vcpu) From 6e7beb7ec8b8c3a1927d4d02c33a0e2a8e72eec3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 10 Apr 2012 08:31:48 -0700 Subject: [PATCH 100/438] ARM: S5PV210: Fix compiler warning in dma.c file Fixes the following warning: warning: 'dma_dmamask' defined but not used [-Wunused-variable] Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 86ce62f66190..b8337e248b09 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -33,8 +33,6 @@ #include #include -static u64 dma_dmamask = DMA_BIT_MASK(32); - static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, From 60806225cdad7f582fcf5e2d7a089486f9718f2f Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 10 Apr 2012 08:37:59 -0700 Subject: [PATCH 101/438] ARM: EXYNOS: Add PDMA and MDMA physical base address defines Add PDMA and MDMA physical base address macros which is require for EXYNOS5 of_dev_auxdata setup. Signed-off-by: Thomas Abraham [kgene.kim@samsung.com: changed dma channel fo mdma1] Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/map.h | 4 ++++ arch/arm/mach-exynos/mach-exynos5-dt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 024d38ff1718..6e6d11ff352a 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -89,6 +89,10 @@ #define EXYNOS4_PA_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 +#define EXYNOS5_PA_MDMA0 0x10800000 +#define EXYNOS5_PA_MDMA1 0x11C10000 +#define EXYNOS5_PA_PDMA0 0x121A0000 +#define EXYNOS5_PA_PDMA1 0x121B0000 #define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 #define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 0d26f50081ad..4711c8920e37 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -45,7 +45,7 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { "exynos4210-uart.3", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), {}, }; From ecb07797ffc1c2aaa2e58d1ba1b5deea44ea5b9e Mon Sep 17 00:00:00 2001 From: Gerard Cauvy Date: Fri, 16 Mar 2012 16:20:10 +0200 Subject: [PATCH 102/438] usb: dwc3: ep0: add a default case for SetFeature command Without this default case returning an error, thus replying with a stall, we would fail USB30CV TD 9.11 Bad Feature test case. Cc: stable@vger.kernel.org Signed-off-by: Gerard Cauvy Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index da43131be0e7..3584a169886f 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; + break; + default: + return -EINVAL; } break; From afb76df140823c57738598a876cd1d6568cd57c7 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 23 Dec 2011 18:37:18 +0200 Subject: [PATCH 103/438] usb: musb: fix oops on omap2430 module unload This change prevents runtime suspend and resume actual execution, if omap2430 controller driver is loaded after musb-hdrc, and therefore the controller isn't initialized properly. The problem is reproducible with 3.1.y and 3.2 kernels. Kernel configuration of musb: % cat .config | egrep 'MUSB|GADGET' CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_TUSB6010 is not set CONFIG_USB_MUSB_OMAP2PLUS=m # CONFIG_USB_MUSB_AM35X is not set CONFIG_MUSB_PIO_ONLY=y CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 CONFIG_USB_GADGET_MUSB_HDRC=m CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_GADGETFS=m # CONFIG_USB_MIDI_GADGET is not set Fixes the following oops on module unloading: Unable to handle kernel NULL pointer dereference at virtual address 00000220 ----8<---- [] (omap2430_runtime_resume+0x24/0x54 [omap2430]) from [] (pm_generic_runtime_resume+0x3c/0x50) [] (pm_generic_runtime_resume+0x3c/0x50) from [] (_od_runtime_resume+0x28/0x2c) [] (_od_runtime_resume+0x28/0x2c) from [] (__rpm_callback+0x60/0xa0) [] (__rpm_callback+0x60/0xa0) from [] (rpm_resume+0x3fc/0x6e4) [] (rpm_resume+0x3fc/0x6e4) from [] (__pm_runtime_resume+0x5c/0x90) [] (__pm_runtime_resume+0x5c/0x90) from [] (__device_release_driver+0x2c/0xd0) [] (__device_release_driver+0x2c/0xd0) from [] (driver_detach+0xe8/0xf4) [] (driver_detach+0xe8/0xf4) from [] (bus_remove_driver+0xa0/0x104) [] (bus_remove_driver+0xa0/0x104) from [] (driver_unregister+0x60/0x80) [] (driver_unregister+0x60/0x80) from [] (platform_driver_unregister+0x1c/0x20) [] (platform_driver_unregister+0x1c/0x20) from [] (omap2430_exit+0x14/0x1c [omap2430]) [] (omap2430_exit+0x14/0x1c [omap2430]) from [] (sys_delete_module+0x1f4/0x264) [] (sys_delete_module+0x1f4/0x264) from [] (ret_fast_syscall+0x0/0x30) Signed-off-by: Vladimir Zapolskiy Cc: Greg Kroah-Hartman Cc: stable@vger.kernel.org # 3.1 Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2ae0bb309994..11b571ec22f2 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -491,11 +491,13 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + if (musb) { + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); - omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb->xceiv, 1); + omap2430_low_level_exit(musb); + usb_phy_set_suspend(musb->xceiv, 1); + } return 0; } @@ -505,11 +507,13 @@ static int omap2430_runtime_resume(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); + if (musb) { + omap2430_low_level_init(musb); + musb_writel(musb->mregs, OTG_INTERFSEL, + musb->context.otg_interfsel); - usb_phy_set_suspend(musb->xceiv, 0); + usb_phy_set_suspend(musb->xceiv, 0); + } return 0; } From c04352a590538123f8c93bd87ef1d4bb9e3a64c7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 4 Feb 2012 19:43:51 +0200 Subject: [PATCH 104/438] usb: musb: fix some runtime_pm issues When runtime_pm was originally added, it was done in rather confusing way: omap2430_musb_init() (called from musb_init_controller) would do runtime_pm_get_sync() and musb_init_controller() itself would do runtime_pm_put to balance it out. This is not only confusing but also wrong if non-omap2430 glue layer is used. This confusion resulted in commit 772aed45b604 "usb: musb: fix pm_runtime mismatch", that removed runtime_pm_put() from musb_init_controller as that looked unbalanced, and also happened to fix unrelated isp1704_charger crash. However this broke runtime PM functionality (musb is now always powered, even without gadget active). Avoid these confusing runtime pm dependences by making musb_init_controller() and omap2430_musb_init() do their own runtime get/put pairs; also cover error paths. Remove unneeded runtime_pm_put in omap2430_remove too. isp1704_charger crash that motivated 772aed45b604 will be fixed by following patch. Cc: Felipe Contreras Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 9 ++++++++- drivers/usb/musb/omap2430.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a40..239214626ec5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1904,7 +1904,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail3; + goto fail2; } if (!musb->xceiv->io_ops) { @@ -1912,6 +1912,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->xceiv->io_ops = &musb_ulpi_access; } + pm_runtime_get_sync(musb->controller); + #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2023,6 +2025,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif + pm_runtime_put(musb->controller); + dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2047,6 +2051,9 @@ fail4: musb_gadget_cleanup(musb); fail3: + pm_runtime_put_sync(musb->controller); + +fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 11b571ec22f2..3dfd122266f4 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -333,6 +333,7 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); + pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -478,7 +479,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); - pm_runtime_put(&pdev->dev); kfree(glue); return 0; From f79a60b8785409f5a77767780315ce6d3ea04a44 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 29 Feb 2012 20:19:46 +0800 Subject: [PATCH 105/438] usb: fsl_udc_core: prime status stage once data stage has primed - For Control Read transfer, the ACK handshake on an IN transaction may be corrupted, so the device may not receive the ACK for data stage, the complete irq will not occur at this situation. Therefore, we need to move prime status stage from complete irq routine to the place where the data stage has just primed, or the host will never get ACK for status stage. The above issue has been described at USB2.0 spec chapter 8.5.3.3. - After adding prime status stage just after prime the data stage, there is a potential problem when the status dTD is added before the data stage has primed by hardware. The reason is the device's dTD descriptor has NO direction bit, if data stage (IN) prime hasn't finished, the status stage(OUT) dTD will be added at data stage dTD's Next dTD Pointer, so when the data stage transfer has finished, the status dTD will be primed as IN by hardware, then the host will never receive ACK from the device side for status stage. - Delete below code at fsl_ep_queue: /* Update ep0 state */ if ((ep_index(ep) == 0)) udc->ep0_state = DATA_STATE_XMIT; the udc->ep0_state will be updated again after udc->driver->setup finishes. It is tested at i.mx51 bbg board with g_mass_storage, g_ether, g_serial. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b9..55abfb6bd612 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); /* check if the pipe is empty */ - if (!(list_empty(&ep->queue))) { + if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) { /* Add td to the end */ struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return -ENOMEM; } - /* Update ep0 state */ - if ((ep_index(ep) == 0)) - udc->ep0_state = DATA_STATE_XMIT; - /* irq handler advances the queue */ if (req != NULL) list_add_tail(&req->queue, &ep->queue); @@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) udc->ep0_dir = USB_DIR_OUT; ep = &udc->eps[0]; - udc->ep0_state = WAIT_FOR_OUT_STATUS; + if (udc->ep0_state != DATA_STATE_XMIT) + udc->ep0_state = WAIT_FOR_OUT_STATUS; req->ep = ep; req->req.length = 0; @@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); + return; stall: ep0stall(udc); @@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc, spin_lock(&udc->lock); udc->ep0_state = (setup->bRequestType & USB_DIR_IN) ? DATA_STATE_XMIT : DATA_STATE_RECV; + /* + * If the data stage is IN, send status prime immediately. + * See 2.0 Spec chapter 8.5.3.3 for detail. + */ + if (udc->ep0_state == DATA_STATE_XMIT) + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); + } else { /* No data phase, IN status from gadget */ udc->ep0_dir = USB_DIR_IN; @@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, switch (udc->ep0_state) { case DATA_STATE_XMIT: - /* receive status phase */ - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); + /* already primed at setup_received_irq */ + udc->ep0_state = WAIT_FOR_OUT_STATUS; break; case DATA_STATE_RECV: /* send status phase */ From f7a83fe19336125d7eb26488788dc66c03f2c08e Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:05:49 +0900 Subject: [PATCH 106/438] usb: s3c-hsotg: Fix TX FIFOs allocation According to documentation, TX FIFO_number index starts from 1. For IN endpoint FIFO 0 we use GNPTXFSIZ register for programming the size and memory start address. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 69295ba9d99a..e3fe5fd795f0 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) /* currently we allocate TX FIFOs for all possible endpoints, * and assume that they are all the same size. */ - for (ep = 0; ep <= 15; ep++) { + for (ep = 1; ep <= 15; ep++) { val = addr; val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; addr += size; From 659ad60cb9128345d0a6b9093dda9b0e366b7937 Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:07:29 +0900 Subject: [PATCH 107/438] usb: s3c-hsotg: Fix maximum patcket size setting for EP0 MPS field of DOEPCTL0 is read only. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index e3fe5fd795f0..03de169ab365 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, reg |= mpsval; writel(reg, regs + S3C_DIEPCTL(ep)); - reg = readl(regs + S3C_DOEPCTL(ep)); - reg &= ~S3C_DxEPCTL_MPS_MASK; - reg |= mpsval; - writel(reg, regs + S3C_DOEPCTL(ep)); + if (ep) { + reg = readl(regs + S3C_DOEPCTL(ep)); + reg &= ~S3C_DxEPCTL_MPS_MASK; + reg |= mpsval; + writel(reg, regs + S3C_DOEPCTL(ep)); + } return; From 70fa030ffb652ace81dd5bcab01255b49723caec Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:08:29 +0900 Subject: [PATCH 108/438] usb: s3c-hsotg: Avoid TxFIFO corruption in DMA mode Writing to TxFIFO relates only to Slave mode and leads to TxFIFO corruption in DMA mode. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 03de169ab365..8db23660b5e2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -1921,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); - s3c_hsotg_trytx(hsotg, hs_ep); + if (!using_dma(hsotg)) + s3c_hsotg_trytx(hsotg, hs_ep); } } } From db1d8ba36551bf55222c7961d9e9a1195a612fde Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 14:09:19 +0900 Subject: [PATCH 109/438] usb: s3c-hsotg: Fix big buffers transfer in DMA mode DMA address register shouldn't be updated manually if transfer size requires multiple packets. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 8db23660b5e2..105b206cd844 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, /* write size / packets */ writel(epsize, hsotg->regs + epsize_reg); - if (using_dma(hsotg)) { + if (using_dma(hsotg) && !continuing) { unsigned int dma_reg; /* write DMA address to control register, buffer already From 64b6c8a7019acc38cc6b37f8e72c1e915593b1bb Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Tue, 6 Mar 2012 17:05:15 +0900 Subject: [PATCH 110/438] usb: dwc3: Free event buffers array Array should be freed together with event buffers, since it was allocated dynamically. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7bd815a507e8..99b58d84553a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - if (evt) { + if (evt) dwc3_free_one_event_buffer(dwc, evt); - dwc->ev_buffs[i] = NULL; - } } + + kfree(dwc->ev_buffs); } /** From e2190a97c6d493eef1f180b9dadfd5ffd4706051 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 12 Mar 2012 12:55:41 +0100 Subject: [PATCH 111/438] usb: gadget: FunctionFS: clear FFS_FL_BOUND flag on unbind (bugfix) clear FFS_FL_BOUND flag on unbind (bugfix) Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cbba70836bc..d187ae73262b 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; ffs_data_put(ffs); + clear_bit(FFS_FL_BOUND, &ffs->flags); } } From 8545e6031a719675da9f3d21f1c8ce143dac7fe5 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 12 Mar 2012 12:55:42 +0100 Subject: [PATCH 112/438] usb: gadget: FunctionFS: make module init & exit __init & __exit make module init & exit __init & __exit Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/g_ffs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 331cd6729d3c..a85eaf40b948 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = { static struct ffs_data *gfs_ffs_data; static unsigned long gfs_registered; -static int gfs_init(void) +static int __init gfs_init(void) { ENTER(); @@ -169,7 +169,7 @@ static int gfs_init(void) } module_init(gfs_init); -static void gfs_exit(void) +static void __exit gfs_exit(void) { ENTER(); From 692933b2ccfce02400dc8360a97acde2846e8541 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Wed, 14 Mar 2012 17:33:35 +0530 Subject: [PATCH 113/438] usb: musb: fix bug in musb_cleanup_urb Control transfers with data expected from device to host will use usb_rcvctrlpipe() for urb->pipe so for such urbs 'is_in' will be set causing control urb to fall into the first "if" condition in musb_cleanup_urb(). Fixed by adding logic to check for non control endpoints. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af779fa..ef8d744800ac 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) } /* turn off DMA requests, discard state, stop polling ... */ - if (is_in) { + if (ep->epnum && is_in) { /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); From bf070bc14178f1458e7eccd76316ac24f76f1890 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Wed, 21 Mar 2012 16:35:52 +0200 Subject: [PATCH 114/438] usb: musb: wake the device before ulpi transfers musb can be suspended at the time some other driver wants to do ulpi transfers using usb_phy_io_* functions, and that can cause data abort, as it happened with isp1704_charger: http://article.gmane.org/gmane.linux.kernel/1226122 Add pm_runtime to ulpi functions to rectify this. This also adds io_dev to usb_phy so that pm_runtime_* functions can be used. Cc: Felipe Contreras Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 31 +++++++++++++++++++++++++------ include/linux/usb/otg.h | 1 + 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 239214626ec5..66aaccf04490 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) int i = 0; u8 r; u8 power; + int ret; + + pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) - return -ETIMEDOUT; + if (i == 10000) { + ret = -ETIMEDOUT; + goto out; + } } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - return musb_readb(addr, MUSB_ULPI_REG_DATA); + ret = musb_readb(addr, MUSB_ULPI_REG_DATA); + +out: + pm_runtime_put(phy->io_dev); + + return ret; } static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) int i = 0; u8 r = 0; u8 power; + int ret = 0; + + pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) - return -ETIMEDOUT; + if (i == 10000) { + ret = -ETIMEDOUT; + goto out; + } } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - return 0; +out: + pm_runtime_put(phy->io_dev); + + return ret; } #else #define musb_ulpi_read NULL @@ -1908,6 +1926,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) } if (!musb->xceiv->io_ops) { + musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; } diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index f67810f8f21b..38ab3f46346f 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -94,6 +94,7 @@ struct usb_phy { struct usb_otg *otg; + struct device *io_dev; struct usb_phy_io_ops *io_ops; void __iomem *io_priv; From 3006dc8c627d738693e910c159630e4368c9e86c Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Wed, 21 Mar 2012 21:30:20 +0530 Subject: [PATCH 115/438] usb: musb: omap: fix crash when musb glue (omap) gets initialized pm_runtime_enable is being called after omap2430_musb_init. Hence pm_runtime_get_sync in omap2430_musb_init does not have any effect (does not enable clocks) resulting in a crash during register access. It is fixed here. Cc: stable@vger.kernel.org # v3.0, v3.1, v3.2, v3.3 Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 3dfd122266f4..0fb4ce84d17e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -453,14 +453,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err2; } + pm_runtime_enable(&pdev->dev); + ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } - pm_runtime_enable(&pdev->dev); - return 0; err2: From 8ae8090c82eb407267001f75b3d256b3bd4ae691 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Wed, 21 Mar 2012 21:34:30 +0530 Subject: [PATCH 116/438] usb: gadget: udc-core: fix asymmetric calls in remove_driver During modprobe of gadget driver, pullup is called after udc_start. In order to make the exit path symmetric when removing a gadget driver, call pullup before ->udc_stop. This is needed to avoid issues with PM where udc_stop disables the module completely (put IP in reset state, cut functional and interface clocks, and so on), which prevents us from accessing the IP's address space, thus creating the possibility of an abort exception when we try to access IP's address space after clocks are off. Cc: stable@vger.kernel.org Signed-off-by: Partha Basak Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index c261887e05ae..2fa9865babed 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) if (udc_is_newstyle(udc)) { udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); usb_gadget_disconnect(udc->gadget); + usb_gadget_udc_stop(udc->gadget, udc->driver); } else { usb_gadget_stop(udc->gadget, udc->driver); } From ad579699c4f0274bf522a9252ff9b20c72197e48 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Thu, 22 Mar 2012 12:48:06 +0530 Subject: [PATCH 117/438] usb: musb: omap: fix the error check for pm_runtime_get_sync pm_runtime_get_sync returns a signed integer. In case of errors it returns a negative value. This patch fixes the error check by making it signed instead of unsigned thus preventing register access if get_sync_fails. Also passes the error cause to the debug message. Cc: stable@vger.kernel.org Cc: Kishon Vijay Abraham I Signed-off-by: Shubhrajyoti D Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 0fb4ce84d17e..c7785e81254c 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) static int omap2430_musb_init(struct musb *musb) { - u32 l, status = 0; + u32 l; + int status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED"); + dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); goto err1; } From f135617224b4a1113b26b8ee5877e94f38e40d1e Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 10 Feb 2012 09:54:51 +0100 Subject: [PATCH 118/438] usb: gadget: rndis: fix Missing req->context assignment It is crucial to assign each req->context value to struct rndis. The problem happens for multi function gadget (g_multi) when multiple functions are calling common usb_composite_dev control request. It might happen that *_setup method from one usb function will alter some fields of this common request issued by other USB function. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7b1cf18df5e3..52343654f5df 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (buf) { memcpy(req->buf, buf, n); req->complete = rndis_response_complete; + req->context = rndis; rndis_free_response(rndis->config, buf); value = n; } From 6190c79df861d2c78a7448fe6d4260e5fa53b9b9 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 23 Mar 2012 22:23:13 +0530 Subject: [PATCH 119/438] usb: gadget: uvc: Remove non-required locking from 'uvc_queue_next_buffer' routine This patch removes the non-required spinlock acquire/release calls on 'queue->irqlock' from 'uvc_queue_next_buffer' routine. This routine is called from 'video->encode' function (which translates to either 'uvc_video_encode_bulk' or 'uvc_video_encode_isoc') in 'uvc_video.c'. As, the 'video->encode' routines are called with 'queue->irqlock' already held, so acquiring a 'queue->irqlock' again in 'uvc_queue_next_buffer' routine causes a spin lock recursion. Signed-off-by: Bhupesh Sharma Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_queue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index d776adb2da67..0cdf89d32a15 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ done: return ret; } +/* called with queue->irqlock held.. */ static struct uvc_buffer * uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { struct uvc_buffer *nextbuf; - unsigned long flags; if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->buf.length != buf->buf.bytesused) { @@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) return buf; } - spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); else nextbuf = NULL; - spin_unlock_irqrestore(&queue->irqlock, flags); buf->buf.sequence = queue->sequence++; do_gettimeofday(&buf->buf.timestamp); From 92b0abf80c5c5f0e0d71d1309688a330fd74731b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 28 Mar 2012 09:30:50 +0200 Subject: [PATCH 120/438] usb: gadget: eliminate NULL pointer dereference (bugfix) usb: gadget: eliminate NULL pointer dereference (bugfix) This patch fixes a bug which causes NULL pointer dereference in ffs_ep0_ioctl. The bug happens when the FunctionFS is not bound (either has not been bound yet or has been bound and then unbound) and can be reproduced with running the following commands: $ insmod g_ffs.ko $ mount -t functionfs func /dev/usbgadget $ ./null where null.c is: #include #include int main(void) { int fd = open("/dev/usbgadget/ep0", O_RDWR); ioctl(fd, FUNCTIONFS_CLEAR_HALT); return 0; } Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index d187ae73262b..f52cb1ae45d9 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget->ops->ioctl) { + } else if (gadget && gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; From fcff311c938c95c90573c060d37648df00e45017 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 21 Mar 2012 12:32:32 +0000 Subject: [PATCH 121/438] staging: sep: Fix sign of error One of our errors wasn't negative as intended. Fix this. (Found by Hillf Danton) While we are at it turn user causable messages down to dev_dbg level in the ioctl paths. Signed-off-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index ad54c2e5c932..f1701bc6e312 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -3114,7 +3114,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) current->pid); if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status)) { - dev_warn(&sep->pdev->dev, + dev_dbg(&sep->pdev->dev, "[PID%d] dcb prep needed before send msg\n", current->pid); error = -EPROTO; @@ -3122,9 +3122,9 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (!arg) { - dev_warn(&sep->pdev->dev, + dev_dbg(&sep->pdev->dev, "[PID%d] dcb null arg\n", current->pid); - error = EINVAL; + error = -EINVAL; goto end_function; } From eaa004a4ba3264d17d7e6882948a7980e14e9d20 Mon Sep 17 00:00:00 2001 From: Gerard Snitselaar Date: Fri, 23 Mar 2012 03:21:05 -0700 Subject: [PATCH 122/438] staging/vme: Fix module parameters loopback should be declared bool, and variant probably shouldn't be const. Signed-off-by: Gerard Snitselaar Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 9fedc442a779..573c80003f0c 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -35,10 +35,10 @@ static int vector[PIO2_CARDS_MAX]; static int vector_num; static int level[PIO2_CARDS_MAX]; static int level_num; -static const char *variant[PIO2_CARDS_MAX]; +static char *variant[PIO2_CARDS_MAX]; static int variant_num; -static int loopback; +static bool loopback; static int pio2_match(struct vme_dev *); static int __devinit pio2_probe(struct vme_dev *); From 50637f050e88fb175135de62a53be33c374a5349 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Fri, 23 Mar 2012 09:40:15 -0700 Subject: [PATCH 123/438] staging: ramster: unbreak my heart The just-merged ramster staging driver was dependent on a cleanup patch in cleancache, so was marked CONFIG_BROKEN until that patch could be merged. That cleancache patch is now merged (and the correct SHA of the cleancache patch is 3167760f83899ccda312b9ad9306ec9e5dda06d4 rather than the one shown in the comment removed in the patch below). So remove the CONFIG_BROKEN now and the comment that is no longer true... Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/Kconfig | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 8b57b87edda4..4af1f8d4b953 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -1,10 +1,6 @@ -# Dependency on CONFIG_BROKEN is because there is a commit dependency -# on a cleancache naming change to be submitted by Konrad Wilk -# a39c00ded70339603ffe1b0ffdf3ade85bcf009a "Merge branch 'stable/cleancache.v13' -# into linux-next. Once this commit is present, BROKEN can be removed config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM select LZO_COMPRESS select LZO_DECOMPRESS default n From 218f4d437d69b4621f36affd52dcd6343597149a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Sat, 24 Mar 2012 07:19:25 +0100 Subject: [PATCH 124/438] staging:iio:core add missing increment of loop index in iio_map_array_unregister() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit staging:iio:core add missing increment of loop index in iio_map_array_unregister() Signed-off-by: Lothar Waßmann Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/inkern.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c index de2c8ea64965..ef07a02bf542 100644 --- a/drivers/staging/iio/inkern.c +++ b/drivers/staging/iio/inkern.c @@ -82,6 +82,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev, ret = -ENODEV; goto error_ret; } + i++; } error_ret: mutex_unlock(&iio_map_list_lock); From 401c90e56c48b1c642507a8bec91b7ae21f1156e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 24 Mar 2012 23:39:18 +0100 Subject: [PATCH 125/438] staging/media/as102: Don't call release_firmware() on uninitialized variable If, in drivers/staging/media/as102/as102_fw.c::as102_fw_upload(), the call cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL); should fail and return NULL so that we jump to the 'error:' label, then we'll end up calling 'release_firmware(firmware);' with 'firmware' still uninitialized - not good. The easy fix is to just initialize 'firmware' to NULL when we declare it, since release_firmware() deals gracefully with being passed NULL pointers. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/as102/as102_fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index 43ebc43e6b9a..1075fb1df0d9 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -165,7 +165,7 @@ error: int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) { int errno = -EFAULT; - const struct firmware *firmware; + const struct firmware *firmware = NULL; unsigned char *cmd_buf = NULL; char *fw1, *fw2; struct usb_device *dev = bus_adap->usb_dev; From 4ca5218e3939685c2325fc0a0a1ac8150272c93f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Mar 2012 09:43:54 +0300 Subject: [PATCH 126/438] Staging: vt6655-6: check keysize before memcpy() We need to check the we don't copy too much memory. This comes from a copy_from_user() in the ioctl. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/key.c | 3 +++ drivers/staging/vt6656/key.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 0ff8d7bbf2a7..774b0d4a7e06 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -655,6 +655,9 @@ bool KeybSetDefaultKey ( return (false); } + if (uKeyLength > MAX_KEY_LEN) + return false; + pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true; for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 27bb523c8a97..ee62a06a75f4 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -684,6 +684,9 @@ BOOL KeybSetDefaultKey( return (FALSE); } + if (uKeyLength > MAX_KEY_LEN) + return false; + pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE; for (ii = 0; ii < ETH_ALEN; ii++) pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; From 0d05568ac79bfc595f1eadc3e0fd7a20a45f7b69 Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 27 Mar 2012 16:43:11 +0800 Subject: [PATCH 127/438] staging:rts_pstor:Fix possible panic by NULL pointer dereference rtsx_transport.c (rtsx_transfer_sglist_adma_partial): pointer struct scatterlist *sg, which is mapped in dma_map_sg, is used as an iterator in later transfer operation. It is corrupted and passed to dma_unmap_sg, thus causing fatal unmap of some erroneous address. Fix it by duplicating *sg_ptr for iterating. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx_transport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index 4e3d2c106af0..9b2e5c99870f 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -335,6 +335,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, int sg_cnt, i, resid; int err = 0; long timeleft; + struct scatterlist *sg_ptr; u32 val = TRIG_DMA; if ((sg == NULL) || (num_sg <= 0) || !offset || !index) @@ -371,7 +372,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); resid = size; - + sg_ptr = sg; chip->sgi = 0; /* Usually the next entry will be @sg@ + 1, but if this sg element * is part of a chained scatterlist, it could jump to the start of @@ -379,14 +380,14 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, * the proper sg */ for (i = 0; i < *index; i++) - sg = sg_next(sg); + sg_ptr = sg_next(sg_ptr); for (i = *index; i < sg_cnt; i++) { dma_addr_t addr; unsigned int len; u8 option; - addr = sg_dma_address(sg); - len = sg_dma_len(sg); + addr = sg_dma_address(sg_ptr); + len = sg_dma_len(sg_ptr); RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len); @@ -415,7 +416,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if (!resid) break; - sg = sg_next(sg); + sg_ptr = sg_next(sg_ptr); } RTSX_DEBUGP("SG table count = %d\n", chip->sgi); From b5bd70a162492a76ee49065605ca15d484bb623a Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 27 Mar 2012 16:43:20 +0800 Subject: [PATCH 128/438] staging:rts_pstor:Avoid "Bad target number" message when probing driver Avoid "Bad LUN" and "Bad target number" message by setting the supported max_lun and max_id for the scsi host Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index a7feb3e328a0..1dccd933a7e4 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -1000,6 +1000,11 @@ static int __devinit rtsx_probe(struct pci_dev *pci, rtsx_init_chip(dev->chip); + /* set the supported max_lun and max_id for the scsi host + * NOTE: the minimal value of max_id is 1 */ + host->max_id = 1; + host->max_lun = dev->chip->max_lun; + /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { From 678b7c17073a9e383f204c3e8e0000821afb6103 Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Thu, 29 Mar 2012 12:09:45 +0000 Subject: [PATCH 129/438] staging: ozwpan: Added new maintainer for ozwpan Added Rupesh Gujare to MAINTAINERS file and contact in TODO file for ozwpan driver. Signed-off-by: Chris Kelly Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + drivers/staging/ozwpan/TODO | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2dcfca850639..d87ad1844b4f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6466,6 +6466,7 @@ S: Odd Fixes F: drivers/staging/olpc_dcon/ STAGING - OZMO DEVICES USB OVER WIFI DRIVER +M: Rupesh Gujare M: Chris Kelly S: Maintained F: drivers/staging/ozwpan/ diff --git a/drivers/staging/ozwpan/TODO b/drivers/staging/ozwpan/TODO index f7a9c122f596..c2d30a7112f3 100644 --- a/drivers/staging/ozwpan/TODO +++ b/drivers/staging/ozwpan/TODO @@ -8,5 +8,7 @@ TODO: - code review by USB developer community. - testing with as many devices as possible. -Please send any patches for this driver to Chris Kelly +Please send any patches for this driver to +Rupesh Gujare +Chris Kelly and Greg Kroah-Hartman . From 3fd654c22c7b002e8681accaed50a6d46656d815 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Mar 2012 21:52:57 +0300 Subject: [PATCH 130/438] Staging: rts_pstor: off by one in for loop I already fixed the other similar for loop in this file. I'm not sure how I missed this one. We use seg_no+1 inside the loop so we can't go right up to the end of the loop. Also if we don't break out of the loop then we end up past the end of the array, but with this fix we end up on the last element. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/ms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 66341dff8c99..f9a4498984cc 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -3498,7 +3498,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 log_blk++; - for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; + seg_no++) { if (log_blk < ms_start_idx[seg_no+1]) break; } From f4477e90b3ea4c40466e8f418cf41a17aef09192 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Mon, 2 Apr 2012 09:13:56 -0500 Subject: [PATCH 131/438] staging: zsmalloc: fix memory leak This patch fixes a memory leak in zsmalloc where the first subpage of each zspage is leaked when the zspage is freed. Signed-off-by: Nitin Gupta Acked-by: Seth Jennings Acked-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zsmalloc/zsmalloc-main.c | 30 ++++++++++++++---------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 09caa4f2687e..917461c66014 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -267,33 +267,39 @@ static unsigned long obj_idx_to_offset(struct page *page, return off + obj_idx * class_size; } +static void reset_page(struct page *page) +{ + clear_bit(PG_private, &page->flags); + clear_bit(PG_private_2, &page->flags); + set_page_private(page, 0); + page->mapping = NULL; + page->freelist = NULL; + reset_page_mapcount(page); +} + static void free_zspage(struct page *first_page) { - struct page *nextp, *tmp; + struct page *nextp, *tmp, *head_extra; BUG_ON(!is_first_page(first_page)); BUG_ON(first_page->inuse); - nextp = (struct page *)page_private(first_page); + head_extra = (struct page *)page_private(first_page); - clear_bit(PG_private, &first_page->flags); - clear_bit(PG_private_2, &first_page->flags); - set_page_private(first_page, 0); - first_page->mapping = NULL; - first_page->freelist = NULL; - reset_page_mapcount(first_page); + reset_page(first_page); __free_page(first_page); /* zspage with only 1 system page */ - if (!nextp) + if (!head_extra) return; - list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) { + list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) { list_del(&nextp->lru); - clear_bit(PG_private_2, &nextp->flags); - nextp->index = 0; + reset_page(nextp); __free_page(nextp); } + reset_page(head_extra); + __free_page(head_extra); } /* Initialize a newly allocated zspage */ From be0775ac140dd80a1d60fb7e71ec60e649c14ff8 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 5 Apr 2012 10:34:56 -0500 Subject: [PATCH 132/438] staging: drm/omap: move where DMM driver is registered Not sure what triggered the change in behavior, but seems to result in recursively acquiring a mutex and hanging on boot. But omap_drm_init() seems a much more sane place to register the driver for the DMM sub-device. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 3df5b4c58ecd..620b8d54223d 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -803,9 +803,6 @@ static void pdev_shutdown(struct platform_device *device) static int pdev_probe(struct platform_device *device) { DBG("%s", device->name); - if (platform_driver_register(&omap_dmm_driver)) - dev_err(&device->dev, "DMM registration failed\n"); - return drm_platform_init(&omap_drm_driver, device); } @@ -833,6 +830,10 @@ struct platform_driver pdev = { static int __init omap_drm_init(void) { DBG("init"); + if (platform_driver_register(&omap_dmm_driver)) { + /* we can continue on without DMM.. so not fatal */ + dev_err(NULL, "DMM registration failed\n"); + } return platform_driver_register(&pdev); } From 40f32d9345bee0b24d3317b498e79b02e4be27f4 Mon Sep 17 00:00:00 2001 From: Preetham Chandru Date: Mon, 9 Apr 2012 18:05:01 +0530 Subject: [PATCH 133/438] staging: iio: ak8975: Remove i2c client data corruption i2c client data set is of type struct indio_dev pointer and hence the pointer returned from i2c_get_clientdata() should be assigned to an object of type struct indio_dev and not to an object of type struct ak8975_data. Also in ak8975_probe() client data should be set first before calling ak8975_setup() as it references the client data. Signed-off-by: Preetham Chandru R CC: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index d5ddac3d8831..ebc2d0840caf 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -108,7 +108,8 @@ static const int ak8975_index_to_reg[] = { static int ak8975_write_data(struct i2c_client *client, u8 reg, u8 val, u8 mask, u8 shift) { - struct ak8975_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ak8975_data *data = iio_priv(indio_dev); u8 regval; int ret; @@ -159,7 +160,8 @@ static int ak8975_read_data(struct i2c_client *client, */ static int ak8975_setup(struct i2c_client *client) { - struct ak8975_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ak8975_data *data = iio_priv(indio_dev); u8 device_id; int ret; @@ -509,6 +511,7 @@ static int ak8975_probe(struct i2c_client *client, goto exit_gpio; } data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); /* Perform some basic start-of-day setup of the device. */ err = ak8975_setup(client); if (err < 0) { @@ -516,7 +519,6 @@ static int ak8975_probe(struct i2c_client *client, goto exit_free_iio; } - i2c_set_clientdata(client, indio_dev); data->client = client; mutex_init(&data->lock); data->eoc_irq = client->irq; From 099f5d01a6f73712e17552679aa724e021809a6e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 21 Mar 2012 10:18:33 -0700 Subject: [PATCH 134/438] android: make persistent_ram based drivers depend on HAVE_MEMBLOCK m68k doesn't have memblock_reserve, which causes a build failure with allmodconfig. Make PERSISTENT_RAM and RAM_CONSOLE depend on HAVE_MEMBLOCK. Reported-by: Geert Uytterhoeven Reported-by: Paul Gortmaker Signed-off-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 08a3b1133d29..eb1dee26bda3 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -27,13 +27,14 @@ config ANDROID_LOGGER config ANDROID_PERSISTENT_RAM bool + depends on HAVE_MEMBLOCK select REED_SOLOMON select REED_SOLOMON_ENC8 select REED_SOLOMON_DEC8 config ANDROID_RAM_CONSOLE bool "Android RAM buffer console" - depends on !S390 && !UML + depends on !S390 && !UML && HAVE_MEMBLOCK select ANDROID_PERSISTENT_RAM default n From 5d92f71e687e4e1a0bed489707d1ec58fe1100de Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 21 Mar 2012 09:24:57 +0800 Subject: [PATCH 135/438] Staging: android: timed_gpio: Fix resource leak in timed_gpio_probe error paths If gpio_request fails, we need to free all allocated resources. Current code uses wrong array index to access gpio_data array. So current code actually frees gpio_data[i].gpio by j times. This patch moves the error handling code to err_out and thus improves readability. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/timed_gpio.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index bc723eff11af..45c522cbe784 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -85,7 +85,7 @@ static int timed_gpio_probe(struct platform_device *pdev) struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; struct timed_gpio *cur_gpio; struct timed_gpio_data *gpio_data, *gpio_dat; - int i, j, ret = 0; + int i, ret; if (!pdata) return -EBUSY; @@ -108,18 +108,12 @@ static int timed_gpio_probe(struct platform_device *pdev) gpio_dat->dev.get_time = gpio_get_time; gpio_dat->dev.enable = gpio_enable; ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret >= 0) { - ret = timed_output_dev_register(&gpio_dat->dev); - if (ret < 0) - gpio_free(cur_gpio->gpio); - } + if (ret < 0) + goto err_out; + ret = timed_output_dev_register(&gpio_dat->dev); if (ret < 0) { - for (j = 0; j < i; j++) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - kfree(gpio_data); - return ret; + gpio_free(cur_gpio->gpio); + goto err_out; } gpio_dat->gpio = cur_gpio->gpio; @@ -131,6 +125,15 @@ static int timed_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio_data); return 0; + +err_out: + while (--i >= 0) { + timed_output_dev_unregister(&gpio_data[i].dev); + gpio_free(gpio_data[i].gpio); + } + kfree(gpio_data); + + return ret; } static int timed_gpio_remove(struct platform_device *pdev) From 6490311f423b0d77969d6fa2ab6354b87e373bf9 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 19 Mar 2012 21:50:09 +0400 Subject: [PATCH 136/438] staging/xgifb: fix display on XGI Volari Z11m cards Image on Z11m cards was totally garbled due to wrong memory being selected. Add a special handling for Z11m cards. Tested on PCIe Z11 and Z11m cards. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 2 +- drivers/staging/xgifb/vb_setmode.c | 7 +++++++ drivers/staging/xgifb/vb_table.h | 11 ++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 94d5c35e22fb..3650bbff7686 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -61,7 +61,7 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, } temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if ((temp & 0x88) == 0x80) + if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) data = 0; /* DDR */ else data = 1; /* DDRII */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2919924213c4..60d4adf99923 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -152,6 +152,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pXGINew_CR97 = &XG20_CR97; if (ChipType == XG27) { + unsigned char temp; pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; @@ -162,7 +163,13 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pCRDE = XG27_CRDE; pVBInfo->pSR40 = &XG27_SR40; pVBInfo->pSR41 = &XG27_SR41; + pVBInfo->SR15 = XG27_SR13; + /*Z11m DDR*/ + temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); + /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ + if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) + pVBInfo->pXGINew_CR97 = &Z11m_CR97; } if (ChipType >= XG20) { diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index dddf261ed53d..e8d6f674b274 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -33,6 +33,13 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = { {0x5c, 0x23, 0x01, 166} }; +static unsigned char XG27_SR13[4][8] = { + {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ + {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ + {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */ + {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */ +}; + static unsigned char XGI340_SR13[4][8] = { {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ @@ -71,7 +78,7 @@ static unsigned char XGI27_cr41[24][8] = { {0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */ - {0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], + {0xB3, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], CR99[2:0], CR45[3:0]*/ {0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */ @@ -2803,6 +2810,8 @@ static unsigned char XG27_CRDE[2]; static unsigned char XG27_SR40 = 0x04 ; static unsigned char XG27_SR41 = 0x00 ; +static unsigned char Z11m_CR97 = 0x80 ; + static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ From 3ffc9cebb65f6942cd912e33e60e1f09e497e208 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 28 Mar 2012 14:55:04 -0600 Subject: [PATCH 137/438] gpio/sodaville: Convert sodaville driver to new irqdomain API The irqdomain api changed significantly in v3.4 which caused a build failure for this driver. Signed-off-by: Grant Likely Acked-by: Sebastian Andrzej Siewior Cc: Hans J. Koch Cc: Torben Hohn --- drivers/gpio/Kconfig | 2 +- drivers/gpio/gpio-sodaville.c | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index edadbdad31d0..e03653d69357 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -430,7 +430,7 @@ config GPIO_ML_IOH config GPIO_SODAVILLE bool "Intel Sodaville GPIO support" - depends on X86 && PCI && OF && BROKEN + depends on X86 && PCI && OF select GPIO_GENERIC select GENERIC_IRQ_CHIP help diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index 9ba15d31d242..031e5d24837d 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c @@ -41,7 +41,7 @@ struct sdv_gpio_chip_data { int irq_base; void __iomem *gpio_pub_base; - struct irq_domain id; + struct irq_domain *id; struct irq_chip_generic *gc; struct bgpio_chip bgpio; }; @@ -51,10 +51,9 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct sdv_gpio_chip_data *sd = gc->private; void __iomem *type_reg; - u32 irq_offs = d->irq - sd->irq_base; u32 reg; - if (irq_offs < 8) + if (d->hwirq < 8) type_reg = sd->gpio_pub_base + GPIT1R0; else type_reg = sd->gpio_pub_base + GPIT1R1; @@ -63,11 +62,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) switch (type) { case IRQ_TYPE_LEVEL_HIGH: - reg &= ~BIT(4 * (irq_offs % 8)); + reg &= ~BIT(4 * (d->hwirq % 8)); break; case IRQ_TYPE_LEVEL_LOW: - reg |= BIT(4 * (irq_offs % 8)); + reg |= BIT(4 * (d->hwirq % 8)); break; default: @@ -91,7 +90,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) u32 irq_bit = __fls(irq_stat); irq_stat &= ~BIT(irq_bit); - generic_handle_irq(sd->irq_base + irq_bit); + generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); } return IRQ_HANDLED; @@ -127,7 +126,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node, } static struct irq_domain_ops irq_domain_sdv_ops = { - .dt_translate = sdv_xlate, + .xlate = sdv_xlate, }; static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, @@ -149,10 +148,6 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, if (ret) goto out_free_desc; - sd->id.irq_base = sd->irq_base; - sd->id.of_node = of_node_get(pdev->dev.of_node); - sd->id.ops = &irq_domain_sdv_ops; - /* * This gpio irq controller latches level irqs. Testing shows that if * we unmask & ACK the IRQ before the source of the interrupt is gone @@ -179,7 +174,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); - irq_domain_add(&sd->id); + sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, + sd->irq_base, 0, &irq_domain_sdv_ops, sd); + if (!sd->id) + goto out_free_irq; return 0; out_free_irq: free_irq(pdev->irq, sd); @@ -260,7 +258,6 @@ static void sdv_gpio_remove(struct pci_dev *pdev) { struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); - irq_domain_del(&sd->id); free_irq(pdev->irq, sd); irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); From 078dc65e61c562e289685fe43b5ef58118e033fc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 6 Apr 2012 20:37:43 +0800 Subject: [PATCH 138/438] gpio: Fix uninitialized variable bit in adp5588_irq_handler The variable 'bit' is uninitialized in the first iteration of for loop. Fix it. Signed-off-by: Axel Lin Signed-off-by: Grant Likely --- drivers/gpio/gpio-adp5588.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index 9ad1703d1408..ae5d7f12ce66 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c @@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid) if (ret < 0) memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); - for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); + for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); bank++, bit = 0) { pending = dev->irq_stat[bank] & dev->irq_mask[bank]; From 6270d830d030da48eddffbe31ed1e4444f203fc5 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Wed, 4 Apr 2012 02:02:58 +0200 Subject: [PATCH 139/438] gpio: Fix range check in of_gpio_simple_xlate() of_gpio_simple_xlate() has an off-by-one bug where it checks to see if args[0] is > ngpio instead of >=. args[0] must always be less than ngpio because it is a zero-based enumeration. Signed-off-by: Roland Stigge [grant.likely: beef up commit text] Signed-off-by: Grant Likely --- drivers/of/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index bba81216b4db..bf984b6dc477 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -140,7 +140,7 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) return -EINVAL; - if (gpiospec->args[0] > gc->ngpio) + if (gpiospec->args[0] >= gc->ngpio) return -EINVAL; if (flags) From a65a6f14dc24a90bde3f5d0073ba2364476200bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 20 Mar 2012 16:59:33 +0100 Subject: [PATCH 140/438] USB: serial: fix race between probe and open Fix race between probe and open by making sure that the disconnected flag is not cleared until all ports have been registered. A call to tty_open while probe is running may get a reference to the serial structure in serial_install before its ports have been registered. This may lead to usb_serial_core calling driver open before port is fully initialised. With ftdi_sio this result in the following NULL-pointer dereference as the private data has not been initialised at open: [ 199.698286] IP: [] ftdi_open+0x59/0xe0 [ftdi_sio] [ 199.698297] *pde = 00000000 [ 199.698303] Oops: 0000 [#1] PREEMPT SMP [ 199.698313] Modules linked in: ftdi_sio usbserial [ 199.698323] [ 199.698327] Pid: 1146, comm: ftdi_open Not tainted 3.2.11 #70 Dell Inc. Vostro 1520/0T816J [ 199.698339] EIP: 0060:[] EFLAGS: 00010286 CPU: 0 [ 199.698344] EIP is at ftdi_open+0x59/0xe0 [ftdi_sio] [ 199.698348] EAX: 0000003e EBX: f5067000 ECX: 00000000 EDX: 80000600 [ 199.698352] ESI: f48d8800 EDI: 00000001 EBP: f515dd54 ESP: f515dcfc [ 199.698356] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 199.698361] Process ftdi_open (pid: 1146, ti=f515c000 task=f481e040 task.ti=f515c000) [ 199.698364] Stack: [ 199.698368] f811a9fe f811a9e0 f811b3ef 00000000 00000000 00001388 00000000 f4a86800 [ 199.698387] 00000002 00000000 f806e68e 00000000 f532765c f481e040 00000246 22222222 [ 199.698479] 22222222 22222222 22222222 f5067004 f5327600 f5327638 f515dd74 f806e6ab [ 199.698496] Call Trace: [ 199.698504] [] ? serial_activate+0x2e/0x70 [usbserial] [ 199.698511] [] serial_activate+0x4b/0x70 [usbserial] [ 199.698521] [] tty_port_open+0x7c/0xd0 [ 199.698527] [] ? serial_set_termios+0xa0/0xa0 [usbserial] [ 199.698534] [] serial_open+0x2f/0x70 [usbserial] [ 199.698540] [] tty_open+0x20c/0x510 [ 199.698546] [] chrdev_open+0xe7/0x230 [ 199.698553] [] __dentry_open+0x1f2/0x390 [ 199.698559] [] ? _raw_spin_unlock+0x2c/0x50 [ 199.698565] [] nameidata_to_filp+0x66/0x80 [ 199.698570] [] ? cdev_put+0x20/0x20 [ 199.698576] [] do_last+0x198/0x730 [ 199.698581] [] path_openat+0xa0/0x350 [ 199.698587] [] do_filp_open+0x35/0x80 [ 199.698593] [] ? _raw_spin_unlock+0x2c/0x50 [ 199.698599] [] ? alloc_fd+0xc0/0x100 [ 199.698605] [] ? getname_flags+0x72/0x120 [ 199.698611] [] do_sys_open+0xf0/0x1c0 [ 199.698617] [] ? trace_hardirqs_on_thunk+0xc/0x10 [ 199.698623] [] sys_open+0x2e/0x40 [ 199.698628] [] sysenter_do_call+0x12/0x36 [ 199.698632] Code: 85 89 00 00 00 8b 16 8b 4d c0 c1 e2 08 c7 44 24 14 88 13 00 00 81 ca 00 00 00 80 c7 44 24 10 00 00 00 00 c7 44 24 0c 00 00 00 00 <0f> b7 41 78 31 c9 89 44 24 08 c7 44 24 04 00 00 00 00 c7 04 24 [ 199.698884] EIP: [] ftdi_open+0x59/0xe0 [ftdi_sio] SS:ESP 0068:f515dcfc [ 199.698893] CR2: 0000000000000078 [ 199.698925] ---[ end trace 77c43ec023940cff ]--- Reported-and-tested-by: Ken Huang Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 5413bd500781..97355a15bbea 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface, serial->attached = 1; } + /* Avoid race with tty_open and serial_install by setting the + * disconnected flag and not clearing it until all ports have been + * registered. + */ + serial->disconnected = 1; + if (get_free_serial(serial, num_ports, &minor) == NULL) { dev_err(&interface->dev, "No more free serial devices\n"); goto probe_error; @@ -1078,6 +1084,8 @@ int usb_serial_probe(struct usb_interface *interface, "continuing\n"); } + serial->disconnected = 0; + usb_serial_console_init(debug, minor); exit: From 5631f2c18f4b2845b3e97df1c659c5094a17605f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Tue, 3 Apr 2012 09:59:48 +0200 Subject: [PATCH 141/438] sysfs: Prevent crash on unset sysfs group attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not let the kernel crash when a device is registered with sysfs while group attributes are not set (aka NULL). Warn about the offender with some information about the offending device. This would warn instead of trying NULL pointer deref like: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] internal_create_group+0x83/0x1a0 PGD 0 Oops: 0000 [#1] SMP CPU 0 Modules linked in: Pid: 1, comm: swapper/0 Not tainted 3.4.0-rc1-x86_64 #3 HP ProLiant DL360 G4 RIP: 0010:[] [] internal_create_group+0x83/0x1a0 RSP: 0018:ffff88019485fd70 EFLAGS: 00010202 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000001 RDX: ffff880192e99908 RSI: ffff880192e99630 RDI: ffffffff81a26c60 RBP: ffff88019485fdc0 R08: 0000000000000000 R09: 0000000000000000 R10: ffff880192e99908 R11: 0000000000000000 R12: ffffffff81a16a00 R13: ffff880192e99908 R14: ffffffff81a16900 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88019bc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001a0c000 CR4: 00000000000007f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process swapper/0 (pid: 1, threadinfo ffff88019485e000, task ffff880194878000) Stack: ffff88019485fdd0 ffff880192da9d60 0000000000000000 ffff880192e99908 ffff880192e995d8 0000000000000001 ffffffff81a16a00 ffff880192da9d60 0000000000000000 0000000000000000 ffff88019485fdd0 ffffffff811527be Call Trace: [] sysfs_create_group+0xe/0x10 [] device_add_groups+0x46/0x80 [] device_add+0x46d/0x6a0 ... Signed-off-by: Bruno Prémont Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index dd1701caecc9..2df555c66d57 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -67,7 +67,11 @@ static int internal_create_group(struct kobject *kobj, int update, /* Updates may happen before the object has been instantiated */ if (unlikely(update && !kobj->sd)) return -EINVAL; - + if (!grp->attrs) { + WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n", + kobj->name, grp->name ? "" : grp->name); + return -EINVAL; + } if (grp->name) { error = sysfs_create_subdir(kobj, grp->name, &sd); if (error) From 3a198886ab5f228fcbebb9ace803d8b99721d49a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2012 13:41:06 -0700 Subject: [PATCH 142/438] sysfs: handle 'parent deleted before child added' In scsi at least two cases of the parent device being deleted before the child is added have been observed. 1/ scsi is performing async scans and the device is removed prior to the async can thread running (can happen with an in-opportune / unlikely unplug during initial scan). 2/ libsas discovery event running after the parent port has been torn down (this is a bug in libsas). Result in crash signatures like: BUG: unable to handle kernel NULL pointer dereference at 0000000000000098 IP: [] sysfs_create_dir+0x32/0xb6 ... Process scsi_scan_8 (pid: 5417, threadinfo ffff88080bd16000, task ffff880801b8a0b0) Stack: 00000000fffffffe ffff880813470628 ffff88080bd17cd0 ffff88080614b7e8 ffff88080b45c108 00000000fffffffe ffff88080bd17d20 ffffffff8125e4a8 ffff88080bd17cf0 ffffffff81075149 ffff88080bd17d30 ffff88080614b7e8 Call Trace: [] kobject_add_internal+0x120/0x1e3 [] ? trace_hardirqs_on+0xd/0xf [] kobject_add_varg+0x41/0x50 [] kobject_add+0x64/0x66 [] device_add+0x12d/0x63a In this scenario the parent is still valid (because we have a reference), but it has been device_del()'d which means its kobj->sd pointer is NULL'd via: device_del()->kobject_del()->sysfs_remove_dir() ...and then sysfs_create_dir() (without this fix) goes ahead and de-references parent_sd via sysfs_ns_type(): return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT; This scenario is being fixed in scsi/libsas, but if other subsystems present the same ordering the system need not immediately crash. Cc: Greg Kroah-Hartman Cc: James Bottomley Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/dir.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 8ddc1021c79a..35a36d39fa2c 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -729,6 +729,9 @@ int sysfs_create_dir(struct kobject * kobj) else parent_sd = &sysfs_root; + if (!parent_sd) + return -ENOENT; + if (sysfs_ns_type(parent_sd)) ns = kobj->ktype->namespace(kobj); type = sysfs_read_ns_type(kobj); From 282029c005e65ffdce3aa9f8220f88a8bbbc4dae Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 6 Apr 2012 13:41:15 -0700 Subject: [PATCH 143/438] kobject: provide more diagnostic info for kobject_add_internal() failures 1/ convert open-coded KERN_ERR+dump_stack() to WARN(), so that automated tools pick up this warning. 2/ include the 'child' and 'parent' kobject names. This information was useful for tracking down the case where scsi invoked device_del() on a parent object and subsequently invoked device_add() on a child. Now the warning looks like: kobject_add_internal failed for target8:0:16 (error: -2 parent: end_device-8:0:24) Pid: 2942, comm: scsi_scan_8 Not tainted 3.3.0-rc7-isci+ #2 Call Trace: [] kobject_add_internal+0x1c1/0x1f3 [] ? trace_hardirqs_on+0xd/0xf [] kobject_add_varg+0x41/0x50 [] kobject_add+0x64/0x66 [] device_add+0x12d/0x63a [] ? kobject_put+0x4c/0x50 [] scsi_sysfs_add_sdev+0x4e/0x28a [] do_scan_async+0x9c/0x145 Cc: Greg Kroah-Hartman Cc: James Bottomley Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index 21dee7c19afd..aeefa8bc8b1c 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -192,14 +192,14 @@ static int kobject_add_internal(struct kobject *kobj) /* be noisy on error issues */ if (error == -EEXIST) - printk(KERN_ERR "%s failed for %s with " - "-EEXIST, don't try to register things with " - "the same name in the same directory.\n", - __func__, kobject_name(kobj)); + WARN(1, "%s failed for %s with " + "-EEXIST, don't try to register things with " + "the same name in the same directory.\n", + __func__, kobject_name(kobj)); else - printk(KERN_ERR "%s failed for %s (%d)\n", - __func__, kobject_name(kobj), error); - dump_stack(); + WARN(1, "%s failed for %s (error: %d parent: %s)\n", + __func__, kobject_name(kobj), error, + parent ? kobject_name(parent) : "'none'"); } else kobj->state_in_sysfs = 1; From bb334e90cc3a2913906665ea966abd7f462b67c2 Mon Sep 17 00:00:00 2001 From: Alex He Date: Thu, 22 Mar 2012 15:06:59 +0800 Subject: [PATCH 144/438] xHCI: correct to print the true HSEE of USBCMD Correct the print of HSEE of USBCMD in xhci-dbg.c. Signed-off-by: Alex He Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index e9b0f043455d..4b436f5a4171 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci) xhci_dbg(xhci, " Event Interrupts %s\n", (temp & CMD_EIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " Host System Error Interrupts %s\n", - (temp & CMD_EIE) ? "enabled " : "disabled"); + (temp & CMD_HSEIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " HC has %sfinished light reset\n", (temp & CMD_LRESET) ? "not " : ""); } From a46c46a1d752756ba159dd454b746a3fb735c4f5 Mon Sep 17 00:00:00 2001 From: Gerard Snitselaar Date: Fri, 16 Mar 2012 11:34:11 -0700 Subject: [PATCH 145/438] usb: xhci: fix section mismatch in linux-next xhci_unregister_pci() is called in xhci_hcd_init(). Signed-off-by: Gerard Snitselaar Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index ef98b38626fb..0d7b85135965 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -326,7 +326,7 @@ int __init xhci_register_pci(void) return pci_register_driver(&xhci_pci_driver); } -void __exit xhci_unregister_pci(void) +void xhci_unregister_pci(void) { pci_unregister_driver(&xhci_pci_driver); } From 9a5c7d6eb9b8cc9fa1c7169ecfd96c9e267c0452 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 3 Apr 2012 14:12:55 +0530 Subject: [PATCH 146/438] gpio/exynos: Fix compiler warning in gpio-samsung.c file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following warning when "SAMSUNG EXYNOS5" is not selected: warning: ‘exynos5_gpios_1’ defined but not used [-Wunused-variable] warning: ‘exynos5_gpios_2’ defined but not used [-Wunused-variable] warning: ‘exynos5_gpios_3’ defined but not used [-Wunused-variable] warning: ‘exynos5_gpios_4’ defined but not used [-Wunused-variable] Signed-off-by: Sachin Kamat Signed-off-by: Grant Likely --- drivers/gpio/gpio-samsung.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 46277877b7ec..19d6fc0229c3 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -2382,8 +2382,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { #endif }; -static struct samsung_gpio_chip exynos5_gpios_1[] = { #ifdef CONFIG_ARCH_EXYNOS5 +static struct samsung_gpio_chip exynos5_gpios_1[] = { { .chip = { .base = EXYNOS5_GPA0(0), @@ -2541,11 +2541,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { .to_irq = samsung_gpiolib_to_irq, }, }, -#endif }; +#endif -static struct samsung_gpio_chip exynos5_gpios_2[] = { #ifdef CONFIG_ARCH_EXYNOS5 +static struct samsung_gpio_chip exynos5_gpios_2[] = { { .chip = { .base = EXYNOS5_GPE0(0), @@ -2602,11 +2602,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = { }, }, -#endif }; +#endif -static struct samsung_gpio_chip exynos5_gpios_3[] = { #ifdef CONFIG_ARCH_EXYNOS5 +static struct samsung_gpio_chip exynos5_gpios_3[] = { { .chip = { .base = EXYNOS5_GPV0(0), @@ -2638,11 +2638,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = { .label = "GPV4", }, }, -#endif }; +#endif -static struct samsung_gpio_chip exynos5_gpios_4[] = { #ifdef CONFIG_ARCH_EXYNOS5 +static struct samsung_gpio_chip exynos5_gpios_4[] = { { .chip = { .base = EXYNOS5_GPZ(0), @@ -2650,8 +2650,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = { .label = "GPZ", }, }, -#endif }; +#endif #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) From 39ec0d38141b198f94fd19c2bb10fd7c616510d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Tue, 3 Apr 2012 15:03:44 +0200 Subject: [PATCH 147/438] spi/imx: prevent NULL pointer dereference in spi_imx_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When no platform_data is present and either 'spi-num-chipselects' is not defined in the DT or 'cs-gpios' has less entries than 'spi-num-chipselects' specifies, the NULL platform_data pointer is being dereferenced. Signed-off-by: Lothar Waßmann Signed-off-by: Grant Likely --- drivers/spi/spi-imx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 373f4fff9358..570f22053be8 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -766,8 +766,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) } ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs); - if (ret < 0) - num_cs = mxc_platform_info->num_chipselect; + if (ret < 0) { + if (mxc_platform_info) + num_cs = mxc_platform_info->num_chipselect; + else + return ret; + } master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data) + sizeof(int) * num_cs); @@ -784,7 +788,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) for (i = 0; i < master->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); - if (cs_gpio < 0) + if (cs_gpio < 0 && mxc_platform_info) cs_gpio = mxc_platform_info->chipselect[i]; spi_imx->chipselect[i] = cs_gpio; From 89e004e78ff6317520d35bdb0d0174893ab49f17 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Thu, 5 Apr 2012 17:07:23 +0800 Subject: [PATCH 148/438] pinctrl: fix compile error if not select PINMUX support The pinctrl_register_mappings is defined in core.c, so change the dependent macro from CONFIG_MUX to CONFIG_PINCTRL. The compile error message is: drivers/pinctrl/core.c:886: error: redefinition of 'pinctrl_register_mappings' include/linux/pinctrl/machine.h:160: note: previous definition of 'pinctrl_register_mappings' was here make[2]: *** [drivers/pinctrl/core.o] Error 1 make[1]: *** [drivers/pinctrl] Error 2 make: *** [drivers] Error 2 Acked-by: Stephen Warren Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index fee4349364f7..d32eb8ccba84 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -148,7 +148,7 @@ struct pinctrl_map { #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) -#ifdef CONFIG_PINMUX +#ifdef CONFIG_PINCTRL extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); From 6f11f6f1a0a717eb8bd0dadd101c4522b945c501 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 16 Mar 2012 14:54:23 -0600 Subject: [PATCH 149/438] pinctrl: include to prevent compile errors Macros in call ARRAY_SIZE(), the definition of which eventually calls BUILD_BUG_ON_ZERO(), which is defined in . Include that so that every .c file using the pinctrl macros doesn't have to do that itself. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index d32eb8ccba84..e4d1de742502 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,6 +12,8 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H +#include + #include "pinctrl-state.h" enum pinctrl_map_type { From f84cc342b1999db11ece939e1d2bf0743eb4578b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 16 Mar 2012 14:54:25 -0600 Subject: [PATCH 150/438] pinctrl: implement pinctrl_check_ops Most code assumes that the pinctrl ops are present. Validate this when registering a pinctrl driver. Remove the one place in the code that was checking whether one of these non-optional ops was present. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index ec3b8cc188af..df6296c5f47b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -908,10 +908,6 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned selector = 0; - /* No grouping */ - if (!ops) - return 0; - mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); @@ -1225,6 +1221,19 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) #endif +static int pinctrl_check_ops(struct pinctrl_dev *pctldev) +{ + const struct pinctrl_ops *ops = pctldev->desc->pctlops; + + if (!ops || + !ops->list_groups || + !ops->get_group_name || + !ops->get_group_pins) + return -EINVAL; + + return 0; +} + /** * pinctrl_register() - register a pin controller device * @pctldesc: descriptor for this pin controller @@ -1256,6 +1265,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, INIT_LIST_HEAD(&pctldev->gpio_ranges); pctldev->dev = dev; + /* check core ops for sanity */ + ret = pinctrl_check_ops(pctldev); + if (ret) { + pr_err("%s pinctrl ops lacks necessary functions\n", + pctldesc->name); + goto out_err; + } + /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { ret = pinmux_check_ops(pctldev); From 7d28e3eaa1a8e951251b942e7220f97114bd73b9 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Thu, 22 Dec 2011 09:22:56 +0100 Subject: [PATCH 151/438] ARM: ux500: wake secondary cpu via resched Wake secondary cpu via resched instead of "Unknown IPI message 0x1" Signed-off-by: Jonas Aaberg Reviewed-by: Rickard Andersson Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index d2058ef8345f..eff5842f6232 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu_logical_map(cpu)); - gic_raise_softirq(cpumask_of(cpu), 1); + smp_send_reschedule(cpu); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { From 0a2da9b2ef2ef76c09397597f260245b020e6522 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 11 Apr 2012 11:45:06 +0200 Subject: [PATCH 152/438] fuse: allow nanosecond granularity Derrik Pates reports that an utimensat with a NULL argument results in the current time being sent from the kernel with 1 second granularity. Reported-by: Derrik Pates Signed-off-by: Miklos Szeredi --- fs/fuse/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 64cf8d07393e..c9a0c972a4b2 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -947,6 +947,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_time_gran = 1; sb->s_export_op = &fuse_export_operations; file = fget(d.fd); From 912093bc7c08f59e97faed2c0269e1e5429dcd58 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Apr 2012 14:03:41 +0200 Subject: [PATCH 153/438] ALSA: hda/realtek - Add a few ALC882 model strings back Since there are still many Acer models that might not be covered by the current fixup table, let's add back a few typical model names so that user can test the fixup without recompiling. Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 4 +++- sound/pci/hda/patch_realtek.c | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index d97d992ced14..03f7897c6414 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -43,7 +43,9 @@ ALC680 ALC882/883/885/888/889 ====================== - N/A + acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G + acer-aspire-8930g Acer Aspire 8330G/6935G + acer-aspire Acer Aspire others ALC861/660 ========== diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9917e55d6f11..e7b2b839a539 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5399,6 +5399,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { {} }; +static const struct alc_model_fixup alc882_fixup_models[] = { + {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, + {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, + {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, + {} +}; + /* * BIOS auto configuration */ @@ -5439,7 +5446,8 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) goto error; - alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); + alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, + alc882_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); From cd10502b8276b0486850685383243cbd26d50c8d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 11 Apr 2012 14:28:04 +0200 Subject: [PATCH 154/438] [S390] drivers/s390/block/dasd_eckd.c: add missing dasd_sfree_request Extend some error paths to call dasd_sfree_request as done earlier in the function. The error-handling code is also moved to the end of the function. Signed-off-by: Julia Lawall Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_eckd.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index c21871a4e73d..bc2e8a7c265b 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( sector_t recid, trkid; unsigned int offs; unsigned int count, count_to_trk_end; + int ret; basedev = block->base; if (rq_data_dir(req) == READ) { @@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0); if (IS_ERR(itcw)) { - dasd_sfree_request(cqr, startdev); - return ERR_PTR(-EINVAL); + ret = -EINVAL; + goto out_error; } cqr->cpaddr = itcw_get_tcw(itcw); if (prepare_itcw(itcw, first_trk, last_trk, @@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( /* Clock not in sync and XRC is enabled. * Try again later. */ - dasd_sfree_request(cqr, startdev); - return ERR_PTR(-EAGAIN); + ret = -EAGAIN; + goto out_error; } len_to_track_end = 0; /* @@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( tidaw_flags = 0; last_tidaw = itcw_add_tidaw(itcw, tidaw_flags, dst, part_len); - if (IS_ERR(last_tidaw)) - return ERR_PTR(-EINVAL); + if (IS_ERR(last_tidaw)) { + ret = -EINVAL; + goto out_error; + } dst += part_len; } } @@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( dst = page_address(bv->bv_page) + bv->bv_offset; last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len); - if (IS_ERR(last_tidaw)) - return ERR_PTR(-EINVAL); + if (IS_ERR(last_tidaw)) { + ret = -EINVAL; + goto out_error; + } } } last_tidaw->flags |= TIDAW_FLAGS_LAST; @@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( cqr->buildclk = get_clock(); cqr->status = DASD_CQR_FILLED; return cqr; +out_error: + dasd_sfree_request(cqr, startdev); + return ERR_PTR(ret); } static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, From dae1df42f544ce3969d437dfa835169210593240 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Wed, 11 Apr 2012 14:28:05 +0200 Subject: [PATCH 155/438] [S390] s390/char/vmur.c: fix memory leak This patch is used to fix a memory leak issue in s390/char/vmur.c. A character device instance is allocated by cdev_alloc, the cdev_del will not free that space if cdev_init is applied before. Signed-off-by: Dennis Chen Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 85f4a9a5d12e..73bef0bd394c 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_urdev_put; } - cdev_init(urd->char_device, &ur_fops); + urd->char_device->ops = &ur_fops; urd->char_device->dev = MKDEV(major, minor); urd->char_device->owner = ur_fops.owner; From b785e0d06ac551f80204742682be3218158234d1 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 11 Apr 2012 14:28:06 +0200 Subject: [PATCH 156/438] [S390] kernel: Use local_irq_save() for memcpy_real() Currently in the memcpy_real() function interrupts are disabled with __arch_local_irq_stnsm(). In order to notify lockdep that interrupts are disabled, with this patch local_irq_save() is used instead. The function __arch_local_irq_stnsm() is still used for switching to real mode. Reviewed-by: Heiko Carstens Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/mm/maccess.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 7bb15fcca75e..e1335dc2b1b7 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -61,21 +61,14 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } -/* - * Copy memory in real mode (kernel to kernel) - */ -int memcpy_real(void *dest, void *src, size_t count) +static int __memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; register unsigned long _len1 asm("3") = (unsigned long) count; register unsigned long _src asm("4") = (unsigned long) src; register unsigned long _len2 asm("5") = (unsigned long) count; - unsigned long flags; int rc = -EFAULT; - if (!count) - return 0; - flags = __arch_local_irq_stnsm(0xf8UL); asm volatile ( "0: mvcle %1,%2,0x0\n" "1: jo 0b\n" @@ -86,7 +79,23 @@ int memcpy_real(void *dest, void *src, size_t count) "+d" (_len2), "=m" (*((long *) dest)) : "m" (*((long *) src)) : "cc", "memory"); - arch_local_irq_restore(flags); + return rc; +} + +/* + * Copy memory in real mode (kernel to kernel) + */ +int memcpy_real(void *dest, void *src, size_t count) +{ + unsigned long flags; + int rc; + + if (!count) + return 0; + local_irq_save(flags); + __arch_local_irq_stnsm(0xfbUL); + rc = __memcpy_real(dest, src, count); + local_irq_restore(flags); return rc; } From cd94154cc6a28dd9dc271042c1a59c08d26da886 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 11 Apr 2012 14:28:07 +0200 Subject: [PATCH 157/438] [S390] fix tlb flushing for page table pages Git commit 36409f6353fc2d7b6516e631415f938eadd92ffa "use generic RCU page-table freeing code" introduced a tlb flushing bug. Partially revert the above git commit and go back to s390 specific page table flush code. For s390 the TLB can contain three types of entries, "normal" TLB page-table entries, TLB combined region-and-segment-table (CRST) entries and real-space entries. Linux does not use real-space entries which leaves normal TLB entries and CRST entries. The CRST entries are intermediate steps in the page-table translation called translation paths. For example a 4K page access in a three-level page table setup will create two CRST TLB entries and one page-table TLB entry. The advantage of that approach is that a page access next to the previous one can reuse the CRST entries and needs just a single read from memory to create the page-table TLB entry. The disadvantage is that the TLB flushing rules are more complicated, before any page-table may be freed the TLB needs to be flushed. In short: the generic RCU page-table freeing code is incorrect for the CRST entries, in particular the check for mm_users < 2 is troublesome. This is applicable to 3.0+ kernels. Cc: Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 - arch/s390/include/asm/pgalloc.h | 3 -- arch/s390/include/asm/tlb.h | 22 +----------- arch/s390/mm/pgtable.c | 63 +++++++++++++++++++++++++++++++-- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2b7c0fbe578e..9015060919a0 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -90,7 +90,6 @@ config S390 select HAVE_KERNEL_XZ select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 - select HAVE_RCU_TABLE_FREE if SMP select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 8eef9b5b3cf4..78e3041919de 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *, unsigned long *); unsigned long *page_table_alloc(struct mm_struct *, unsigned long); void page_table_free(struct mm_struct *, unsigned long *); -#ifdef CONFIG_HAVE_RCU_TABLE_FREE void page_table_free_rcu(struct mmu_gather *, unsigned long *); -void __tlb_remove_table(void *_table); -#endif static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index c687a2c83462..775a5eea8f9e 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -30,14 +30,10 @@ struct mmu_gather { struct mm_struct *mm; -#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; -#endif unsigned int fullmm; - unsigned int need_flush; }; -#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch { struct rcu_head rcu; unsigned int nr; @@ -49,7 +45,6 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); -#endif static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, @@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, { tlb->mm = mm; tlb->fullmm = full_mm_flush; - tlb->need_flush = 0; -#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb->batch = NULL; -#endif if (tlb->fullmm) __tlb_flush_mm(mm); } static inline void tlb_flush_mmu(struct mmu_gather *tlb) { - if (!tlb->need_flush) - return; - tlb->need_flush = 0; - __tlb_flush_mm(tlb->mm); -#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); -#endif } static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_flush_mmu(tlb); + tlb_table_flush(tlb); } /* @@ -105,10 +91,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long address) { -#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return page_table_free_rcu(tlb, (unsigned long *) pte); -#endif page_table_free(tlb->mm, (unsigned long *) pte); } @@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; -#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pmd); -#endif crst_table_free(tlb->mm, (unsigned long *) pmd); #endif } @@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; -#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pud); -#endif crst_table_free(tlb->mm, (unsigned long *) pud); #endif } diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 373adf69b01c..6e765bf00670 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -678,8 +678,6 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) } } -#ifdef CONFIG_HAVE_RCU_TABLE_FREE - static void __page_table_free_rcu(void *table, unsigned bit) { struct page *page; @@ -733,7 +731,66 @@ void __tlb_remove_table(void *_table) free_pages((unsigned long) table, ALLOC_ORDER); } -#endif +static void tlb_remove_table_smp_sync(void *arg) +{ + /* Simply deliver the interrupt */ +} + +static void tlb_remove_table_one(void *table) +{ + /* + * This isn't an RCU grace period and hence the page-tables cannot be + * assumed to be actually RCU-freed. + * + * It is however sufficient for software page-table walkers that rely + * on IRQ disabling. See the comment near struct mmu_table_batch. + */ + smp_call_function(tlb_remove_table_smp_sync, NULL, 1); + __tlb_remove_table(table); +} + +static void tlb_remove_table_rcu(struct rcu_head *head) +{ + struct mmu_table_batch *batch; + int i; + + batch = container_of(head, struct mmu_table_batch, rcu); + + for (i = 0; i < batch->nr; i++) + __tlb_remove_table(batch->tables[i]); + + free_page((unsigned long)batch); +} + +void tlb_table_flush(struct mmu_gather *tlb) +{ + struct mmu_table_batch **batch = &tlb->batch; + + if (*batch) { + __tlb_flush_mm(tlb->mm); + call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); + *batch = NULL; + } +} + +void tlb_remove_table(struct mmu_gather *tlb, void *table) +{ + struct mmu_table_batch **batch = &tlb->batch; + + if (*batch == NULL) { + *batch = (struct mmu_table_batch *) + __get_free_page(GFP_NOWAIT | __GFP_NOWARN); + if (*batch == NULL) { + __tlb_flush_mm(tlb->mm); + tlb_remove_table_one(table); + return; + } + (*batch)->nr = 0; + } + (*batch)->tables[(*batch)->nr++] = table; + if ((*batch)->nr == MAX_TABLE_BATCH) + tlb_table_flush(tlb); +} /* * switch on pgstes for its userspace process (for kvm) From ac2ac6e852716448d962033a041182cd1e2d3c01 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 11 Apr 2012 14:28:08 +0200 Subject: [PATCH 158/438] [S390] update default configuration Add TASKSTATS options, enable CRASH_DUMP, and regenerate defconfig file with "make savedefconfig". Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/defconfig | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 6cf8e26b3137..1957a9dd256d 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,8 +1,12 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y -CONFIG_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -14,16 +18,22 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y +CONFIG_NAMESPACES=y CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_EXPERT=y # CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y CONFIG_DEFAULT_DEADLINE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -34,18 +44,15 @@ CONFIG_KSM=y CONFIG_BINFMT_MISC=m CONFIG_CMM=m CONFIG_HZ_100=y -CONFIG_KEXEC=y -CONFIG_PM=y +CONFIG_CRASH_DUMP=y CONFIG_HIBERNATION=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y -CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_INET_LRO is not set CONFIG_IPV6=y -CONFIG_NET_SCTPPROBE=m CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_VLAN_8021Q=y @@ -84,15 +91,14 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y -CONFIG_ZFCP_DIF=y CONFIG_NETDEVICES=y -CONFIG_DUMMY=m CONFIG_BONDING=m +CONFIG_DUMMY=m CONFIG_EQUALIZER=m CONFIG_TUN=m -CONFIG_NET_ETHERNET=y CONFIG_VIRTIO_NET=y CONFIG_RAW_DRIVER=m +CONFIG_VIRTIO_BALLOON=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -103,27 +109,21 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_IBM_PARTITION=y -CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_RCU_TRACE=y CONFIG_KPROBES_SANITY_TEST=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_PAGEALLOC=y -# CONFIG_FTRACE is not set +CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_STRICT_DEVMEM is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m @@ -173,4 +173,3 @@ CONFIG_CRYPTO_SHA512_S390=m CONFIG_CRYPTO_DES_S390=m CONFIG_CRYPTO_AES_S390=m CONFIG_CRC7=m -CONFIG_VIRTIO_BALLOON=y From 7968ca814801b403ebd0829eda7a92e3eef23b45 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 11 Apr 2012 14:28:09 +0200 Subject: [PATCH 159/438] [S390] irq: simple coding style change Use braces for if/else/list_for_each_entry bodies if the body consists of more than a single line. Otherwise I get confused and check if there is something broken whenever I see these code snippets. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 1c2cdd59ccd0..8a22c27219dd 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -118,9 +118,10 @@ asmlinkage void do_softirq(void) "a" (__do_softirq) : "0", "1", "2", "3", "4", "5", "14", "cc", "memory" ); - } else + } else { /* We are already on the async stack. */ __do_softirq(); + } } local_irq_restore(flags); @@ -192,11 +193,12 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) + list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { if (p->code == code && p->handler == handler) { list_del_rcu(&p->entry); kfree_rcu(p, rcu); } + } spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -211,9 +213,10 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) + if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) { /* Serve timer interrupts first. */ clock_comparator_work(); + } kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; From af0ee94e541e366ee4b84c6d476c88fd633fe80a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 11 Apr 2012 14:28:10 +0200 Subject: [PATCH 160/438] [S390] cpum_cf: get rid of compile warnings Fix these: arch/s390/kernel/perf_cpum_cf.c:180:3: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'int' [-Wformat] arch/s390/kernel/perf_cpum_cf.c: In function 'cpumf_pmu_disable': arch/s390/kernel/perf_cpum_cf.c:205:3: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'int' [-Wformat] Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_cpum_cf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 46405086479c..cb019f429e88 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu) err = lcctl(cpuhw->state); if (err) { pr_err("Enabling the performance measuring unit " - "failed with rc=%lx\n", err); + "failed with rc=%x\n", err); return; } @@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu) err = lcctl(inactive); if (err) { pr_err("Disabling the performance measuring unit " - "failed with rc=%lx\n", err); + "failed with rc=%x\n", err); return; } From 37e37c20ab2dbccdc7a7fa5922e182a51adf50f6 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 11 Apr 2012 14:28:11 +0200 Subject: [PATCH 161/438] [S390] Fix stfle() lowcore protection problem The stfle() function writes into lowcore memory when stfl_fac_list is initialized with "S390_lowcore.stfl_fac_list = 0". For older compilers this triggers a lowcore exception. With newer compilers and "-OXX" compile option the bug does not show up because the "S390_lowcore.stfl_fac_list" initialization is removed by the compiler. The reason for thatis the incorrect "=m" (S390_lowcore.stfl_fac_list) constraint in the stfl inline assembly. The following shows the disassembly of the stfle() optimized code that is inlined in the lgr_info_get() function: 000000000011325c : 11325c: eb 9f f0 60 00 24 stmg %r9,%r15,96(%r15) 113262: c0 d0 00 29 0e 47 larl %r13,634ef0 113268: a7 f1 3f c0 tml %r15,16320 11326c: b9 04 00 ef lgr %r14,%r15 113270: a7 84 00 01 je 113272 113274: a7 fb ff c0 aghi %r15,-64 113278: b9 04 00 c2 lgr %r12,%r2 11327c: a7 29 00 01 lghi %r2,1 113280: e3 e0 f0 98 00 24 stg %r14,152(%r15) 113286: d7 97 c0 00 c0 00 xc 0(152,%r12),0(%r12) 11328c: c0 e5 00 28 db 4c brasl %r14,62e924 113292: b2 b1 00 00 stfl 0 To fix the problem we now clear the S390_lowcore.stfl_fac_list at startup in "head.S" for all machine types before lowcore protection is enabled. In addition to that the "=m" constraint is replaced by "+m". Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facility.h | 3 +-- arch/s390/kernel/head.S | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index 1e5b27edc0c9..2ee66a65f2d4 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -38,12 +38,11 @@ static inline void stfle(u64 *stfle_fac_list, int size) unsigned long nr; preempt_disable(); - S390_lowcore.stfl_fac_list = 0; asm volatile( " .insn s,0xb2b10000,0(0)\n" /* stfl */ "0:\n" EX_TABLE(0b, 0b) - : "=m" (S390_lowcore.stfl_fac_list)); + : "+m" (S390_lowcore.stfl_fac_list)); nr = 4; /* bytes stored by stfl */ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); if (S390_lowcore.stfl_fac_list & 0x01000000) { diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index c27a0727f930..adccd908ebc7 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -474,9 +474,9 @@ ENTRY(startup_kdump) stck __LC_LAST_UPDATE_CLOCK spt 5f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13) + xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST #ifndef CONFIG_MARCH_G5 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} - xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f From affbb420239695018941173b63bf70551ede8b93 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 11 Apr 2012 14:28:12 +0200 Subject: [PATCH 162/438] [S390] Fix compile error in swab.h The inline assembly in__arch_swab16p causes compile errors of the form: *error*: *invalid* '*asm*': operand number missing after %-*letter* The assembly uses the %O/%R notation but the first operand misses the operand number, it needs to be "%O1" instead of "%O". Reported-by: Gil Peleg Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/swab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/include/asm/swab.h b/arch/s390/include/asm/swab.h index 6bdee21c077e..a3e4ebb32090 100644 --- a/arch/s390/include/asm/swab.h +++ b/arch/s390/include/asm/swab.h @@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x) asm volatile( #ifndef __s390x__ - " icm %0,2,%O+1(%R1)\n" + " icm %0,2,%O1+1(%R1)\n" " ic %0,%1\n" : "=&d" (result) : "Q" (*x) : "cc"); #else /* __s390x__ */ From 7fb0a5ee8889488f7568ffddffeb66ddeb50917e Mon Sep 17 00:00:00 2001 From: "Nikunj A. Dadhania" Date: Mon, 9 Apr 2012 13:52:23 +0530 Subject: [PATCH 163/438] perf kvm: Finding struct machine fails for PERF_RECORD_MMAP Running 'perf kvm --host --guest --guestmount /tmp/guestmount record -a -g -- sleep 2' Was resulting in a segfault. For event type PERF_RECORD_MMAP, event->ip.pid is being used in perf_session__find_machine_for_cpumode, which is not correct. The event->ip.pid field happens to be 0 in this case and results in returning a NULL machine object. Finally, access to self->pid in machine__mmap_name, results in a segfault later. For PERF_RECORD_MMAP type, pass event->mmap.pid. Signed-off-by: Nikunj A. Dadhania Reviewed-by: David Ahern Tested-by: David Ahern Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Nikunj A. Dadhania Link: http://lkml.kernel.org/r/20120409081835.10576.22018.stgit@abhimanyu.in.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 9412e3b05f68..00923cda4d9c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -826,8 +826,16 @@ static struct machine * { const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) - return perf_session__find_machine(session, event->ip.pid); + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { + u32 pid; + + if (event->header.type == PERF_RECORD_MMAP) + pid = event->mmap.pid; + else + pid = event->ip.pid; + + return perf_session__find_machine(session, pid); + } return perf_session__find_host_machine(session); } From 4e833c0b87a30798e67f06120cecebef6ee9644c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 15 Mar 2012 16:37:08 +0200 Subject: [PATCH 164/438] xhci: don't re-enable IE constantly While we're at that, define IMAN bitfield to aid readability. The interrupt enable bit should be set once on driver init, and we shouldn't need to continually re-enable it. Commit c21599a3 introduced a read of the irq_pending register, and that allows us to preserve the state of the IE bit. Before that commit, we were blindly writing 0x3 to the register. This patch should be backported to kernels as old as 2.6.36, or ones that contain the commit c21599a36165dbc78b380846b254017a548b9de5 "USB: xhci: Reduce reads and writes of interrupter registers". Signed-off-by: Felipe Balbi Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6bd9d53062eb..5ddc4ae85499 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2417,7 +2417,7 @@ hw_died: u32 irq_pending; /* Acknowledge the PCI interrupt */ irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - irq_pending |= 0x3; + irq_pending |= IMAN_IP; xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 91074fdab3eb..3d69c4b2b542 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -205,6 +205,10 @@ struct xhci_op_regs { #define CMD_PM_INDEX (1 << 11) /* bits 12:31 are reserved (and should be preserved on writes). */ +/* IMAN - Interrupt Management Register */ +#define IMAN_IP (1 << 1) +#define IMAN_IE (1 << 0) + /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ #define STS_HALT XHCI_STS_HALT From 5af98bb06dee79d28c805f9fd0805ce791121784 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 16 Mar 2012 12:58:20 -0700 Subject: [PATCH 165/438] xhci: Warn when hosts don't halt. Eric Fu reports a problem with his VIA host controller fetching a zeroed event ring pointer on resume from suspend. The host should have been halted, but we can't be sure because that code ignores the return value from xhci_halt(). Print a warning when the host controller refuses to halt within XHCI_MAX_HALT_USEC (currently 16 seconds). (Update: it turns out that the VIA host controller is reporting a halted state when it fetches the zeroed event ring pointer. However, we still need this warning for other host controllers.) Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e1963d4a430f..f68bc15d21e8 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -106,6 +106,9 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) xhci->xhc_state |= XHCI_STATE_HALTED; + else + xhci_warn(xhci, "Host not halted after %u microseconds.\n", + XHCI_MAX_HALT_USEC); return ret; } From 159e1fcc9a60fc7daba23ee8fcdb99799de3fe84 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 16 Mar 2012 13:09:39 -0700 Subject: [PATCH 166/438] xhci: Don't write zeroed pointers to xHC registers. When xhci_mem_cleanup() is called, we can't be sure if the xHC is actually halted. We can ask the xHC to halt by writing to the RUN bit in the command register, but that might timeout due to a HW hang. If the host controller is still running, we should not write zeroed values to the event ring dequeue pointers or base tables, the DCBAA pointers, or the command ring pointers. Eric Fu reports his VIA VL800 host accesses the event ring pointers after a failed register restore on resume from suspend. The hypothesis is that the host never actually halted before the register write to change the event ring pointer to zero. Remove all writes of zeroed values to pointer registers in xhci_mem_cleanup(). Instead, make all callers of the function reset the host controller first, which will reset those registers to zero. xhci_mem_init() is the only caller that doesn't first halt and reset the host controller before calling xhci_mem_cleanup(). This should be backported to kernels as old as 2.6.32. Signed-off-by: Sarah Sharp Tested-by: Elric Fu Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-mem.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index cae4c6f2845a..68eaa908ac8e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1796,11 +1796,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int i; /* Free the Event Ring Segment Table and the actual Event Ring */ - if (xhci->ir_set) { - xhci_writel(xhci, 0, &xhci->ir_set->erst_size); - xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); - xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); - } size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); if (xhci->erst.entries) dma_free_coherent(&pdev->dev, size, @@ -1812,7 +1807,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->event_ring = NULL; xhci_dbg(xhci, "Freed event ring\n"); - xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); if (xhci->cmd_ring) xhci_ring_free(xhci, xhci->cmd_ring); xhci->cmd_ring = NULL; @@ -1841,7 +1835,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->medium_streams_pool = NULL; xhci_dbg(xhci, "Freed medium stream array pool\n"); - xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); if (xhci->dcbaa) dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), xhci->dcbaa, xhci->dcbaa->dma); @@ -2459,6 +2452,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) fail: xhci_warn(xhci, "Couldn't initialize memory\n"); + xhci_halt(xhci); + xhci_reset(xhci); xhci_mem_cleanup(xhci); return -ENOMEM; } From fb3d85bc7193f23c9a564502df95564c49a32c91 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 16 Mar 2012 13:27:39 -0700 Subject: [PATCH 167/438] xhci: Restore event ring dequeue pointer on resume. The xhci_save_registers() function saved the event ring dequeue pointer in the s3 register structure, but xhci_restore_registers() never restored it. No other code in the xHCI successful resume path would ever restore it either. Fix that. This should be backported to kernels as old as 2.6.37, that contain the commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power management implementation". Signed-off-by: Sarah Sharp Tested-by: Elric Fu Cc: Andiry Xu Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f68bc15d21e8..d2222dc2f82e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -684,6 +684,7 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); + xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) From c7713e736526d8c9f6f87716fb90562a8ffaff2c Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 16 Mar 2012 13:19:35 -0700 Subject: [PATCH 168/438] xhci: Fix register save/restore order. The xHCI 1.0 spec errata released on June 13, 2011, changes the ordering that the xHCI registers are saved and restored in. It moves the interrupt pending (IMAN) and interrupt control (IMOD) registers to be saved and restored last. I believe that's because the host controller may attempt to fetch the event ring table when interrupts are re-enabled. Therefore we need to restore the event ring registers before we re-enable interrupts. This should be backported to kernels as old as 2.6.37, that contain the commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power management implementation" Signed-off-by: Sarah Sharp Tested-by: Elric Fu Cc: Andiry Xu Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d2222dc2f82e..36641a7f2371 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -667,11 +667,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); - xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); } static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -680,11 +680,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); - xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); - xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); + xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); + xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) From d8aec3dbdfd02627e198e7956ab4aaeba2a349fa Mon Sep 17 00:00:00 2001 From: Elric Fu Date: Mon, 26 Mar 2012 21:16:02 +0800 Subject: [PATCH 169/438] USB: fix bug of device descriptor got from superspeed device When the Seagate Goflex USB3.0 device is attached to VIA xHCI host, sometimes the device will downgrade mode to high speed. By the USB analyzer, I found the device finished the link training process and worked at superspeed mode. But the device descriptor got from the device shows the device works at 2.1. It is very strange and seems like the device controller of Seagate Goflex has a little confusion. The first 8 bytes of device descriptor should be: 12 01 00 03 00 00 00 09 But the first 8 bytes of wrong device descriptor are: 12 01 10 02 00 00 00 40 The wrong device descriptor caused the initialization of mass storage failed. After a while, the device would be recognized as a high speed device and works fine. This patch will warm reset the device to fix the issue after finding the bcdUSB field of device descriptor isn't 0x0300 but the speed mode of device is superspeed. This patch should be backported to kernels as old as 3.2, or ones that contain the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm reset logic". Signed-off-by: Elric Fu Acked-by: Andiry Xu Acked-by: Sergei Shtylyov Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/core/hub.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 28664eb7f555..a2aa9d652c67 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3163,6 +3163,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; + /* + * Some superspeed devices have finished the link training process + * and attached to a superspeed hub port, but the device descriptor + * got from those devices show they aren't superspeed devices. Warm + * reset the port attached by the devices can fix them. + */ + if ((udev->speed == USB_SPEED_SUPER) && + (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { + dev_err(&udev->dev, "got a wrong device descriptor, " + "warm reset device\n"); + hub_port_reset(hub, port1, udev, + HUB_BH_RESET_TIME, true); + retval = -EINVAL; + goto fail; + } + if (udev->descriptor.bMaxPacketSize0 == 0xff || udev->speed == USB_SPEED_SUPER) i = 512; From 457a4f61f9bfc3ae76e5b49f30f25d86bb696f67 Mon Sep 17 00:00:00 2001 From: Elric Fu Date: Thu, 29 Mar 2012 15:47:50 +0800 Subject: [PATCH 170/438] xHCI: add XHCI_RESET_ON_RESUME quirk for VIA xHCI host The suspend operation of VIA xHCI host have some issues and hibernate operation works fine, so The XHCI_RESET_ON_RESUME quirk is added for it. This patch should base on "xHCI: Don't write zeroed pointer to xHC registers" that is released by Sarah. Otherwise, the host system error will ocurr in the hibernate operation process. This should be backported to stable kernels as old as 2.6.37, that contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 "xhci: Add reset on resume quirk for asrock p67 host". Signed-off-by: Elric Fu Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 0d7b85135965..7a856a767e77 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_RESET_ON_RESUME; xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); } + if (pdev->vendor == PCI_VENDOR_ID_VIA) + xhci->quirks |= XHCI_RESET_ON_RESUME; } /* called during probe() after chip reset completes */ From 3fc8206d3dca1550eb0a1f6e2a350881835954ba Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 28 Mar 2012 10:30:26 +0300 Subject: [PATCH 171/438] xHCI: use gfp flags from caller instead of GFP_ATOMIC The caller is allowed to specify the GFP flags for these functions. We should prefer their flags unless we have good reason. For example, if we take a spin_lock ourselves we'd need to use GFP_ATOMIC. But in this case it's safe to use the callers GFP flags. The callers all pass GFP_ATOMIC here, so this change doesn't affect how the kernel behaves but we may add other callers later and this is a cleanup. Signed-off-by: Dan Carpenter Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 5ddc4ae85499..3d9422f16a20 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, urb->dev->speed == USB_SPEED_FULL) urb->interval /= 8; } - return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); + return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index); } /* @@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, } ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free; - return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); + return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index); } /**** Command Ring Operations ****/ From 95018a53f7653e791bba1f54c8d75d9cb700d1bd Mon Sep 17 00:00:00 2001 From: Alex He Date: Fri, 30 Mar 2012 10:21:38 +0800 Subject: [PATCH 172/438] xHCI: Correct the #define XHCI_LEGACY_DISABLE_SMI Re-define XHCI_LEGACY_DISABLE_SMI and used it in right way. All SMI enable bits will be cleared to zero and flag bits 29:31 are also cleared to zero. Other bits should be presvered as Table 146. This patch should be backported to kernels as old as 2.6.31. Signed-off-by: Alex He Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/pci-quirks.c | 10 +++++++--- drivers/usb/host/xhci-ext-caps.h | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 11de5f1be981..32dada8c8b4f 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) } } - /* Disable any BIOS SMIs */ - writel(XHCI_LEGACY_DISABLE_SMI, - base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + /* Mask off (turn off) any enabled SMIs */ + val &= XHCI_LEGACY_DISABLE_SMI; + /* Mask all SMI events bits, RW1C */ + val |= XHCI_LEGACY_SMI_EVENTS; + /* Disable any BIOS SMIs and clear all SMI events*/ + writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); if (usb_is_intel_switchable_xhci(pdev)) usb_enable_xhci_ports(pdev); diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index c7f33123d4c0..377f4242dabb 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -62,8 +62,9 @@ /* USB Legacy Support Control and Status Register - section 7.1.2 */ /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ #define XHCI_LEGACY_CONTROL_OFFSET (0x04) -/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ -#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) +/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) +#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29) /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */ #define XHCI_L1C (1 << 16) From 9dc4e6c4d1182d34604ea40fef641775f5b15456 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 9 Apr 2012 18:06:49 -0400 Subject: [PATCH 173/438] nfsd: don't fail unchecked creates of non-special files Allow a v3 unchecked open of a non-regular file succeed as if it were a lookup; typically a client in such a case will want to fall back on a local open, so succeeding and giving it the filehandle is more useful than failing with nfserr_exist, which makes it appear that nothing at all exists by that name. Similarly for v4, on an open-create, return the same errors we would on an attempt to open a non-regular file, instead of returning nfserr_exist. This fixes a problem found doing a v4 open of a symlink with O_RDONLY|O_CREAT, which resulted in the current client returning EEXIST. Thanks also to Trond for analysis. Cc: stable@kernel.org Reported-by: Orion Poplawski Tested-by: Orion Poplawski Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 8 ++++---- fs/nfsd/vfs.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2ed14dfd00a2..8256efda3638 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o */ if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_MODIFY); + FATTR4_WORD1_TIME_MODIFY); } else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, resfh); fh_unlock(current_fh); - if (status) - goto out; - status = nfsd_check_obj_isreg(resfh); } + if (status) + goto out; + status = nfsd_check_obj_isreg(resfh); if (status) goto out; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 296d671654d6..568666156ea4 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, switch (createmode) { case NFS3_CREATE_UNCHECKED: if (! S_ISREG(dchild->d_inode->i_mode)) - err = nfserr_exist; + goto out; else if (truncp) { /* in nfsv4, we need to treat this case a little * differently. we don't want to truncate the From d48fc63f6f3f485ed5aa9cf019d8e8e3a7d10263 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 11 Apr 2012 23:49:16 +0200 Subject: [PATCH 174/438] Revert "clocksource: Load the ACPI PM clocksource asynchronously" This reverts commit b519508298e0292e1771eecf14aaf67755adc39d. The reason for this revert is that making the frequency verification preemptible and interruptible is not working reliably. Michaels machine failed to use PM-timer with the message: PM-Timer running at invalid rate: 113% of normal - aborting. That's not a surprise as the frequency verification does rely on interrupts being disabled. With a async scheduled thread there is no guarantee to achieve the same result. Also some driver might fiddle with the CTC channel 2 during the verification period, which makes the result even more random and unpredictable. This can be solved by using the same mechanism as we use in the deferred TSC validation code, but that only will work if we verified a working HPET _BEFORE_ trying to do the PM-Timer lazy validation. So for now reverting is the safe option. Bisected-by: Michael Witten Cc: Arjan van de Ven Cc: Arjan van de Ven Cc: John Stultz Cc: Len Brown LKML-Reference: Signed-off-by: Thomas Gleixner --- drivers/clocksource/acpi_pm.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 82e882028fcf..6b5cf02c35c8 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -23,7 +23,6 @@ #include #include #include -#include #include /* @@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void) /* Number of reads we try to get two different values */ #define ACPI_PM_READ_CHECKS 10000 -static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) +static int __init init_acpi_pm_clocksource(void) { cycle_t value1, value2; unsigned int i, j = 0; + if (!pmtmr_ioport) + return -ENODEV; /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - usleep_range(100 * j, 100 * j + 100); + udelay(100 * j); value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); @@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); pmtmr_ioport = 0; - return; + return -EINVAL; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); pmtmr_ioport = 0; - return; + return -ENODEV; } } if (verify_pmtmr_rate() != 0){ pmtmr_ioport = 0; - return; + return -ENODEV; } - clocksource_register_hz(&clocksource_acpi_pm, + return clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); } -static int __init init_acpi_pm_clocksource(void) -{ - if (!pmtmr_ioport) - return -ENODEV; - - async_schedule(acpi_pm_clocksource_async, NULL); - return 0; -} - /* We use fs_initcall because we want the PCI fixups to have run * but we still need to load before device_initcall */ From 32f6daad4651a748a58a3ab6da0611862175722f Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 11 Apr 2012 09:51:49 -0600 Subject: [PATCH 175/438] KVM: unmap pages from the iommu when slots are removed We've been adding new mappings, but not destroying old mappings. This can lead to a page leak as pages are pinned using get_user_pages, but only unpinned with put_page if they still exist in the memslots list on vm shutdown. A memslot that is destroyed while an iommu domain is enabled for the guest will therefore result in an elevated page reference count that is never cleared. Additionally, without this fix, the iommu is only programmed with the first translation for a gpa. This can result in peer-to-peer errors if a mapping is destroyed and replaced by a new mapping at the same gpa as the iommu will still be pointing to the original, pinned memory address. Signed-off-by: Alex Williamson Signed-off-by: Marcelo Tosatti --- include/linux/kvm_host.h | 6 ++++++ virt/kvm/iommu.c | 7 ++++++- virt/kvm/kvm_main.c | 5 +++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 665a260c7e09..72cbf08d45fb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -596,6 +596,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_IOMMU_API int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); +void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_guest(struct kvm *kvm); int kvm_iommu_unmap_guest(struct kvm *kvm); int kvm_assign_device(struct kvm *kvm, @@ -609,6 +610,11 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm, return 0; } +static inline void kvm_iommu_unmap_pages(struct kvm *kvm, + struct kvm_memory_slot *slot) +{ +} + static inline int kvm_iommu_map_guest(struct kvm *kvm) { return -ENODEV; diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index a457d2138f49..fec1723de9b4 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -310,6 +310,11 @@ static void kvm_iommu_put_pages(struct kvm *kvm, } } +void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot) +{ + kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages); +} + static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int idx; @@ -320,7 +325,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) - kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages); + kvm_iommu_unmap_pages(kvm, memslot); srcu_read_unlock(&kvm->srcu, idx); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 42b73930a6de..9739b533ca2e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -808,12 +808,13 @@ int __kvm_set_memory_region(struct kvm *kvm, if (r) goto out_free; - /* map the pages in iommu page table */ + /* map/unmap the pages in iommu page table */ if (npages) { r = kvm_iommu_map_pages(kvm, &new); if (r) goto out_free; - } + } else + kvm_iommu_unmap_pages(kvm, &old); r = -ENOMEM; slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), From 4fe9e9639d95cd11de63afa353f2de320f26033a Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Tue, 10 Apr 2012 18:12:27 +0100 Subject: [PATCH 176/438] Cleanup handling of NULL value passed for a mount option Allow blank user= and ip= mount option. Also clean up redundant checks for NULL values since the token parser will not actually match mount options with NULL values unless explicitly specified. Signed-off-by: Sachin Prabhu Reported-by: Chris Clayton Acked-by: Jeff Layton Tested-by: Chris Clayton Signed-off-by: Steve French --- fs/cifs/connect.c | 80 +++++++++++------------------------------------ 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d81e933a796b..6a86f3d68182 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -109,6 +109,8 @@ enum { /* Options which could be blank */ Opt_blank_pass, + Opt_blank_user, + Opt_blank_ip, Opt_err }; @@ -183,11 +185,15 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_wsize, "wsize=%s" }, { Opt_actimeo, "actimeo=%s" }, + { Opt_blank_user, "user=" }, + { Opt_blank_user, "username=" }, { Opt_user, "user=%s" }, { Opt_user, "username=%s" }, { Opt_blank_pass, "pass=" }, { Opt_pass, "pass=%s" }, { Opt_pass, "password=%s" }, + { Opt_blank_ip, "ip=" }, + { Opt_blank_ip, "addr=" }, { Opt_ip, "ip=%s" }, { Opt_ip, "addr=%s" }, { Opt_unc, "unc=%s" }, @@ -1534,15 +1540,17 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* String Arguments */ + case Opt_blank_user: + /* null user, ie. anonymous authentication */ + vol->nullauth = 1; + vol->username = NULL; + break; case Opt_user: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (!*string) { - /* null user, ie. anonymous authentication */ - vol->nullauth = 1; - } else if (strnlen(string, MAX_USERNAME_SIZE) > + if (strnlen(string, MAX_USERNAME_SIZE) > MAX_USERNAME_SIZE) { printk(KERN_WARNING "CIFS: username too long\n"); goto cifs_parse_mount_err; @@ -1611,14 +1619,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } vol->password[j] = '\0'; break; + case Opt_blank_ip: + vol->UNCip = NULL; + break; case Opt_ip: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (!*string) { - vol->UNCip = NULL; - } else if (strnlen(string, INET6_ADDRSTRLEN) > + if (strnlen(string, INET6_ADDRSTRLEN) > INET6_ADDRSTRLEN) { printk(KERN_WARNING "CIFS: ip address " "too long\n"); @@ -1636,12 +1645,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: invalid path to " - "network resource\n"); - goto cifs_parse_mount_err; - } - temp_len = strnlen(string, 300); if (temp_len == 300) { printk(KERN_WARNING "CIFS: UNC name too long\n"); @@ -1670,11 +1673,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: invalid domain" - " name\n"); - goto cifs_parse_mount_err; - } else if (strnlen(string, 256) == 256) { + if (strnlen(string, 256) == 256) { printk(KERN_WARNING "CIFS: domain name too" " long\n"); goto cifs_parse_mount_err; @@ -1693,11 +1692,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: srcaddr value not" - " specified\n"); - goto cifs_parse_mount_err; - } else if (!cifs_convert_address( + if (!cifs_convert_address( (struct sockaddr *)&vol->srcaddr, string, strlen(string))) { printk(KERN_WARNING "CIFS: Could not parse" @@ -1710,11 +1705,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: Invalid path" - " prefix\n"); - goto cifs_parse_mount_err; - } temp_len = strnlen(string, 1024); if (string[0] != '/') temp_len++; /* missing leading slash */ @@ -1742,11 +1732,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: Invalid iocharset" - " specified\n"); - goto cifs_parse_mount_err; - } else if (strnlen(string, 1024) >= 65) { + if (strnlen(string, 1024) >= 65) { printk(KERN_WARNING "CIFS: iocharset name " "too long.\n"); goto cifs_parse_mount_err; @@ -1771,11 +1757,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: No socket option" - " specified\n"); - goto cifs_parse_mount_err; - } if (strnicmp(string, "TCP_NODELAY", 11) == 0) vol->sockopt_tcp_nodelay = 1; break; @@ -1784,12 +1765,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: Invalid (empty)" - " netbiosname\n"); - break; - } - memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); /* @@ -1817,11 +1792,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: Empty server" - " netbiosname specified\n"); - break; - } /* last byte, type, is 0x20 for servr type */ memset(vol->target_rfc1001_name, 0x20, RFC1001_NAME_LEN_WITH_NULL); @@ -1848,12 +1818,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - cERROR(1, "no protocol version specified" - " after vers= mount option"); - goto cifs_parse_mount_err; - } - if (strnicmp(string, "cifs", 4) == 0 || strnicmp(string, "1", 1) == 0) { /* This is the default */ @@ -1868,12 +1832,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!*string) { - printk(KERN_WARNING "CIFS: no security flavor" - " specified\n"); - break; - } - if (cifs_parse_security_flavors(string, vol) != 0) goto cifs_parse_mount_err; break; From 038d4fef376bc494d4f11072d2ab248414b7d568 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Apr 2012 17:18:12 +0200 Subject: [PATCH 177/438] ALSA: hda/realtek - Fix GPIO1 setup for Acer Aspire 4930 & co Add GPIO1 setup explicitly for Acer Aspire 493x & co. This could be set by alc_auto_init_amp(), but it's safer to set it more explicitly in the fixup table. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e7b2b839a539..4eec2150312b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5269,7 +5269,9 @@ static const struct alc_fixup alc882_fixups[] = { { 0x16, 0x99130111 }, /* CLFE speaker */ { 0x17, 0x99130112 }, /* surround speaker */ { } - } + }, + .chained = true, + .chain_id = ALC882_FIXUP_GPIO1, }, [ALC882_FIXUP_ACER_ASPIRE_8930G] = { .type = ALC_FIXUP_PINS, @@ -5312,7 +5314,9 @@ static const struct alc_fixup alc882_fixups[] = { { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, { } - } + }, + .chained = true, + .chain_id = ALC882_FIXUP_GPIO1, }, [ALC885_FIXUP_MACPRO_GPIO] = { .type = ALC_FIXUP_FUNC, From 63634806519b49bb43f37e53a1e8366eb3e846a4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 Apr 2012 08:47:05 +0200 Subject: [PATCH 178/438] block: mtip32xx: remove HOTPLUG_PCI_PCIE dependancy This removes the HOTPLUG_PCI_PCIE dependency on the driver and makes it depend on PCI. Cc: Sam Bradshaw Signed-off-by: Greg Kroah-Hartman Acked-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/mtip32xx/Kconfig b/drivers/block/mtip32xx/Kconfig index b5dd14e072f2..0ba837fc62a8 100644 --- a/drivers/block/mtip32xx/Kconfig +++ b/drivers/block/mtip32xx/Kconfig @@ -4,6 +4,6 @@ config BLK_DEV_PCIESSD_MTIP32XX tristate "Block Device Driver for Micron PCIe SSDs" - depends on HOTPLUG_PCI_PCIE + depends on PCI help This enables the block driver for Micron PCIe SSDs. From 5e7045b010bdb56abbfe5714e8debf03a024c016 Mon Sep 17 00:00:00 2001 From: Zhi Yong Wu Date: Mon, 9 Apr 2012 10:42:13 +0300 Subject: [PATCH 179/438] tools/virtio: fix up vhost/test module build commit ea5d404655ba3b356d0c06d6a3c4f24112124522 broke build for the vhost test module used by tools/virtio. Fix it up. Signed-off-by: Zhi Yong Wu Signed-off-by: Michael S. Tsirkin --- drivers/vhost/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index fc9a1d75281f..3de00d9fae2e 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); - vhost_dev_cleanup(&n->dev); + vhost_dev_cleanup(&n->dev, false); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ vhost_test_flush(n); From c0aa3e0916d7e531e69b02e426f7162dfb1c6c0f Mon Sep 17 00:00:00 2001 From: Ren Mingxin Date: Tue, 10 Apr 2012 15:28:05 +0800 Subject: [PATCH 180/438] virtio_blk: helper function to format disk names The current virtio block's naming algorithm just supports 18278 (26^3 + 26^2 + 26) disks. If there are more virtio blocks, there will be disks with the same name. Based on commit 3e1a7ff8a0a7b948f2684930166954f9e8e776fe, add a function "virtblk_name_format()" for virtio block to support mass of disks naming. Notes: - Our naming scheme is ugly. We are stuck with it for virtio but don't use it for any new driver: new drivers should name their devices PREFIX%d where the sequence number can be allocated by ida - sd_format_disk_name has exactly the same logic. Moving it to a central place was deferred over worries that this will make people keep using the legacy naming in new drivers. We kept code idential in case someone wants to deduplicate later. Signed-off-by: Ren Mingxin Acked-by: Asias He Signed-off-by: Michael S. Tsirkin --- drivers/block/virtio_blk.c | 41 +++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c4a60badf252..303779cb1fa2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -374,6 +374,34 @@ static int init_vq(struct virtio_blk *vblk) return err; } +/* + * Legacy naming scheme used for virtio devices. We are stuck with it for + * virtio blk but don't ever use it for any new driver. + */ +static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) +{ + const int base = 'z' - 'a' + 1; + char *begin = buf + strlen(prefix); + char *end = buf + buflen; + char *p; + int unit; + + p = end - 1; + *p = '\0'; + unit = base; + do { + if (p == begin) + return -EINVAL; + *--p = 'a' + (index % unit); + index = (index / unit) - 1; + } while (index >= 0); + + memmove(begin, p, end - p); + memcpy(buf, prefix, strlen(prefix)); + + return 0; +} + static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -442,18 +470,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) q->queuedata = vblk; - if (index < 26) { - sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); - } else if (index < (26 + 1) * 26) { - sprintf(vblk->disk->disk_name, "vd%c%c", - 'a' + index / 26 - 1, 'a' + index % 26); - } else { - const unsigned int m1 = (index / 26 - 1) / 26 - 1; - const unsigned int m2 = (index / 26 - 1) % 26; - const unsigned int m3 = index % 26; - sprintf(vblk->disk->disk_name, "vd%c%c%c", - 'a' + m1, 'a' + m2, 'a' + m3); - } + virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); vblk->disk->major = major; vblk->disk->first_minor = index_to_minor(index); From c628ee67fb15a0d8d48351aa2e487c5f14779785 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 12 Apr 2012 12:57:08 +0200 Subject: [PATCH 181/438] fuse: use flexible array in fuse.h Use the ISO C standard compliant form instead of the gcc extension in the interface definition. Reported-by: Shachar Sharon Signed-off-by: Miklos Szeredi --- include/linux/fuse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 8ba2c9460b28..8f2ab8fef929 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -593,7 +593,7 @@ struct fuse_dirent { __u64 off; __u32 namelen; __u32 type; - char name[0]; + char name[]; }; #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) From 6f3603367b8f7c34598fdfc1058622e0e1951e98 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 12 Apr 2012 07:51:08 -0700 Subject: [PATCH 182/438] IB/srpt: Set srq_type to IB_SRQT_BASIC Since commit 96104eda0169 ("RDMA/core: Add SRQ type field"), kernel users of SRQs need to specify srq_type = IB_SRQT_BASIC in struct ib_srq_init_attr, or else most low-level drivers will fail in when srpt_add_one() calls ib_create_srq() and gets -ENOSYS. (mlx4_ib works OK nearly all of the time, because it just needs srq_type != IB_SRQT_XRC. And apparently nearly everyone using ib_srpt is using mlx4 hardware) Reported-by: Alexey Shvetsov Cc: Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srpt/ib_srpt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 69e2ad06e515..daf21b899999 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3232,6 +3232,7 @@ static void srpt_add_one(struct ib_device *device) srq_attr.attr.max_wr = sdev->srq_size; srq_attr.attr.max_sge = 1; srq_attr.attr.srq_limit = 0; + srq_attr.srq_type = IB_SRQT_BASIC; sdev->srq = ib_create_srq(sdev->pd, &srq_attr); if (IS_ERR(sdev->srq)) From 6782206b5dfece4c51f587b3ca1540a4027f87dd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 12 Apr 2012 14:21:01 +0200 Subject: [PATCH 183/438] perf session: Skip event correctly for unknown id/machine In case the perf_session__process_event function fails, we estimate the next event offset. This is not necessary for sample event failing on unknown ID or machine. In such case we know proper size of the event, so we dont need to guess. Also failure statistics are updated correctly so we don't miss any information. Forcing perf_session__process_event to return 0 in case of unknown ID or machine. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1334233262-5679-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 00923cda4d9c..1efd3bee6336 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -876,11 +876,11 @@ static int perf_session_deliver_event(struct perf_session *session, dump_sample(session, event, sample); if (evsel == NULL) { ++session->hists.stats.nr_unknown_id; - return -1; + return 0; } if (machine == NULL) { ++session->hists.stats.nr_unprocessable_samples; - return -1; + return 0; } return tool->sample(tool, event, sample, evsel, machine); case PERF_RECORD_MMAP: From 9de29225bdd25958c1fa82521ff02726f1cab953 Mon Sep 17 00:00:00 2001 From: Stephen Lewis Date: Mon, 2 Apr 2012 13:38:49 -0700 Subject: [PATCH 184/438] USB: update usbtmc api documentation Correct path names in API documentation for usbtmc Signed-off-by: Stephen Lewis Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/stable/sysfs-driver-usb-usbtmc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc index 2a7f9a00cb0a..e960cd027e1e 100644 --- a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc +++ b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc @@ -1,5 +1,5 @@ -What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities +What: /sys/bus/usb/drivers/usbtmc/*/interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/*/device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -12,8 +12,8 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities +What: /sys/bus/usb/drivers/usbtmc/*/usb488_interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/*/usb488_device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -27,7 +27,7 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar +What: /sys/bus/usb/drivers/usbtmc/*/TermChar Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -40,7 +40,7 @@ Description: sent to the device or not. -What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled +What: /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -51,7 +51,7 @@ Description: published by the USB-IF. -What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort +What: /sys/bus/usb/drivers/usbtmc/*/auto_abort Date: August 2008 Contact: Greg Kroah-Hartman Description: From 8e62c2de6e23e5c1fee04f59de51b54cc2868ca5 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Apr 2012 13:46:48 -0400 Subject: [PATCH 185/438] Revert "Btrfs: increase the global block reserve estimates" This reverts commit 5500cdbe14d7435e04f66ff3cfb8ecd8b8e44ebf. We've had a number of complaints of early enospc that bisect down to this patch. We'll hae to fix the reservations differently. CC: stable@kernel.org Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a84420491c11..ace5e8cef03e 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4205,7 +4205,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) num_bytes += div64_u64(data_used + meta_used, 50); if (num_bytes * 3 > meta_used) - num_bytes = div64_u64(meta_used, 3) * 2; + num_bytes = div64_u64(meta_used, 3); return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10); } From fe97da1f7001ca0f572358462606eb3d1bde3f23 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Apr 2012 08:00:19 +0200 Subject: [PATCH 186/438] ALSA: hda/realtek - Add a fixup entry for Acer Aspire 8940G It's compatible with 8930G. Using the same fixup gives the proper 5.1 sound back. Reported-and-tested-by: Dany Martineau Cc: [v3.3+] Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4eec2150312b..d25a6f90a37b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5363,6 +5363,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), + SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), From 29ebe40284c75a5888c601872059fca7e258528d Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 12 Apr 2012 13:55:36 -0400 Subject: [PATCH 187/438] ALSA: hda/realtek - Add quirk for Mac Pro 5,1 machines A user reported that setting model=imac24 used to allow sound to work on their Mac Pro 5,1 machine. Commit 5671087ffa "Move ALC885 macpro and imac24 models to auto-parser" removed this model option. All Mac machines are now explicitly handled with a quirk and the auto-parser. This adds a quirk for the device found on the Mac Pro 5,1 machines. This (partially) fixes https://bugzilla.redhat.com/show_bug.cgi?id=808559 [sorted the new entry in the ID number order by tiwai] Reported-by: Gabriel Somlo Signed-off-by: Josh Boyer Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d25a6f90a37b..8f4a48463fad 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5389,6 +5389,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), + SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), From f755397211745e26a4cc693a195982de6c454edd Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 10 Apr 2012 12:35:13 +0200 Subject: [PATCH 188/438] perf tools: fix NO_GTK2 Makefile config error In case the user specified NO_GTK2 on the make cmdline, compilation would fail with undefined symbol because the Makefile would not set the correct cpp variable: NO_GTK2 vs. NO_GTK2_SUPPORT. This patch renames the variable to the correct name. Signed-off-by: Stephane Eranian Cc: David Ahern Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120410103513.GA9229@quad Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 820371f10d1b..a20d0c599b22 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -527,7 +527,7 @@ else endif ifdef NO_GTK2 - BASIC_CFLAGS += -DNO_GTK2 + BASIC_CFLAGS += -DNO_GTK2_SUPPORT else FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0) ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) From d95603b262edb53d6016a8df0c150371d4d61e67 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Apr 2012 15:55:15 -0400 Subject: [PATCH 189/438] Btrfs: fix uninit variable in repair_eb_io_failure We'd have to be passing bogus extent buffers for this uninit variable to actually be used, but set it to zero just in case. Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 0c3ec003f273..59ec105444fe 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1937,7 +1937,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; u64 start = eb->start; unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); - int ret; + int ret = 0; for (i = 0; i < num_pages; i++) { struct page *p = extent_buffer_page(eb, i); From 96d5d96aedc29c75bb16433f6ecf8664ec3c1b46 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Tue, 21 Feb 2012 10:45:26 -0800 Subject: [PATCH 190/438] ata_piix: IDE-mode SATA patch for Intel DH89xxCC DeviceIDs This patch adds the IDE-mode SATA DeviceIDs for the Intel DH89xxCC PCH. Signed-off-by: Seth Heasley Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 68013f96729f..7857e8fd0a3e 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,6 +329,8 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (DH89xxCC) */ + { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; From 99b80e97710ae2e53c951acfdd956e9f38e36646 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 10 Mar 2012 12:00:05 +0300 Subject: [PATCH 191/438] sata_mv: silence an uninitialized variable warning Gcc version 4.6.2-12 complains that if we can't find the "nr-ports" property in of_property_read_u32_array() then "n_ports" is used uninitialized. Let's set it to zero in that case. Signed-off-by: Dan Carpenter Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 38950ea8398a..7336d4a7ab31 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4025,7 +4025,8 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; - int n_ports, rc; + int n_ports = 0; + int rc; ata_print_version_once(&pdev->dev, DRV_VERSION); From 85d6725b7c0d7e3fa4261fdd4c020be4224fc9f1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 10 Mar 2012 23:28:46 -0800 Subject: [PATCH 192/438] libata: make ata_print_id atomic This variable is incremented from multiple contexts (module_init via libata-lldds and the libsas discovery thread). Make it atomic to head off any chance of libsas and libata creating duplicate ids. Acked-by: Jacek Danecki Signed-off-by: Dan Williams Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 ++-- drivers/ata/libata-scsi.c | 4 ++-- drivers/ata/libata.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e0bda9ff89cd..28db50b57b91 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev); -unsigned int ata_print_id = 1; +atomic_t ata_print_id = ATOMIC_INIT(1); struct ata_force_param { const char *name; @@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* give ports names and add SCSI hosts */ for (i = 0; i < host->n_ports; i++) - host->ports[i]->print_id = ata_print_id++; + host->ports[i]->print_id = atomic_inc_return(&ata_print_id); /* Create associated sysfs transport objects */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1ee00c8b5b04..93dabdcd2cbe 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3843,7 +3843,7 @@ int ata_sas_async_port_init(struct ata_port *ap) int rc = ap->ops->port_start(ap); if (!rc) { - ap->print_id = ata_print_id++; + ap->print_id = atomic_inc_return(&ata_print_id); __ata_port_probe(ap); } @@ -3867,7 +3867,7 @@ int ata_sas_port_init(struct ata_port *ap) int rc = ap->ops->port_start(ap); if (!rc) { - ap->print_id = ata_print_id++; + ap->print_id = atomic_inc_return(&ata_print_id); rc = ata_port_probe(ap); } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2e26fcaf635b..9d0fd0b71852 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -53,7 +53,7 @@ enum { ATA_DNXFER_QUIET = (1 << 31), }; -extern unsigned int ata_print_id; +extern atomic_t ata_print_id; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; From b89203f74bdfcb15407d54d3f257b16a2ea19e62 Mon Sep 17 00:00:00 2001 From: Liu Bo Date: Thu, 12 Apr 2012 16:03:56 -0400 Subject: [PATCH 193/438] Btrfs: fix eof while discarding extents We miscalculate the length of extents we're discarding, and it leads to an eof of device. Reported-by: Daniel Blueman Signed-off-by: Liu Bo Signed-off-by: Chris Mason --- fs/btrfs/volumes.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a872b48be0ae..759d02486d7c 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3833,6 +3833,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, int sub_stripes = 0; u64 stripes_per_dev = 0; u32 remaining_stripes = 0; + u32 last_stripe = 0; if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) { @@ -3846,6 +3847,8 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, stripe_nr_orig, factor, &remaining_stripes); + div_u64_rem(stripe_nr_end - 1, factor, &last_stripe); + last_stripe *= sub_stripes; } for (i = 0; i < num_stripes; i++) { @@ -3858,16 +3861,29 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, BTRFS_BLOCK_GROUP_RAID10)) { bbio->stripes[i].length = stripes_per_dev * map->stripe_len; + if (i / sub_stripes < remaining_stripes) bbio->stripes[i].length += map->stripe_len; + + /* + * Special for the first stripe and + * the last stripe: + * + * |-------|...|-------| + * |----------| + * off end_off + */ if (i < sub_stripes) bbio->stripes[i].length -= stripe_offset; - if ((i / sub_stripes + 1) % - sub_stripes == remaining_stripes) + + if (stripe_index >= last_stripe && + stripe_index <= (last_stripe + + sub_stripes - 1)) bbio->stripes[i].length -= stripe_end_offset; + if (i == sub_stripes - 1) stripe_offset = 0; } else From c6664b42c4e567792abdb17c958fb01c5bcfcb3a Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Thu, 12 Apr 2012 16:03:56 -0400 Subject: [PATCH 194/438] Btrfs: remove lock assert from get_restripe_target() This fixes a regression introduced by fc67c450. spin_is_locked() always returns 0 on UP kernels, which caused assert in get_restripe_target() to be fired on every call from btrfs_reduce_alloc_profile() on UP systems. Remove it completely for now, it's not clear if it's going to be needed in future. Reported-by: Bobby Powers Reported-by: Mitch Harder Tested-by: Mitch Harder Signed-off-by: Ilya Dryomov Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index ace5e8cef03e..a2134d8141c1 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3152,15 +3152,14 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) /* * returns target flags in extended format or 0 if restripe for this * chunk_type is not in progress + * + * should be called with either volume_mutex or balance_lock held */ static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags) { struct btrfs_balance_control *bctl = fs_info->balance_ctl; u64 target = 0; - BUG_ON(!mutex_is_locked(&fs_info->volume_mutex) && - !spin_is_locked(&fs_info->balance_lock)); - if (!bctl) return 0; From e627ee7bcd42b4e3a03ca01a8e46dcb4033c5ae0 Mon Sep 17 00:00:00 2001 From: Tsutomu Itoh Date: Thu, 12 Apr 2012 16:03:56 -0400 Subject: [PATCH 195/438] Btrfs: check return value of bio_alloc() properly bio_alloc() has the possibility of returning NULL. So, it is necessary to check the return value. Signed-off-by: Tsutomu Itoh Signed-off-by: Chris Mason --- fs/btrfs/compression.c | 2 ++ fs/btrfs/extent_io.c | 4 ++++ fs/btrfs/scrub.c | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index d11afa67c7d8..646f5e6f2566 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -405,6 +405,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, bio_put(bio); bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); + BUG_ON(!bio); bio->bi_private = cb; bio->bi_end_io = end_compressed_bio_write; bio_add_page(bio, page, PAGE_CACHE_SIZE, 0); @@ -687,6 +688,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); + BUG_ON(!comp_bio); comp_bio->bi_private = cb; comp_bio->bi_end_io = end_compressed_bio_read; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 59ec105444fe..4789770f8eaf 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2180,6 +2180,10 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, } bio = bio_alloc(GFP_NOFS, 1); + if (!bio) { + free_io_failure(inode, failrec, 0); + return -EIO; + } bio->bi_private = state; bio->bi_end_io = failed_bio->bi_end_io; bio->bi_sector = failrec->logical >> 9; diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index c9a2c1aef4bd..60f0e28db31e 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -1044,6 +1044,8 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, BUG_ON(!page->page); bio = bio_alloc(GFP_NOFS, 1); + if (!bio) + return -EIO; bio->bi_bdev = page->bdev; bio->bi_sector = page->physical >> 9; bio->bi_end_io = scrub_complete_bio_end_io; @@ -1172,6 +1174,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, DECLARE_COMPLETION_ONSTACK(complete); bio = bio_alloc(GFP_NOFS, 1); + if (!bio) + return -EIO; bio->bi_bdev = page_bad->bdev; bio->bi_sector = page_bad->physical >> 9; bio->bi_end_io = scrub_complete_bio_end_io; From 4edc2ca388d62abffe38149f6ac00e749ea721c5 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 12 Apr 2012 16:03:56 -0400 Subject: [PATCH 196/438] Btrfs: fix use-after-free in __btrfs_end_transaction 49b25e0540904be0bf558b84475c69d72e4de66e introduced a use-after-free bug that caused spurious -EIO's to be returned. Do the check before we free the transaction. Cc: David Sterba Cc: Jeff Mahoney Signed-off-by: Dave Jones Signed-off-by: Chris Mason --- fs/btrfs/transaction.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8da29e8e4de1..11b77a59db62 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -480,6 +480,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_fs_info *info = root->fs_info; int count = 0; + int err = 0; if (--trans->use_count) { trans->block_rsv = trans->orig_rsv; @@ -532,18 +533,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, if (current->journal_info == trans) current->journal_info = NULL; - memset(trans, 0, sizeof(*trans)); - kmem_cache_free(btrfs_trans_handle_cachep, trans); if (throttle) btrfs_run_delayed_iputs(root); if (trans->aborted || root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { - return -EIO; + err = -EIO; } - return 0; + memset(trans, 0, sizeof(*trans)); + kmem_cache_free(btrfs_trans_handle_cachep, trans); + return err; } int btrfs_end_transaction(struct btrfs_trans_handle *trans, From 62d2feb9803f18c4e3c8a1a2c7e30a54df8a1d72 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 12 Apr 2012 21:48:03 +0200 Subject: [PATCH 197/438] staging: iio: hmc5843: Fix crash in probe function. Fix crash after issuing: echo hmc5843 0x1e > /sys/class/i2c-dev/i2c-2/device/new_device [ 37.180999] device: '2-001e': device_add [ 37.188293] bus: 'i2c': add device 2-001e [ 37.194549] PM: Adding info for i2c:2-001e [ 37.200958] bus: 'i2c': driver_probe_device: matched device 2-001e with driver hmc5843 [ 37.210815] bus: 'i2c': really_probe: probing driver hmc5843 with device 2-001e [ 37.224884] HMC5843 initialized [ 37.228759] ------------[ cut here ]------------ [ 37.233612] kernel BUG at mm/slab.c:505! [ 37.237701] Internal error: Oops - BUG: 0 [#1] PREEMPT [ 37.243103] Modules linked in: [ 37.246337] CPU: 0 Not tainted (3.3.1-gta04+ #28) [ 37.251647] PC is at kfree+0x84/0x144 [ 37.255493] LR is at kfree+0x20/0x144 [ 37.259338] pc : [] lr : [] psr: 40000093 [ 37.259368] sp : de249cd8 ip : 0000000c fp : 00000090 [ 37.271362] r10: 0000000a r9 : de229eac r8 : c0236274 [ 37.276855] r7 : c09d6490 r6 : a0000013 r5 : de229c00 r4 : de229c10 [ 37.283691] r3 : c0f00218 r2 : 00000400 r1 : c0eea000 r0 : c00b4028 [ 37.290527] Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user [ 37.298095] Control: 10c5387d Table: 9e1d0019 DAC: 00000015 [ 37.304107] Process sh (pid: 91, stack limit = 0xde2482f0) [ 37.309844] Stack: (0xde249cd8 to 0xde24a000) [ 37.314422] 9cc0: de229c10 de229c00 [ 37.322998] 9ce0: de229c10 ffffffea 00000005 c0236274 de140a80 c00b4798 dec00080 de140a80 [ 37.331573] 9d00: c032f37c dec00080 000080d0 00000001 de229c00 de229c10 c048d578 00000005 [ 37.340148] 9d20: de229eac 0000000a 00000090 c032fa40 00000001 00000000 00000001 de229c10 [ 37.348724] 9d40: de229eac 00000029 c075b558 00000001 00000003 00000004 de229c10 c048d594 [ 37.357299] 9d60: 00000000 60000013 00000018 205b0007 37332020 3432322e 5d343838 c0060020 [ 37.365905] 9d80: de251600 00000001 00000000 de251600 00000001 c0065a84 de229c00 de229c48 [ 37.374481] 9da0: 00000006 0048d62c de229c38 de229c00 de229c00 de1f6c00 de1f6c20 00000001 [ 37.383056] 9dc0: 00000000 c048d62c 00000000 de229c00 de229c00 de1f6c00 de1f6c20 00000001 [ 37.391632] 9de0: 00000000 c048d62c 00000000 c0330164 00000000 de1f6c20 c048d62c de1f6c00 [ 37.400207] 9e00: c0330078 de1f6c04 c078d714 de189b58 00000000 c02ccfd8 de1f6c20 c0795f40 [ 37.408782] 9e20: c0238330 00000000 00000000 c02381a8 de1b9fc0 de1f6c20 de1f6c20 de249e48 [ 37.417358] 9e40: c0238330 c0236bb0 decdbed8 de7d0f14 de1f6c20 de1f6c20 de1f6c54 de1f6c20 [ 37.425933] 9e60: 00000000 c0238030 de1f6c20 c078d7bc de1f6c20 c02377ec de1f6c20 de1f6c28 [ 37.434509] 9e80: dee64cb0 c0236138 c047c554 de189b58 00000000 c004b45c de1f6c20 de1f6cd8 [ 37.443084] 9ea0: c0edfa6c de1f6c00 dee64c68 de1f6c04 de1f6c20 dee64cb8 c047c554 de189b58 [ 37.451690] 9ec0: 00000000 c02cd634 dee64c68 de249ef4 de23b008 dee64cb0 0000000d de23b000 [ 37.460266] 9ee0: de23b007 c02cd78c 00000002 00000000 00000000 35636d68 00333438 00000000 [ 37.468841] 9f00: 00000000 00000000 001e0000 00000000 00000000 00000000 00000000 0a10cec0 [ 37.477416] 9f20: 00000002 de249f80 0000000d dee62990 de189b40 c0234d88 0000000d c010c354 [ 37.485992] 9f40: 0000000d de210f28 000acc88 de249f80 0000000d de248000 00000000 c00b7bf8 [ 37.494567] 9f60: de210f28 000acc88 de210f28 000acc88 00000000 00000000 0000000d c00b7ed8 [ 37.503143] 9f80: 00000000 00000000 0000000d 00000000 0007fa28 0000000d 000acc88 00000004 [ 37.511718] 9fa0: c000e544 c000e380 0007fa28 0000000d 00000001 000acc88 0000000d 00000000 [ 37.520294] 9fc0: 0007fa28 0000000d 000acc88 00000004 00000001 00000020 00000002 00000000 [ 37.528869] 9fe0: 00000000 beab8624 0000ea05 b6eaebac 600d0010 00000001 00000000 00000000 [ 37.537475] [] (kfree+0x84/0x144) from [] (device_add+0x530/0x57c) [ 37.545806] [] (device_add+0x530/0x57c) from [] (iio_device_register+0x8c8/0x990) [ 37.555480] [] (iio_device_register+0x8c8/0x990) from [] (hmc5843_probe+0xec/0x114) [ 37.565338] [] (hmc5843_probe+0xec/0x114) from [] (i2c_device_probe+0xc4/0xf8) [ 37.574737] [] (i2c_device_probe+0xc4/0xf8) from [] (driver_probe_device+0x118/0x218) [ 37.584777] [] (driver_probe_device+0x118/0x218) from [] (bus_for_each_drv+0x4c/0x84) [ 37.594818] [] (bus_for_each_drv+0x4c/0x84) from [] (device_attach+0x78/0xa4) [ 37.604125] [] (device_attach+0x78/0xa4) from [] (bus_probe_device+0x28/0x9c) [ 37.613433] [] (bus_probe_device+0x28/0x9c) from [] (device_add+0x3f4/0x57c) [ 37.622650] [] (device_add+0x3f4/0x57c) from [] (i2c_new_device+0xf8/0x19c) [ 37.631805] [] (i2c_new_device+0xf8/0x19c) from [] (i2c_sysfs_new_device+0xb4/0x130) [ 37.641754] [] (i2c_sysfs_new_device+0xb4/0x130) from [] (dev_attr_store+0x18/0x24) [ 37.651611] [] (dev_attr_store+0x18/0x24) from [] (sysfs_write_file+0x10c/0x140) [ 37.661193] [] (sysfs_write_file+0x10c/0x140) from [] (vfs_write+0xb0/0x178) [ 37.670410] [] (vfs_write+0xb0/0x178) from [] (sys_write+0x3c/0x68) [ 37.678833] [] (sys_write+0x3c/0x68) from [] (ret_fast_syscall+0x0/0x3c) [ 37.687683] Code: 1593301c e5932000 e3120080 1a000000 (e7f001f2) [ 37.700775] ---[ end trace aaf805debdb69390 ]--- Client data was assigned to iio_dev structure in probe but in hmc5843_init_client function casted to private driver data structure which is wrong. Possibly calling mutex_init(&data->lock); corrupt data which the lead to above crash. Signed-off-by: Marek Belisko Cc: stable Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/hmc5843.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 91dd3da70cb4..e00b416c4d33 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -521,7 +521,9 @@ static int hmc5843_detect(struct i2c_client *client, /* Called when we have found a new HMC5843. */ static void hmc5843_init_client(struct i2c_client *client) { - struct hmc5843_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hmc5843_data *data = iio_priv(indio_dev); + hmc5843_set_meas_conf(client, data->meas_conf); hmc5843_set_rate(client, data->rate); hmc5843_configure(client, data->operating_mode); From 17b7e1ba1e2ecc9a09f5e154e555accd2a2eaedf Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 12 Apr 2012 00:35:46 +0200 Subject: [PATCH 198/438] staging: vt6656: Don't leak memory in drivers/staging/vt6656/ioctl.c::private_ioctl() If copy_to_user() fails in the WLAN_CMD_GET_NODE_LIST case of the switch in drivers/staging/vt6656/ioctl.c::private_ioctl() we'll leak the memory allocated to 'pNodeList'. Fix that by kfree'ing the memory in the failure case. Also remove a pointless cast (to type 'PSNodeList') of a kmalloc() return value - kmalloc() returns a void pointer that is implicitly converted, so there is no need for an explicit cast. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 1463d76895f0..d59456c29df1 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -ENOMEM; break; } - pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); + pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); if (pNodeList == NULL) { result = -ENOMEM; break; @@ -601,6 +601,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } } if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { + kfree(pNodeList); result = -EFAULT; break; } From 474a89885f77953b12bce9f23660c31ef5c2630e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 11 Apr 2012 22:10:20 +0200 Subject: [PATCH 199/438] staging: android: fix mem leaks in __persistent_ram_init() If, in __persistent_ram_init(), the call to persistent_ram_buffer_init() fails or the call to persistent_ram_init_ecc() fails then we fail to free the memory we allocated to 'prz' with kzalloc() - thus leaking it. To prevent the leaks I consolidated all error exits from the function at a 'err:' label at the end and made all error cases jump to that label where we can then make sure we always free 'prz'. This is safe since all the situations where the code bails out happen before 'prz' has been stored anywhere and although we'll do a redundant kfree(NULL) call in the case of kzalloc() itself failing that's OK since kfree() deals gracefully with NULL pointers and I felt it was more important to keep all error exits at a single location than to avoid that one harmless/redundant kfree() on a error path. Signed-off-by: Jesper Juhl Acked-by: Colin Cross Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/persistent_ram.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index e08f2574e30a..8d8c1e33e0ff 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -399,12 +399,12 @@ static __init struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) { struct persistent_ram_zone *prz; - int ret; + int ret = -ENOMEM; prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); if (!prz) { pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - return ERR_PTR(-ENOMEM); + goto err; } INIT_LIST_HEAD(&prz->node); @@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) ret = persistent_ram_buffer_init(dev_name(dev), prz); if (ret) { pr_err("persistent_ram: failed to initialize buffer\n"); - return ERR_PTR(ret); + goto err; } prz->ecc = ecc; ret = persistent_ram_init_ecc(prz, prz->buffer_size); if (ret) - return ERR_PTR(ret); + goto err; if (prz->buffer->sig == PERSISTENT_RAM_SIG) { if (buffer_size(prz) > prz->buffer_size || @@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) atomic_set(&prz->buffer->size, 0); return prz; +err: + kfree(prz); + return ERR_PTR(ret); } struct persistent_ram_zone * __init From 5269a9ab7def9a3116663347d59c4d70afa2d180 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 12 Apr 2012 14:42:15 -0600 Subject: [PATCH 200/438] irq_domain: fix type mismatch in debugfs output format sizeof(void*) returns an unsigned long, but it was being used as a width parameter to a "%-*s" format string which requires an int. On 64 bit platforms this causes a type mismatch: linux/kernel/irq/irqdomain.c:575: warning: field width should have type 'int', but argument 6 has type 'long unsigned int' This change casts the size to an int so printf gets the right data type. Reported-by: Andreas Schwab Signed-off-by: Grant Likely Cc: David Daney --- kernel/irq/irqdomain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index d34413e78628..0e0ba5f840b2 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -629,7 +629,8 @@ static int virq_debug_show(struct seq_file *m, void *private) int i; seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq", - "chip name", 2 * sizeof(void *) + 2, "chip data", "domain name"); + "chip name", (int)(2 * sizeof(void *) + 2), "chip data", + "domain name"); for (i = 1; i < nr_irqs; i++) { desc = irq_to_desc(i); From d53ba47484ed6245e640ee4bfe9d21e9bfc15765 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Thu, 12 Apr 2012 16:03:57 -0400 Subject: [PATCH 201/438] Btrfs: use commit root when loading free space cache A user reported that booting his box up with btrfs root on 3.4 was way slower than on 3.3 because I removed the ideal caching code. It turns out that we don't load the free space cache if we're in a commit for deadlock reasons, but since we're reading the cache and it hasn't changed yet we are safe reading the inode and free space item from the commit root, so do that and remove all of the deadlock checks so we don't unnecessarily skip loading the free space cache. The user reported this fixed the slowness. Thanks, Tested-by: Calvin Walton Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 4 +--- fs/btrfs/free-space-cache.c | 9 ++------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a2134d8141c1..2b35f8d14bb9 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -529,9 +529,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, * allocate blocks for the tree root we can't do the fast caching since * we likely hold important locks. */ - if (trans && (!trans->transaction->in_commit) && - (root && root != root->fs_info->tree_root) && - btrfs_test_opt(root, SPACE_CACHE)) { + if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) { ret = load_free_space_cache(fs_info, cache); spin_lock(&cache->lock); diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 054707ed5791..baaa518baaf8 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -747,13 +747,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, bool matched; u64 used = btrfs_block_group_used(&block_group->item); - /* - * If we're unmounting then just return, since this does a search on the - * normal root and not the commit root and we could deadlock. - */ - if (btrfs_fs_closing(fs_info)) - return 0; - /* * If this block group has been marked to be cleared for one reason or * another then we can't trust the on disk cache, so just return. @@ -768,6 +761,8 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return 0; + path->search_commit_root = 1; + path->skip_locking = 1; inode = lookup_free_space_inode(root, block_group, path); if (IS_ERR(inode)) { From 69349c2dc01c489eccaa4c472542c08e370c6d7e Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 12 Apr 2012 19:46:32 -0400 Subject: [PATCH 202/438] kconfig: fix IS_ENABLED to not require all options to be defined Using IS_ENABLED() within C (vs. within CPP #if statements) in its current form requires us to actually define every possible bool/tristate Kconfig option twice (__enabled_* and __enabled_*_MODULE variants). This results in a huge autoconf.h file, on the order of 16k lines for a x86_64 defconfig. Fixing IS_ENABLED to be able to work on the smaller subset of just things that we really have defined is step one to fixing this. Which means it has to not choke when fed non-enabled options, such as: include/linux/netdevice.h:964:1: warning: "__enabled_CONFIG_FCOE_MODULE" is not defined [-Wundef] The original prototype of how to implement a C and preprocessor compatible way of doing this came from the Google+ user "comex ." in response to Linus' crowdsourcing challenge for a possible improvement on his earlier C specific solution: #define config_enabled(x) (__stringify(x)[0] == '1') In this implementation, I've chosen variable names that hopefully make how it works more understandable. Signed-off-by: Paul Gortmaker Signed-off-by: Linus Torvalds --- include/linux/kconfig.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index 067eda0e4b32..be342b94c640 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -4,29 +4,43 @@ #include /* - * Helper macros to use CONFIG_ options in C expressions. Note that + * Helper macros to use CONFIG_ options in C/CPP expressions. Note that * these only work with boolean and tristate options. */ +/* + * Getting something that works in C and CPP for an arg that may or may + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" + * we match on the placeholder define, insert the "0," for arg1 and generate + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when + * the last step cherry picks the 2nd arg, we get a zero. + */ +#define __ARG_PLACEHOLDER_1 0, +#define config_enabled(cfg) _config_enabled(cfg) +#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) +#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) +#define ___config_enabled(__ignored, val, ...) val + /* * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', * 0 otherwise. * */ #define IS_ENABLED(option) \ - (__enabled_ ## option || __enabled_ ## option ## _MODULE) + (config_enabled(option) || config_enabled(option##_MODULE)) /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 * otherwise. For boolean options, this is equivalent to * IS_ENABLED(CONFIG_FOO). */ -#define IS_BUILTIN(option) __enabled_ ## option +#define IS_BUILTIN(option) config_enabled(option) /* * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 * otherwise. */ -#define IS_MODULE(option) __enabled_ ## option ## _MODULE +#define IS_MODULE(option) config_enabled(option##_MODULE) #endif /* __LINUX_KCONFIG_H */ From a959613533a176a8f5f402585827e94a5220d2db Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 12 Apr 2012 19:46:33 -0400 Subject: [PATCH 203/438] Revert "kconfig: fix __enabled_ macros definition for invisible and un-selected symbols" This reverts commit 953742c8fe8ac45be453fee959d7be40cd89f920. Dumping two lines into autoconf.h for all existing Kconfig options results in a giant file (~16k lines) we have to process each time we compile something. We've weaned IS_ENABLED() and similar off of requiring the __enabled_ definitions so now we can revert the change which caused all the extra lines. Signed-off-by: Paul Gortmaker Signed-off-by: Linus Torvalds --- scripts/kconfig/confdata.c | 49 ++++++++++---------------------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 0586085136d1..9d0674473564 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -489,6 +489,17 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) fprintf(fp, "#define %s%s%s 1\n", CONFIG_, sym->name, suffix); } + /* + * Generate the __enabled_CONFIG_* and + * __enabled_CONFIG_*_MODULE macros for use by the + * IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is + * generated even for booleans so that the IS_ENABLED() macro + * works. + */ + fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", + sym->name, (*value == 'y')); + fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", + sym->name, (*value == 'm')); break; } case S_HEX: { @@ -539,35 +550,6 @@ static struct conf_printer header_printer_cb = .print_comment = header_print_comment, }; -/* - * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for - * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is - * generated even for booleans so that the IS_ENABLED() macro works. - */ -static void -header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) -{ - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: { - fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", - sym->name, (*value == 'y')); - fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", - sym->name, (*value == 'm')); - break; - } - default: - break; - } -} - -static struct conf_printer header__enabled_printer_cb = -{ - .print_symbol = header_print__enabled_symbol, - .print_comment = header_print_comment, -}; - /* * Tristate printer * @@ -949,16 +931,11 @@ int conf_write_autoconf(void) conf_write_heading(out_h, &header_printer_cb, NULL); for_all_symbols(i, sym) { - if (!sym->name) - continue; - sym_calc_value(sym); - - conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL); - - if (!(sym->flags & SYMBOL_WRITE)) + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; + /* write symbol to auto.conf, tristate and header files */ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); From e4757cab4cff01e9c47b14376be7438694032c3c Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 12 Apr 2012 19:46:34 -0400 Subject: [PATCH 204/438] kconfig: delete last traces of __enabled_ from autoconf.h We've now fixed IS_ENABLED() and friends to not require any special "__enabled_" prefixed versions of the normal Kconfig options, so delete the last traces of them being generated. Signed-off-by: Paul Gortmaker Signed-off-by: Linus Torvalds --- scripts/kconfig/confdata.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9d0674473564..52577f052bc1 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -489,17 +489,6 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) fprintf(fp, "#define %s%s%s 1\n", CONFIG_, sym->name, suffix); } - /* - * Generate the __enabled_CONFIG_* and - * __enabled_CONFIG_*_MODULE macros for use by the - * IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is - * generated even for booleans so that the IS_ENABLED() macro - * works. - */ - fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", - sym->name, (*value == 'y')); - fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", - sym->name, (*value == 'm')); break; } case S_HEX: { From 7d7eb9ea314e992413620610b4d09c9cd5fa8959 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 12 Apr 2012 22:11:25 +0200 Subject: [PATCH 205/438] ALSA: hda/realtek - Fix mem leak (and rid us of trailing whitespace). In sound/pci/hda/patch_realtek.c::alc_auto_fill_dac_nids(), in the 'for (;;)' loop, if the 'badness' value returned from fill_and_eval_dacs() is negative, then we'll return from the function without freeing the memory we allocated for 'best_cfg', thus leaking. Fix the leak by kfree()'ing the memory when badness is negative. While I was there I also noticed some trailing whitespace in the function that I removed (along with all other trailing whitespace in the file) - it didn't seem worth-while to do that as two patches, so I hope it's OK that I just did it all as one patch. Signed-off-by: Jesper Juhl Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8f4a48463fad..2508f8109f11 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3398,8 +3398,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (;;) { badness = fill_and_eval_dacs(codec, fill_hardwired, fill_mio_first); - if (badness < 0) + if (badness < 0) { + kfree(best_cfg); return badness; + } debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", cfg->line_out_type, fill_hardwired, fill_mio_first, badness); @@ -3434,7 +3436,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; fill_hardwired = true; continue; - } + } if (cfg->hp_outs > 0 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { cfg->speaker_outs = cfg->line_outs; @@ -3448,7 +3450,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_HP_OUT; fill_hardwired = true; continue; - } + } break; } @@ -4423,7 +4425,7 @@ static int alc_parse_auto_config(struct hda_codec *codec, static int alc880_parse_auto_config(struct hda_codec *codec) { static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; + static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); } @@ -6093,7 +6095,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), @@ -6310,7 +6312,7 @@ static void alc_fixup_no_jack_detect(struct hda_codec *codec, { if (action == ALC_FIXUP_ACT_PRE_PROBE) codec->no_jack_detect = 1; -} +} static const struct alc_fixup alc861_fixups[] = { [ALC861_FIXUP_FSC_AMILO_PI1505] = { @@ -6728,7 +6730,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), From d99de7f552fac43e24fd4fb8048d8f21abaea691 Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo Date: Fri, 13 Apr 2012 05:08:03 -0600 Subject: [PATCH 206/438] ARM: OMAP2+: hwmod: add softreset delay field and OMAP4 data Due to HW limitation, some IPs should not be accessed just after a softreset. Since the current hwmod sequence is accessing the sysconfig register just after the reset, it might lead to OCP bus error in that case. Add a new field in the sysconfig structure to specify a delay in usecs needed after doing a softreset. In the case of the ISS and FDIF modules, the L3 OCP port will be disconnected upon a SW reset. That issue was confirmed with HW simulation and an errata should be available soon. The HW recommendation to avoid that is to wait for 100 OCP clk cycles, before accessing the IP. Considering the worse case (OPP50), the L3 bus will run at 100 MHz, so a 1 usec delay is needed. Add an x2 margin to be safe. Acked-by: Benoit Cousson Signed-off-by: Fernando Guzman Lugo [paul@pwsan.com: dropped FDIF change for now since the hwmod data is not yet upstream; the FDIF change will need to be added later once the FDIF data is merged] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 9 +++++++++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 4 +++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 2c27fdb61e66..45f1d9c44e94 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1422,6 +1422,9 @@ static int _ocp_softreset(struct omap_hwmod *oh) goto dis_opt_clks; _write_sysconfig(v, oh); + if (oh->class->sysc->srst_udelay) + udelay(oh->class->sysc->srst_udelay); + if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index cc9bd106a854..6abc75753e42 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2594,6 +2594,15 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + /* + * ISS needs 100 OCP clk cycles delay after a softreset before + * accessing sysconfig again. + * The lowest frequency at the moment for L3 bus is 100 MHz, so + * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). + * + * TODO: Indicate errata when available. + */ + .srst_udelay = 2, .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 8070145ccb98..3f26db4ee8e6 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -305,6 +305,7 @@ struct omap_hwmod_sysc_fields { * @rev_offs: IP block revision register offset (from module base addr) * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr) * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) + * @srst_udelay: Delay needed after doing a softreset in usecs * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART} * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported * @clockact: the default value of the module CLOCKACTIVITY bits @@ -330,9 +331,10 @@ struct omap_hwmod_class_sysconfig { u16 sysc_offs; u16 syss_offs; u16 sysc_flags; + struct omap_hwmod_sysc_fields *sysc_fields; + u8 srst_udelay; u8 idlemodes; u8 clockact; - struct omap_hwmod_sysc_fields *sysc_fields; }; /** From 3c55c1baffa5f719eb2ae9729088bc867f972f53 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 13 Apr 2012 05:08:43 -0600 Subject: [PATCH 207/438] ARM: OMAP2+: hwmod: Revert "ARM: OMAP2+: hwmod: Make omap_hwmod_softreset wait for reset status" This reverts commit f9a2f9c3fa76eec55928e8e06f3094c8f01df7cb. This commit caused a regression in the I2C hwmod reset on OMAP2/3/4, logging messages similar to these during boot: [ 0.200378] omap_hwmod: i2c1: softreset failed (waited 10000 usec) [ 0.222076] omap_hwmod: i2c2: softreset failed (waited 10000 usec) While the original patch was intended to fix some reset-related timing issues, it's believed that these problems were actually fixed by commit 2800852a079504f35f88e44faf5c9c96318c0cca ("ARM: OMAP2+: hwmod: Restore sysc after a reset"): http://marc.info/?l=linux-arm-kernel&m=133410322617245&w=2 Cc: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 45f1d9c44e94..7144ae651d3d 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1906,10 +1906,20 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) */ int omap_hwmod_softreset(struct omap_hwmod *oh) { - if (!oh) + u32 v; + int ret; + + if (!oh || !(oh->_sysc_cache)) return -EINVAL; - return _ocp_softreset(oh); + v = oh->_sysc_cache; + ret = _set_softreset(oh, &v); + if (ret) + goto error; + _write_sysconfig(v, oh); + +error: + return ret; } /** From 1f5e6247ca99287bac87aff4971a7eee9c2b223a Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 13 Apr 2012 13:31:55 +0530 Subject: [PATCH 208/438] ARM: OMAP2/3: VENC hwmods: Remove OCPIF_SWSUP_IDLE flag from VENC slave interface The clocks for all DSS slave interfaces were recently changed to "dss_ick" on OMAP2 and OMAP3, this clock can be autoidled by PRCM. The VENC interface previously had "dss_54m_fck" as it's clock which couldn't be autoidled, and hence the OCPIF_SWSUP_IDLE flag was needed. Remove the OCPIF_SWSUP_IDLE flag from VENC interfaces as it's clock is now "dss_ick". This allows the PRCM hardware to autoidle the VENC interface clocks when they are not active, rather than relying on the software to do it, which can keep the interface clocks active unnecessarily. Signed-off-by: Archit Taneja [paul@pwsan.com: add a short description of the fix to the commit log] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 1 - arch/arm/mach-omap2/omap_hwmod_2430_data.c | 1 - arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a5409ce3f323..a6bde34e443a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1000,7 +1000,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, - .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index c4f56cb60d7d..04a3885f4475 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1049,7 +1049,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { .slave = &omap2430_dss_venc_hwmod, .clk = "dss_ick", .addr = omap2_dss_venc_addrs, - .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 34b9766d1d23..db86ce90c69f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1676,7 +1676,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, - .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; From 1e45860f541497d73162305d48b638d9b87e1ae3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 13 Apr 2012 13:11:50 +0100 Subject: [PATCH 209/438] ARM: 7366/3: amba: Remove AMBA level regulator support The AMBA bus regulator support is being used to model on/off switches for power domains which isn't terribly idiomatic for modern kernels with the generic power domain code and creates integration problems on platforms which don't use regulators for their power domains as it's hard to tell the difference between a regulator that is needed but failed to be provided and one that isn't supposed to be there (though DT does make that easier). Platforms that wish to use the regulator API to manage their power domains can indirect via the power domain interface. This feature is only used with the vape supply of the db8500 PRCMU driver which supplies the UARTs and MMC controllers, none of which have support for managing vcore at runtime in mainline (only pl022 SPI controller does). Update that supply to have an always_on constraint until the power domain support for the system is updated so that it is enabled for these users, this is likely to have no impact on practical systems as probably at least one of these devices will be active and cause AMBA to hold the supply on anyway. Signed-off-by: Mark Brown Acked-by: Linus Walleij Tested-by: Shawn Guo Signed-off-by: Russell King --- drivers/amba/bus.c | 42 +------------------------------------- drivers/mfd/db8500-prcmu.c | 1 + drivers/spi/spi-pl022.c | 2 -- include/linux/amba/bus.h | 7 ------- 4 files changed, 2 insertions(+), 50 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 01c2cf4efcdd..cc273226dbd0 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -247,8 +247,7 @@ static int amba_pm_restore(struct device *dev) /* * Hooks to provide runtime PM of the pclk (bus clock). It is safe to * enable/disable the bus clock at runtime PM suspend/resume as this - * does not result in loss of context. However, disabling vcore power - * would do, so we leave that to the driver. + * does not result in loss of context. */ static int amba_pm_runtime_suspend(struct device *dev) { @@ -354,39 +353,6 @@ static void amba_put_disable_pclk(struct amba_device *pcdev) clk_put(pclk); } -static int amba_get_enable_vcore(struct amba_device *pcdev) -{ - struct regulator *vcore = regulator_get(&pcdev->dev, "vcore"); - int ret; - - pcdev->vcore = vcore; - - if (IS_ERR(vcore)) { - /* It is OK not to supply a vcore regulator */ - if (PTR_ERR(vcore) == -ENODEV) - return 0; - return PTR_ERR(vcore); - } - - ret = regulator_enable(vcore); - if (ret) { - regulator_put(vcore); - pcdev->vcore = ERR_PTR(-ENODEV); - } - - return ret; -} - -static void amba_put_disable_vcore(struct amba_device *pcdev) -{ - struct regulator *vcore = pcdev->vcore; - - if (!IS_ERR(vcore)) { - regulator_disable(vcore); - regulator_put(vcore); - } -} - /* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. @@ -399,10 +365,6 @@ static int amba_probe(struct device *dev) int ret; do { - ret = amba_get_enable_vcore(pcdev); - if (ret) - break; - ret = amba_get_enable_pclk(pcdev); if (ret) break; @@ -420,7 +382,6 @@ static int amba_probe(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); - amba_put_disable_vcore(pcdev); } while (0); return ret; @@ -442,7 +403,6 @@ static int amba_remove(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); - amba_put_disable_vcore(pcdev); return ret; } diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index ebc1e8658226..5be32489714f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -2788,6 +2788,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { .constraints = { .name = "db8500-vape", .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .always_on = true, }, .consumer_supplies = db8500_vape_consumers, .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 96f0da66b185..09c925aaf320 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -2195,7 +2195,6 @@ static int pl022_runtime_suspend(struct device *dev) struct pl022 *pl022 = dev_get_drvdata(dev); clk_disable(pl022->clk); - amba_vcore_disable(pl022->adev); return 0; } @@ -2204,7 +2203,6 @@ static int pl022_runtime_resume(struct device *dev) { struct pl022 *pl022 = dev_get_drvdata(dev); - amba_vcore_enable(pl022->adev); clk_enable(pl022->clk); return 0; diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 7847e197730a..8d54f79457ba 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -30,7 +30,6 @@ struct amba_device { struct device dev; struct resource res; struct clk *pclk; - struct regulator *vcore; u64 dma_mask; unsigned int periphid; unsigned int irq[AMBA_NR_IRQS]; @@ -75,12 +74,6 @@ void amba_release_regions(struct amba_device *); #define amba_pclk_disable(d) \ do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) -#define amba_vcore_enable(d) \ - (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore)) - -#define amba_vcore_disable(d) \ - do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0) - /* Some drivers don't use the struct amba_device */ #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) From 9c5fd9e85f574d9d0361b2b878f55732290afe5b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 11 Apr 2012 14:52:55 +0100 Subject: [PATCH 210/438] ARM: 7379/1: DT: fix atags_to_fdt() second call site atags_to_fdt() returns 1 when it fails to find a valid FDT signature. The CONFIG_ARM_ATAG_DTB_COMPAT code is supposed to retry with another location, but only does so when the initial call doesn't fail. Fix this by using the correct condition in the assembly code. Acked-by: Nicolas Pitre Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org Signed-off-by: Russell King --- arch/arm/boot/compressed/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 5f6045f1766c..dc7e8ce8e6be 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -273,7 +273,7 @@ restart: adr r0, LC0 add r0, r0, #0x100 mov r1, r6 sub r2, sp, r6 - blne atags_to_fdt + bleq atags_to_fdt ldmfd sp!, {r0-r3, ip, lr} sub sp, sp, #0x10000 From a106b21a352517b57af1c3581e15b8787ffe4e98 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 11 Apr 2012 14:52:56 +0100 Subject: [PATCH 211/438] ARM: 7380/1: DT: do not add a zero-sized memory property Some bootloaders are broken enough to expose an ATAG_MEM with a null size. Converting such tag to a memory node leads to an unbootable system. Skip over zero sized ATAG_MEM to avoid this situation. Acked-by: Nicolas Pitre Signed-off-by: Marc Zyngier Signed-off-by: Russell King --- arch/arm/boot/compressed/atags_to_fdt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 6ce11c481178..797f04bedb47 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c @@ -77,6 +77,8 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) } else if (atag->hdr.tag == ATAG_MEM) { if (memcount >= sizeof(mem_reg_property)/4) continue; + if (!atag->u.mem.size) + continue; mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); } else if (atag->hdr.tag == ATAG_INITRD2) { From 9b7333a9c1c22409f685ff6bb6a9e3638e7ff06f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 12 Apr 2012 17:12:37 +0100 Subject: [PATCH 212/438] ARM: 7381/1: nommu: fix typo in mm/Kconfig The description for the CPU_HIGH_VECTOR Kconfig option for nommu builds doesn't make any sense. This patch fixes up the trivial grammatical error. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 7edef9121632..7c8a7d8467bf 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR bool "Select the High exception vector" help Say Y here to select high exception vector(0xFFFF0000~). - The exception vector can be vary depending on the platform + The exception vector can vary depending on the platform design in nommu mode. If your platform needs to select high exception vector, say Y. Otherwise or if you are unsure, say N, and the low exception From 6b8e5c912f4294611351aba151324764ebbefa1b Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 12 Apr 2012 17:16:01 +0100 Subject: [PATCH 213/438] ARM: 7383/1: nommu: populate vectors page from paging_init Commit 94e5a85b ("ARM: earlier initialization of vectors page") made it the responsibility of paging_init to initialise the vectors page. This patch adds a call to early_trap_init for the !CONFIG_MMU case, placing the vectors at CONFIG_VECTORS_BASE. Cc: Jonathan Austin Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mm/nommu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 6486d2f253cd..d51225f90ae2 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "mm.h" @@ -39,6 +40,7 @@ void __init sanity_check_meminfo(void) */ void __init paging_init(struct machine_desc *mdesc) { + early_trap_init((void *)CONFIG_VECTORS_BASE); bootmem_init(); } From 96f6f98501196d46ce52c2697dd758d9300c63f5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 12 Apr 2012 23:47:00 -0400 Subject: [PATCH 214/438] nfsd: fix b0rken error value for setattr on read-only mount ..._want_write() returns -EROFS on failure, _not_ an NFS error value. Signed-off-by: Al Viro --- fs/nfsd/nfs4proc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2ed14dfd00a2..694d526c8f19 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -841,6 +841,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) { __be32 status = nfs_ok; + int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); @@ -852,9 +853,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } } - status = fh_want_write(&cstate->current_fh); - if (status) - return status; + err = fh_want_write(&cstate->current_fh); + if (err) + return nfserrno(err); status = nfs_ok; status = check_attr_support(rqstp, cstate, setattr->sa_bmval, From 04da6e9d63427b2d0fd04766712200c250b3278f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 00:00:04 -0400 Subject: [PATCH 215/438] nfsd: fix error values returned by nfsd4_lockt() when nfsd_open() fails nfsd_open() already returns an NFS error value; only vfs_test_lock() result needs to be fed through nfserrno(). Broken by commit 55ef12 (nfsd: Ensure nfsv4 calls the underlying filesystem on LOCKT) three years ago... Signed-off-by: Al Viro --- fs/nfsd/nfs4state.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1841f8bf845e..7f71c69cdcdf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4211,16 +4211,14 @@ out: * vfs_test_lock. (Arguably perhaps test_lock should be done with an * inode operation.) */ -static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) +static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) { struct file *file; - int err; - - err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); - if (err) - return err; - err = vfs_test_lock(file, lock); - nfsd_close(file); + __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); + if (!err) { + err = nfserrno(vfs_test_lock(file, lock)); + nfsd_close(file); + } return err; } @@ -4234,7 +4232,6 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct inode *inode; struct file_lock file_lock; struct nfs4_lockowner *lo; - int error; __be32 status; if (locks_in_grace()) @@ -4280,12 +4277,10 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_transform_lock_offset(&file_lock); - status = nfs_ok; - error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); - if (error) { - status = nfserrno(error); + status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); + if (status) goto out; - } + if (file_lock.fl_type != F_UNLCK) { status = nfserr_denied; nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); From 02f5fde5df0ea930e70f93763dd48beff182b208 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 00:10:34 -0400 Subject: [PATCH 216/438] nfsd: fix endianness breakage in TEST_STATEID handling ->ts_id_status gets nfs errno, i.e. it's already big-endian; no need to apply htonl() to it. Broken by commit 174568 (NFSD: Added TEST_STATEID operation) last year... Signed-off-by: Al Viro --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index bcd8904ab1e3..07a99b6d4bbe 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, *p++ = htonl(test_stateid->ts_num_ids); list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { - *p++ = htonl(stateid->ts_id_status); + *p++ = stateid->ts_id_status; } ADJUST_ARGS(); From afcf6792afd66209161495f691e19d4fc5460a93 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 00:15:37 -0400 Subject: [PATCH 217/438] nfsd: fix error value on allocation failure in nfsd4_decode_test_stateid() PTR_ERR(NULL) is going to be 0... Signed-off-by: Al Viro --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 07a99b6d4bbe..74c00bc92b9a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta for (i = 0; i < test_stateid->ts_num_ids; i++) { stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL); if (!stateid) { - status = PTR_ERR(stateid); + status = nfserrno(-ENOMEM); goto out; } From efe39651f08813180f37dc508d950fc7d92b29a8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 00:32:14 -0400 Subject: [PATCH 218/438] nfsd: fix compose_entry_fh() failure exits Restore the original logics ("fail on mountpoints, negatives and in case of fh_compose() failures"). Since commit 8177e (nfsd: clean up readdirplus encoding) that got broken - rv = fh_compose(fhp, exp, dchild, &cd->fh); if (rv) goto out; if (!dchild->d_inode) goto out; rv = 0; out: is equivalent to rv = fh_compose(fhp, exp, dchild, &cd->fh); out: and the second check has no effect whatsoever... Signed-off-by: Al Viro --- fs/nfsd/nfs3xdr.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 08c6e36ab2eb..43f46cd9edea 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static int +static __be32 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, const char *name, int namlen) { struct svc_export *exp; struct dentry *dparent, *dchild; - int rv = 0; + __be32 rv = nfserr_noent; dparent = cd->fh.fh_dentry; exp = cd->fh.fh_export; @@ -817,26 +817,20 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); - if (dchild == dparent) { - /* filesystem root - cannot return filehandle for ".." */ - dput(dchild); - return -ENOENT; - } + /* filesystem root - cannot return filehandle for ".." */ + if (dchild == dparent) + goto out; } else dchild = dget(dparent); } else dchild = lookup_one_len(name, dparent, namlen); if (IS_ERR(dchild)) - return -ENOENT; - rv = -ENOENT; + return rv; if (d_mountpoint(dchild)) goto out; - rv = fh_compose(fhp, exp, dchild, &cd->fh); - if (rv) - goto out; if (!dchild->d_inode) goto out; - rv = 0; + rv = fh_compose(fhp, exp, dchild, &cd->fh); out: dput(dchild); return rv; @@ -845,7 +839,7 @@ out: static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) { struct svc_fh fh; - int err; + __be32 err; fh_init(&fh, NFS3_FHSIZE); err = compose_entry_fh(cd, &fh, name, namlen); From af1584f570b19b0285e4402a0b54731495d31784 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 12 Apr 2012 20:32:25 -0400 Subject: [PATCH 219/438] ext4: fix endianness breakage in ext4_split_extent_at() ->ee_len is __le16, so assigning cpu_to_le32() to it is going to do Bad Things(tm) on big-endian hosts... Signed-off-by: Al Viro --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1421938e6792..1d418387ffb0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2882,7 +2882,7 @@ static int ext4_split_extent_at(handle_t *handle, if (err) goto fix_extent_len; /* update the extent length and mark as initialized */ - ex->ee_len = cpu_to_le32(ee_len); + ex->ee_len = cpu_to_le16(ee_len); ext4_ext_try_to_merge(inode, path, ex); err = ext4_ext_dirty(handle, inode, path + depth); goto out; From bfa890a3cdeed29eef53d54cd7f80cec0fd46b11 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Fri, 13 Apr 2012 14:04:32 +0100 Subject: [PATCH 220/438] Fix number parsing in cifs_parse_mount_options The function kstrtoul() used to parse number strings in the mount option parser is set to expect a base 10 number . This treats the octal numbers passed for mount options such as file_mode as base10 numbers leading to incorrect behavior. Change the 'base' argument passed to kstrtoul from 10 to 0 to allow it to auto-detect the base of the number passed. Signed-off-by: Sachin Prabhu Acked-by: Jeff Layton Reported-by: Chris Clayton Signed-off-by: Steve French --- fs/cifs/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6a86f3d68182..f31dc9ac37b7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1123,7 +1123,7 @@ static int get_option_ul(substring_t args[], unsigned long *option) string = match_strdup(args); if (string == NULL) return -ENOMEM; - rc = kstrtoul(string, 10, option); + rc = kstrtoul(string, 0, option); kfree(string); return rc; From 6ed3cf2cdfce4c9f1d73171bd3f27d9cb77b734e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 11:49:04 -0400 Subject: [PATCH 221/438] btrfs: btrfs_root_readonly() broken on big-endian ->root_flags is __le64 and all accesses to it go through the helpers that do proper conversions. Except for btrfs_root_readonly(), which checks bit 0 as in host-endian... Signed-off-by: Al Viro --- fs/btrfs/ctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 5b8ef8eb3521..3f65a812e282 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2166,7 +2166,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, static inline bool btrfs_root_readonly(struct btrfs_root *root) { - return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY; + return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; } /* struct btrfs_root_backup */ From 3a251f04fe97c3d335b745c98e4b377e3c3899f2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 12:22:00 -0400 Subject: [PATCH 222/438] ocfs2: ->l_next_free_req breakage on big-endian It's le16, not le32... Signed-off-by: Al Viro --- fs/ocfs2/alloc.c | 2 +- fs/ocfs2/refcounttree.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 3165aebb43c8..31b9463fba1f 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle, } el = path_leaf_el(path); - rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1]; + rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1]; ocfs2_adjust_rightmost_records(handle, et, path, rec); diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index cf7823382664..a7b7217062b7 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, tmp_el = left_path->p_node[subtree_root].el; blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; - for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { + for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) { if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); break; } } - BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); + BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec)); out: ocfs2_free_path(left_path); From e1bf4cc620fd143766ddfcee3b004a1d1bb34fd0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 12:27:11 -0400 Subject: [PATCH 223/438] ocfs: ->rl_used breakage on big-endian it's le16, not le32 or le64... Signed-off-by: Al Viro --- fs/ocfs2/refcounttree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index a7b7217062b7..bc90ebcec169 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, trace_ocfs2_divide_leaf_refcount_block( (unsigned long long)ref_leaf_bh->b_blocknr, - le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); + le32_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); /* * XXX: Improvement later. @@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, rb = (struct ocfs2_refcount_block *) prev_bh->b_data; - if (le64_to_cpu(rb->rf_records.rl_used) + + if (le16_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, if (prev_bh) { rb = (struct ocfs2_refcount_block *)prev_bh->b_data; - if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > + if (le16_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode, * one will split a refcount rec, so totally we need * clusters * 2 new refcount rec. */ - if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 > + if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; From 28748b325dc2d730ccc312830a91c4ae0c0d9379 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 12:28:21 -0400 Subject: [PATCH 224/438] ocfs2: ->rl_count endianness breakage le16, not le32... Signed-off-by: Al Viro --- fs/ocfs2/refcounttree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index bc90ebcec169..9f32d7cbb7a3 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, trace_ocfs2_divide_leaf_refcount_block( (unsigned long long)ref_leaf_bh->b_blocknr, - le32_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); + le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); /* * XXX: Improvement later. From 72094e43e3af5020510f920321d71f1798fa896d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 12:30:02 -0400 Subject: [PATCH 225/438] ocfs2: ->e_leaf_clusters endianness breakage le16, not le32... Signed-off-by: Al Viro --- fs/ocfs2/suballoc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ba5d97e4a73e..f169da4624fd 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle, ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode, cluster_ac->ac_bh, le64_to_cpu(rec->e_blkno), - le32_to_cpu(rec->e_leaf_clusters)); + le16_to_cpu(rec->e_leaf_clusters)); if (ret) mlog_errno(ret); /* Try all the clusters to free */ @@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, { unsigned int bpc = le16_to_cpu(cl->cl_bpc); unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc; - unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc; + unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc; if (res->sr_bit_offset < bitoff) return 0; From 5ba840f9da1ff96e0c6e982608a9e80e35333cc5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 2 Apr 2012 16:04:13 -0400 Subject: [PATCH 226/438] alpha: fix build failures from system.h dismemberment commit ec2212088c42ff7d1362629ec26dda4f3e8bdad3 "Disintegrate asm/system.h for Alpha" combined with commit b4816afa3986704d1404fc48e931da5135820472 "Move the asm-generic/system.h xchg() implementation to asm-generic/cmpxchg.h" introduced the concept of asm/cmpxchg.h but the alpha arch never got one. Fork the cmpxchg content out of the asm/atomic.h file to create one. Some minor whitespace fixups were done on the block of code that created the new file. Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Cc: David Howells Acked-by: Matt Turner Signed-off-by: Paul Gortmaker --- arch/alpha/include/asm/atomic.h | 68 +----------------------------- arch/alpha/include/asm/cmpxchg.h | 71 ++++++++++++++++++++++++++++++++ arch/alpha/include/asm/xchg.h | 4 +- 3 files changed, 74 insertions(+), 69 deletions(-) create mode 100644 arch/alpha/include/asm/cmpxchg.h diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index f62251e82ffa..3bb7ffeae3bc 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -3,6 +3,7 @@ #include #include +#include /* * Atomic operations that C can't guarantee us. Useful for @@ -168,73 +169,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) return result; } -/* - * Atomic exchange routines. - */ - -#define __ASM__MB -#define ____xchg(type, args...) __xchg ## type ## _local(args) -#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) -#include - -#define xchg_local(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) - -#define cmpxchg_local(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, \ - sizeof(*(ptr))); \ - }) - -#define cmpxchg64_local(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ - }) - -#ifdef CONFIG_SMP -#undef __ASM__MB -#define __ASM__MB "\tmb\n" -#endif -#undef ____xchg -#undef ____cmpxchg -#define ____xchg(type, args...) __xchg ##type(args) -#define ____cmpxchg(type, args...) __cmpxchg ##type(args) -#include - -#define xchg(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) - -#define cmpxchg(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr)));\ - }) - -#define cmpxchg64(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg((ptr), (o), (n)); \ - }) - -#undef __ASM__MB -#undef ____cmpxchg - -#define __HAVE_ARCH_CMPXCHG 1 - #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h new file mode 100644 index 000000000000..429e8cd0d78e --- /dev/null +++ b/arch/alpha/include/asm/cmpxchg.h @@ -0,0 +1,71 @@ +#ifndef _ALPHA_CMPXCHG_H +#define _ALPHA_CMPXCHG_H + +/* + * Atomic exchange routines. + */ + +#define __ASM__MB +#define ____xchg(type, args...) __xchg ## type ## _local(args) +#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) +#include + +#define xchg_local(ptr, x) \ +({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ +}) + +#define cmpxchg_local(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, \ + sizeof(*(ptr))); \ +}) + +#define cmpxchg64_local(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ +}) + +#ifdef CONFIG_SMP +#undef __ASM__MB +#define __ASM__MB "\tmb\n" +#endif +#undef ____xchg +#undef ____cmpxchg +#define ____xchg(type, args...) __xchg ##type(args) +#define ____cmpxchg(type, args...) __cmpxchg ##type(args) +#include + +#define xchg(ptr, x) \ +({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ +}) + +#define cmpxchg(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr)));\ +}) + +#define cmpxchg64(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg((ptr), (o), (n)); \ +}) + +#undef __ASM__MB +#undef ____cmpxchg + +#define __HAVE_ARCH_CMPXCHG 1 + +#endif /* _ALPHA_CMPXCHG_H */ diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h index 1d1b436fbff2..0ca9724597c1 100644 --- a/arch/alpha/include/asm/xchg.h +++ b/arch/alpha/include/asm/xchg.h @@ -1,10 +1,10 @@ -#ifndef _ALPHA_ATOMIC_H +#ifndef _ALPHA_CMPXCHG_H #error Do not include xchg.h directly! #else /* * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code * except that local version do not have the expensive memory barrier. - * So this file is included twice from asm/system.h. + * So this file is included twice from asm/cmpxchg.h. */ /* From 85f8f7759e418c814ee2ceacf73eddb9bed39492 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 3 Apr 2012 13:51:35 -0400 Subject: [PATCH 227/438] ia64: populate the cmpxchg header with appropriate code commit 93f378883cecb9dcb2cf5b51d9d24175906659da "Fix ia64 build errors (fallout from system.h disintegration)" introduced arch/ia64/include/asm/cmpxchg.h as a temporary build fix and stated: "... leave the migration of xchg() and cmpxchg() to this new header file for a future patch." Migrate the appropriate chunks from asm/intrinsics.h and fix the whitespace issues in the migrated chunk. Cc: Fenghua Yu Cc: David Howells Acked-by: Tony Luck Signed-off-by: Paul Gortmaker --- arch/ia64/include/asm/cmpxchg.h | 148 ++++++++++++++++++++++++++++- arch/ia64/include/asm/intrinsics.h | 114 +--------------------- 2 files changed, 148 insertions(+), 114 deletions(-) diff --git a/arch/ia64/include/asm/cmpxchg.h b/arch/ia64/include/asm/cmpxchg.h index 4c96187e2049..4f37dbbb8640 100644 --- a/arch/ia64/include/asm/cmpxchg.h +++ b/arch/ia64/include/asm/cmpxchg.h @@ -1 +1,147 @@ -#include +#ifndef _ASM_IA64_CMPXCHG_H +#define _ASM_IA64_CMPXCHG_H + +/* + * Compare/Exchange, forked from asm/intrinsics.h + * which was: + * + * Copyright (C) 2002-2003 Hewlett-Packard Co + * David Mosberger-Tang + */ + +#ifndef __ASSEMBLY__ + +#include +/* include compiler specific intrinsics */ +#include +#ifdef __INTEL_COMPILER +# include +#else +# include +#endif + +/* + * This function doesn't exist, so you'll get a linker error if + * something tries to do an invalid xchg(). + */ +extern void ia64_xchg_called_with_bad_pointer(void); + +#define __xchg(x, ptr, size) \ +({ \ + unsigned long __xchg_result; \ + \ + switch (size) { \ + case 1: \ + __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ + break; \ + \ + case 2: \ + __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ + break; \ + \ + case 4: \ + __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ + break; \ + \ + case 8: \ + __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ + break; \ + default: \ + ia64_xchg_called_with_bad_pointer(); \ + } \ + __xchg_result; \ +}) + +#define xchg(ptr, x) \ +((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ + +#define __HAVE_ARCH_CMPXCHG 1 + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid cmpxchg(). + */ +extern long ia64_cmpxchg_called_with_bad_pointer(void); + +#define ia64_cmpxchg(sem, ptr, old, new, size) \ +({ \ + __u64 _o_, _r_; \ + \ + switch (size) { \ + case 1: \ + _o_ = (__u8) (long) (old); \ + break; \ + case 2: \ + _o_ = (__u16) (long) (old); \ + break; \ + case 4: \ + _o_ = (__u32) (long) (old); \ + break; \ + case 8: \ + _o_ = (__u64) (long) (old); \ + break; \ + default: \ + break; \ + } \ + switch (size) { \ + case 1: \ + _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ + break; \ + \ + case 2: \ + _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ + break; \ + \ + case 4: \ + _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ + break; \ + \ + case 8: \ + _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ + break; \ + \ + default: \ + _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ + break; \ + } \ + (__typeof__(old)) _r_; \ +}) + +#define cmpxchg_acq(ptr, o, n) \ + ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) +#define cmpxchg_rel(ptr, o, n) \ + ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) + +/* for compatibility with other platforms: */ +#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) +#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) + +#define cmpxchg_local cmpxchg +#define cmpxchg64_local cmpxchg64 + +#ifdef CONFIG_IA64_DEBUG_CMPXCHG +# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; +# define CMPXCHG_BUGCHECK(v) \ +do { \ + if (_cmpxchg_bugcheck_count-- <= 0) { \ + void *ip; \ + extern int printk(const char *fmt, ...); \ + ip = (void *) ia64_getreg(_IA64_REG_IP); \ + printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\ + break; \ + } \ +} while (0) +#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ +# define CMPXCHG_BUGCHECK_DECL +# define CMPXCHG_BUGCHECK(v) +#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_IA64_CMPXCHG_H */ diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h index e4076b511829..d129e367e764 100644 --- a/arch/ia64/include/asm/intrinsics.h +++ b/arch/ia64/include/asm/intrinsics.h @@ -18,6 +18,7 @@ #else # include #endif +#include #define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I) @@ -81,119 +82,6 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ -/* - * This function doesn't exist, so you'll get a linker error if - * something tries to do an invalid xchg(). - */ -extern void ia64_xchg_called_with_bad_pointer (void); - -#define __xchg(x,ptr,size) \ -({ \ - unsigned long __xchg_result; \ - \ - switch (size) { \ - case 1: \ - __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ - break; \ - \ - case 2: \ - __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ - break; \ - \ - case 4: \ - __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ - break; \ - \ - case 8: \ - __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ - break; \ - default: \ - ia64_xchg_called_with_bad_pointer(); \ - } \ - __xchg_result; \ -}) - -#define xchg(ptr,x) \ - ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr)))) - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - */ - -#define __HAVE_ARCH_CMPXCHG 1 - -/* - * This function doesn't exist, so you'll get a linker error - * if something tries to do an invalid cmpxchg(). - */ -extern long ia64_cmpxchg_called_with_bad_pointer (void); - -#define ia64_cmpxchg(sem,ptr,old,new,size) \ -({ \ - __u64 _o_, _r_; \ - \ - switch (size) { \ - case 1: _o_ = (__u8 ) (long) (old); break; \ - case 2: _o_ = (__u16) (long) (old); break; \ - case 4: _o_ = (__u32) (long) (old); break; \ - case 8: _o_ = (__u64) (long) (old); break; \ - default: break; \ - } \ - switch (size) { \ - case 1: \ - _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ - break; \ - \ - case 2: \ - _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ - break; \ - \ - case 4: \ - _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ - break; \ - \ - case 8: \ - _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ - break; \ - \ - default: \ - _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ - break; \ - } \ - (__typeof__(old)) _r_; \ -}) - -#define cmpxchg_acq(ptr, o, n) \ - ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) -#define cmpxchg_rel(ptr, o, n) \ - ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) - -/* for compatibility with other platforms: */ -#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) -#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) - -#define cmpxchg_local cmpxchg -#define cmpxchg64_local cmpxchg64 - -#ifdef CONFIG_IA64_DEBUG_CMPXCHG -# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; -# define CMPXCHG_BUGCHECK(v) \ - do { \ - if (_cmpxchg_bugcheck_count-- <= 0) { \ - void *ip; \ - extern int printk(const char *fmt, ...); \ - ip = (void *) ia64_getreg(_IA64_REG_IP); \ - printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \ - break; \ - } \ - } while (0) -#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ -# define CMPXCHG_BUGCHECK_DECL -# define CMPXCHG_BUGCHECK(v) -#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ - #endif #ifdef __KERNEL__ From ef1f0982540e5f79c8bbf3675bbc0a9734dba3fc Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 11 Apr 2012 12:21:39 -0400 Subject: [PATCH 228/438] irq_work: fix compile failure on tile from missing include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building with IRQ_WORK configured results in kernel/irq_work.c: In function ‘irq_work_run’: kernel/irq_work.c:110: error: implicit declaration of function ‘irqs_disabled’ The appropriate header just needs to be included. Signed-off-by: Chris Metcalf Signed-off-by: Paul Gortmaker --- kernel/irq_work.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq_work.c b/kernel/irq_work.c index 0c56d44b9fd5..1588e3b2871b 100644 --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -11,6 +11,7 @@ #include #include #include +#include #include /* From 1c07ae43bb7f01480c0aceec36d1f27dd6c598bf Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 11 Apr 2012 21:04:02 -0700 Subject: [PATCH 229/438] arm: msm: halibut: remove unneeded fixup This old fixup causes a build failure, so I remove it just like in trout. Signed-off-by: Daniel Walker Signed-off-by: David Brown --- arch/arm/mach-msm/board-halibut.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 3698a370d636..26aac363a064 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -86,9 +86,6 @@ static void __init halibut_init(void) static void __init halibut_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) { - mi->nr_banks=1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = (101*1024*1024); } static void __init halibut_map_io(void) From 204241c27c8fa2186e6d656d587f941422fff1b9 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 12 Apr 2012 08:45:37 -0700 Subject: [PATCH 230/438] arm: msm: trout: fix compile failure Fixes the following warnings, arch/arm/mach-msm/board-trout.c: In function 'trout_init': arch/arm/mach-msm/board-trout.c:71: error: 'system_rev' undeclared (first use in this function) arch/arm/mach-msm/board-trout.c:71: error: (Each undeclared identifier is reported only once arch/arm/mach-msm/board-trout.c:71: error: for each function it appears in.) and arch/arm/mach-msm/board-trout-panel.c: In function 'trout_init_panel': arch/arm/mach-msm/board-trout-panel.c:267: error: 'system_rev' undeclared (first use in this function) arch/arm/mach-msm/board-trout-panel.c:267: error: (Each undeclared identifier is reported only once arch/arm/mach-msm/board-trout-panel.c:267: error: for each function it appears in.) This came in with the following commit 9f97da78bf018206fb623cd351d454af2f105fe0 which removes asm/system.h Signed-off-by: Daniel Walker cc: David Howells cc: Bryan Huntsman cc: linux-arm-msm@vger.kernel.org cc: linux-arm-kernel@lists.infradead.org Signed-off-by: David Brown --- arch/arm/mach-msm/board-trout-panel.c | 1 + arch/arm/mach-msm/board-trout.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c index 25105c1027fe..89bf6b426699 100644 --- a/arch/arm/mach-msm/board-trout-panel.c +++ b/arch/arm/mach-msm/board-trout-panel.c @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 5414f76ec0a9..d4060a37e23d 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include From e89c0e4377303a101d1032bf1dde822218372f15 Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 12 Apr 2012 11:36:50 -0700 Subject: [PATCH 231/438] video: msm: Fix section mismatches in mddi.c The change commit 461cbe77d0a4f887c33a3a95ea68a7daf23b4302 Author: Gregory Bean Date: Wed Jul 28 10:22:13 2010 -0700 video: msm: Fix section mismatch in mddi.c. fixes a section mismatch between the board file and the driver's probe function, however, it misses the additional mismatches between the probe function and some routines it calls. Fix these up as well. Signed-off-by: David Brown --- drivers/video/msm/mddi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index 4527cbf0a4ec..b061d709bc44 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -420,7 +420,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) mddi_set_auto_hibernate(&mddi->client_data, 1); } -static int __init mddi_get_client_caps(struct mddi_info *mddi) +static int __devinit mddi_get_client_caps(struct mddi_info *mddi) { int i, j; @@ -622,9 +622,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) static struct mddi_info mddi_info[2]; -static int __init mddi_clk_setup(struct platform_device *pdev, - struct mddi_info *mddi, - unsigned long clk_rate) +static int __devinit mddi_clk_setup(struct platform_device *pdev, + struct mddi_info *mddi, + unsigned long clk_rate) { int ret; From af33eadc73e4a5d35a966c1c7ffe28a8424c9d96 Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 12 Apr 2012 11:36:50 -0700 Subject: [PATCH 232/438] ARM: msm: Fix section mismatches in proc_comm.c The change commit 4416e9eb0b4859b3d28016c5fd0a609bdcbc8a2a Author: Gregory Bean Date: Wed Jul 28 10:22:12 2010 -0700 arm: msm: Fix section mismatch in smd.c. fixes a section mismatch between the board file and the smd driver's probe function, however, it misses the additional mismatches between the probe function and some routines it calls. Fix these up as well. Signed-off-by: David Brown --- arch/arm/mach-msm/proc_comm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c index 67e701c7f183..9980dc736e7b 100644 --- a/arch/arm/mach-msm/proc_comm.c +++ b/arch/arm/mach-msm/proc_comm.c @@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) * and unknown state. This function should be called early to * wait on the ARM9. */ -void __init proc_comm_boot_wait(void) +void __devinit proc_comm_boot_wait(void) { void __iomem *base = MSM_SHARED_RAM_BASE; From e847469bf77a1d339274074ed068d461f0c872bc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 13 Apr 2012 13:49:47 -0400 Subject: [PATCH 233/438] lockd: fix the endianness bug comparing be32 values for < is not doing the right thing... Signed-off-by: Al Viro --- fs/lockd/clnt4xdr.c | 2 +- fs/lockd/clntxdr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index 3ddcbb1c0a43..13ad1539fbf2 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c @@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(*p > nlm4_failed)) + if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) goto out_bad_xdr; *stat = *p; return 0; diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 3d35e3e80c1c..d269ada7670e 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c @@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr, p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(*p > nlm_lck_denied_grace_period)) + if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) goto out_enum; *stat = *p; return 0; From effcc625eb4ab3b10b4744237fd37e8f7dcd6511 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 28 Mar 2012 11:38:01 -0700 Subject: [PATCH 234/438] libertas: fix signedness bug in lbs_auth_to_authtype() Return type for lbs_auth_to_authtype() is changed from "u8" to "int" to return negative error code correctly. Also an error check is added in connect handler for invalid auth type. Reported-by: Dan Carpenter Signed-off-by: Amitkumar Karwar Signed-off-by: Kiran Divekar Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 3fa1ecebadfd..2fa879b015b6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = { * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1 * in the firmware spec */ -static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type) { int ret = -ENOTSUPP; @@ -1411,7 +1411,12 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - lbs_set_authtype(priv, sme); + ret = lbs_set_authtype(priv, sme); + if (ret == -ENOTSUPP) { + wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); + goto done; + } + lbs_set_radio(priv, preamble, 1); /* Do the actual association */ From badc4f07622f0f7093a201638f45e85765f1b5e4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 11 Apr 2012 11:52:51 +0200 Subject: [PATCH 235/438] brcm80211: smac: resume transmit fifo upon receiving frames There have been reports about not being able to use access-points on channel 12 and 13 or having connectivity issues when these channels were part of the selected regulatory domain. Upon switching to these channels the brcmsmac driver suspends the transmit dma fifos. This patch resumes them upon handing over the first received beacon to mac80211. This patch is to be applied to the stable tree for kernel versions 3.2 and 3.3. Cc: stable@vger.kernel.org Tested-by: Francesco Saverio Schiavarelli Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 231ddf4a674f..7083db75b00c 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -7614,6 +7614,7 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, { int len_mpdu; struct ieee80211_rx_status rx_status; + struct ieee80211_hdr *hdr; memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,6 +7624,13 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); + /* unmute transmit */ + if (wlc->hw->suspended_fifos) { + hdr = (struct ieee80211_hdr *)p->data; + if (ieee80211_is_beacon(hdr->frame_control)) + brcms_b_mute(wlc->hw, false); + } + memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); } From e55a4046dab28c440c96890bdddcf02dc8981f2d Mon Sep 17 00:00:00 2001 From: Lukasz Kucharczyk Date: Wed, 11 Apr 2012 14:55:10 +0200 Subject: [PATCH 236/438] cfg80211: fix interface combinations check. Signed-off-by: Lukasz Kucharczyk Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 1b7a08df933c..957f25621617 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -989,7 +989,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, if (rdev->wiphy.software_iftypes & BIT(iftype)) continue; for (j = 0; j < c->n_limits; j++) { - if (!(limits[j].types & iftype)) + if (!(limits[j].types & BIT(iftype))) continue; if (limits[j].max < num[iftype]) goto cont; From 32b92f4f3f261697a49f944e31920dbcbbd4ad01 Mon Sep 17 00:00:00 2001 From: Jonathan Bither Date: Thu, 12 Apr 2012 06:13:33 -0400 Subject: [PATCH 237/438] ath5k: fix undefined 'THIS_MODULE' When cross compiling ath5k for a Mips machine with kernel 3.2.14 the compilation fails with "/ath5k/ahb.c:231:12: error: 'THIS_MODULE' undeclared here (not in a function)" Fix the build by including Signed-off-by: Jonathan Bither Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8faa129da5a0..47b6c35077d6 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "ath5k.h" #include "debug.h" From 2db0d2ba97801fb57c91e99b9e22b2a24c32d3d7 Mon Sep 17 00:00:00 2001 From: Jonathan Bither Date: Thu, 12 Apr 2012 07:03:09 -0400 Subject: [PATCH 238/438] ath5k: unmap io memory on probe failure Signed-off-by: Jonathan Bither Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 47b6c35077d6..8c50d9d19d78 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -120,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (res == NULL) { dev_err(&pdev->dev, "no IRQ resource found\n"); ret = -ENXIO; - goto err_out; + goto err_iounmap; } irq = res->start; @@ -129,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (hw == NULL) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); ret = -ENOMEM; - goto err_out; + goto err_iounmap; } ah = hw->priv; @@ -186,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev) err_free_hw: ieee80211_free_hw(hw); platform_set_drvdata(pdev, NULL); + err_iounmap: + iounmap(mem); err_out: return ret; } From 75600abf1991657580233570400009e85f861787 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 12 Apr 2012 20:36:31 +0200 Subject: [PATCH 239/438] ath9k: wake up the hardware from full sleep when idle is turned off The hardware needs a reset to recover from full sleep. Issue this reset directly in the ath9k_config call that turns off idle, otherwise tx remains dead until the first channel change after the idle state change Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2504ab005589..798ea57252b4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1548,6 +1548,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; + bool reset_channel = false; ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); @@ -1556,6 +1557,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); if (sc->ps_idle) ath_cancel_work(sc); + else + /* + * The chip needs a reset to properly wake up from + * full sleep + */ + reset_channel = ah->chip_fullsleep; } /* @@ -1584,7 +1591,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; int old_pos = -1; From 428ca8a7065354877db63ceabfc493107686eebe Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 12 Apr 2012 19:00:35 -0700 Subject: [PATCH 240/438] mwifiex: update pcie8766 scratch register addresses The scratch register addresses have been changed for newer chips. Since the old chip was never shipped and it will not be supported any more, just update register addresses to support the new chips. Cc: # 3.2.y, 3.3.y Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 445ff21772e2..2f218f9a3fd3 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@ #define PCIE_HOST_INT_STATUS_MASK 0xC3C #define PCIE_SCRATCH_2_REG 0xC40 #define PCIE_SCRATCH_3_REG 0xC44 -#define PCIE_SCRATCH_4_REG 0xCC0 -#define PCIE_SCRATCH_5_REG 0xCC4 -#define PCIE_SCRATCH_6_REG 0xCC8 -#define PCIE_SCRATCH_7_REG 0xCCC -#define PCIE_SCRATCH_8_REG 0xCD0 -#define PCIE_SCRATCH_9_REG 0xCD4 -#define PCIE_SCRATCH_10_REG 0xCD8 -#define PCIE_SCRATCH_11_REG 0xCDC -#define PCIE_SCRATCH_12_REG 0xCE0 +#define PCIE_SCRATCH_4_REG 0xCD0 +#define PCIE_SCRATCH_5_REG 0xCD4 +#define PCIE_SCRATCH_6_REG 0xCD8 +#define PCIE_SCRATCH_7_REG 0xCDC +#define PCIE_SCRATCH_8_REG 0xCE0 +#define PCIE_SCRATCH_9_REG 0xCE4 +#define PCIE_SCRATCH_10_REG 0xCE8 +#define PCIE_SCRATCH_11_REG 0xCEC +#define PCIE_SCRATCH_12_REG 0xCF0 #define CPU_INTR_DNLD_RDY BIT(0) #define CPU_INTR_DOOR_BELL BIT(1) From 9e0daff30fd7ecf698e5d20b0fa7f851e427cca5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 13 Apr 2012 11:56:22 -0700 Subject: [PATCH 241/438] sparc64: Fix bootup crash on sun4v. The DS driver registers as a subsys_initcall() but this can be too early, in particular this risks registering before we've had a chance to allocate and setup module_kset in kernel/params.c which is performed also as a subsyts_initcall(). Register DS using device_initcall() insteal. Signed-off-by: David S. Miller Cc: stable@vger.kernel.org --- arch/sparc/kernel/ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index fea13c7b1aee..b93c2c9ccb1d 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -1264,4 +1264,4 @@ static int __init ds_init(void) return vio_register_driver(&ds_driver); } -subsys_initcall(ds_init); +fs_initcall(ds_init); From 3d3eeb2ef26112a200785e5fca58ec58dd33bf1e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 13 Apr 2012 03:35:13 +0000 Subject: [PATCH 242/438] sparc64: Eliminate obsolete __handle_softirq() function The invocation of softirq is now handled by irq_exit(), so there is no need for sparc64 to invoke it on the trap-return path. In fact, doing so is a bug because if the trap occurred in the idle loop, this invocation can result in lockdep-RCU failures. The problem is that RCU ignores idle CPUs, and the sparc64 trap-return path to the softirq handlers fails to tell RCU that the CPU must be considered non-idle while those handlers are executing. This means that RCU is ignoring any RCU read-side critical sections in those handlers, which in turn means that RCU-protected data can be yanked out from under those read-side critical sections. The shiny new lockdep-RCU ability to detect RCU read-side critical sections that RCU is ignoring located this problem. The fix is straightforward: Make sparc64 stop manually invoking the softirq handlers. Reported-by: Meelis Roos Suggested-by: David Miller Signed-off-by: Paul E. McKenney Tested-by: Meelis Roos Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- arch/sparc/kernel/rtrap_64.S | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 77f1b95e0806..9171fc238def 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -20,11 +20,6 @@ .text .align 32 -__handle_softirq: - call do_softirq - nop - ba,a,pt %xcc, __handle_softirq_continue - nop __handle_preemption: call schedule wrpr %g0, RTRAP_PSTATE, %pstate @@ -89,9 +84,7 @@ rtrap: cmp %l1, 0 /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ - bne,pn %icc, __handle_softirq ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 -__handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 From 2d59dcfb54ade45cacc59a6e7bd96b8c19088c3d Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 13 Apr 2012 13:32:30 -0700 Subject: [PATCH 243/438] cpufreq: OMAP: fix build errors: depends on ARCH_OMAP2PLUS The OMAP driver needs a 'depends on ARCH_OMAP2PLUS' since it only builds for OMAP2+ platforms. This 'depends on' was in the original patch from Russell King, but was erroneously removed by me when making this option user-selectable in commit b09db45c (cpufreq: OMAP driver depends CPUfreq tables.) This patch remedies that. Apologies to Russell King for breaking his originally working patch. Also, thanks to Grazvydas Ignotas for reporting the same problem. Cc: Russell King Cc: Grazvydas Ignotas Signed-off-by: Kevin Hilman Signed-off-by: Linus Torvalds --- drivers/cpufreq/Kconfig.arm | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index ffbb44685915..5961e6415f08 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -4,6 +4,7 @@ config ARM_OMAP2PLUS_CPUFREQ bool "TI OMAP2+" + depends on ARCH_OMAP2PLUS default ARCH_OMAP2PLUS select CPU_FREQ_TABLE From 3cd21f6162e7703adc13c5030f316db9ec6bf5cf Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Sat, 14 Apr 2012 07:42:04 -0700 Subject: [PATCH 244/438] ARM: SAMSUNG: make SAMSUNG_PM_DEBUG select DEBUG_LL When selecting SAMSUNG_PM_DEBUG, it complains about a missing printascii() function if you do not select DEBUG_LL, so make the former select the latter. Signed-off-by: Maurus Cuelenaere Acked-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 71553f410016..a0ffc77da809 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -302,6 +302,7 @@ comment "Power management" config SAMSUNG_PM_DEBUG bool "S3C2410 PM Suspend debug" depends on PM + select DEBUG_LL help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See From f441f8a0a180827e3f7bd705aed9cffba62cebc2 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Apr 2012 21:10:32 -0700 Subject: [PATCH 245/438] ARM: EXYNOS: fix regulator name for NURI board Regulator names should not contain slash to avoid issues with debugfs. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mach-nuri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index b3982c867c9c..f92ec88b1266 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -571,7 +571,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = { static struct regulator_init_data __initdata max8997_ldo8_data = { .constraints = { - .name = "VUSB/VDAC_3.3V_C210", + .name = "VUSB+VDAC_3.3V_C210", .min_uV = 3300000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_STATUS, From 3d3231b1c986aa3ee1d94ffe36082faf45f0d96b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Apr 2012 21:10:32 -0700 Subject: [PATCH 246/438] ARM: EXYNOS: set fix xusbxti clock for NURI and Universal210 boards On some versions of NURI and UniversalC210 boards, camera clocks are routed directly to xusbxti clock source. This patch sets the correct value for this clock to let usb and camera sensors to work correctly and avoid division by zero on driver's probe. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mach-nuri.c | 2 +- arch/arm/mach-exynos/mach-universal_c210.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index f92ec88b1266..dd3ec8eef841 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -1347,6 +1347,7 @@ static struct platform_device *nuri_devices[] __initdata = { static void __init nuri_map_io(void) { + clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); @@ -1379,7 +1380,6 @@ static void __init nuri_machine_init(void) nuri_camera_init(); nuri_ehci_init(); - clk_xusbxti.rate = 24000000; /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 6bb9dbdd73fd..7ebf79c2ab34 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -1057,6 +1058,7 @@ static struct platform_device *universal_devices[] __initdata = { static void __init universal_map_io(void) { + clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); From 5262c543317cf362fe7223563609efaeb555f716 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Apr 2012 21:10:32 -0700 Subject: [PATCH 247/438] ARM: EXYNOS: Remove broken config values for touchscren for NURI board The atmel_mxt_ts driver has been extended to support more 'configuration objects' in commit 81c88a711 ("Input: atmel_mxt_ts - update object list"), what broke the configuration values for NURI board. These values are optional anyway, so remove them to get the driver working correctly. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mach-nuri.c | 42 -------------------------------- 1 file changed, 42 deletions(-) diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index dd3ec8eef841..b4f1f902ce6d 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -307,49 +307,7 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; /* TSP */ -static u8 mxt_init_vals[] = { - /* MXT_GEN_COMMAND(6) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_GEN_POWER(7) */ - 0x20, 0xff, 0x32, - /* MXT_GEN_ACQUIRE(8) */ - 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, - /* MXT_TOUCH_MULTI(9) */ - 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, - /* MXT_TOUCH_KEYARRAY(15) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, - /* MXT_SPT_GPIOPWM(19) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_GRIPFACE(20) */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, - 0x0f, 0x0a, - /* MXT_PROCG_NOISE(22) */ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, - 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, - /* MXT_TOUCH_PROXIMITY(23) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_ONETOUCH(24) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_SPT_SELFTEST(25) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_TWOTOUCH(27) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_SPT_CTECONFIG(28) */ - 0x00, 0x00, 0x02, 0x08, 0x10, 0x00, -}; - static struct mxt_platform_data mxt_platform_data = { - .config = mxt_init_vals, - .config_length = ARRAY_SIZE(mxt_init_vals), - .x_line = 18, .y_line = 11, .x_size = 1024, From 2084c24a81413b75bc97e4bee56b32ffece70460 Mon Sep 17 00:00:00 2001 From: Lubos Lunak Date: Wed, 21 Mar 2012 14:08:24 +0100 Subject: [PATCH 248/438] do not export kernel's NULL #define to userspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC's NULL is actually __null, which allows detecting some questionable NULL usage and warn about it. Moreover each platform/compiler should have its own stddef.h anyway (which is different from linux/stddef.h). So there's no good reason to leak kernel's NULL to userspace and override what the compiler provides. Signed-off-by: Luboš Luňák Acked-by: Arnd Bergmann Signed-off-by: Linus Torvalds --- include/linux/stddef.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/include/linux/stddef.h b/include/linux/stddef.h index 6a40c76bdcf1..1747b6787b9e 100644 --- a/include/linux/stddef.h +++ b/include/linux/stddef.h @@ -3,15 +3,11 @@ #include -#undef NULL -#if defined(__cplusplus) -#define NULL 0 -#else -#define NULL ((void *)0) -#endif - #ifdef __KERNEL__ +#undef NULL +#define NULL ((void *)0) + enum { false = 0, true = 1 From 5ad14306a3f468df61e1739f9f252663f18f1702 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 14 Apr 2012 07:53:51 -0700 Subject: [PATCH 249/438] ARM: EXYNOS: Fix Kconfig dependencies for device tree enabled machine files Add config dependency for Exynos4 and Exynos5 device tree enabled machine files on config options ARCH_EXYNOS4 and ARCH_EXYNOS5 respectively. Enabling machine support without proper ARCH support enabled is incorrect. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 0491ceef1cda..e81c35f936b5 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -368,6 +368,7 @@ comment "Flattened Device Tree based board for EXYNOS SoCs" config MACH_EXYNOS4_DT bool "Samsung Exynos4 Machine using device tree" + depends on ARCH_EXYNOS4 select CPU_EXYNOS4210 select USE_OF select ARM_AMBA @@ -380,6 +381,7 @@ config MACH_EXYNOS4_DT config MACH_EXYNOS5_DT bool "SAMSUNG EXYNOS5 Machine using device tree" + depends on ARCH_EXYNOS5 select SOC_EXYNOS5250 select USE_OF select ARM_AMBA From 2a5204fed0f313f9b55a7b4d5f48ca484446d095 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 11 Apr 2012 12:39:51 +0200 Subject: [PATCH 250/438] perf tools: Fix parsers' rules to dependencies Currently the parsers objects (bison/flex related) are each time perf is built. No matter the generated files are already in place, the parser generation is executed every time. Changing the rules to have proper flex/bison objects generation dependencies. The parsers code is not rebuilt until the flex/bison source files are touched. Also when flex/bison source is changed, only dependent objects are rebuilt. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1334140791-3024-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index a20d0c599b22..03059e75665a 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -237,21 +237,20 @@ export PERL_PATH FLEX = $(CROSS_COMPILE)flex BISON= $(CROSS_COMPILE)bison -event-parser: - $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c +$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c -$(OUTPUT)util/parse-events-flex.c: event-parser -$(OUTPUT)util/parse-events-bison.c: event-parser +$(OUTPUT)util/parse-events-bison.c: util/parse-events.y + $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c -pmu-parser: - $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c +$(OUTPUT)util/pmu-flex.c: util/pmu.l $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c -$(OUTPUT)util/pmu-flex.c: pmu-parser -$(OUTPUT)util/pmu-bison.c: pmu-parser +$(OUTPUT)util/pmu-bison.c: util/pmu.y + $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -$(OUTPUT)util/parse-events.o: event-parser pmu-parser +$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c +$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c LIB_FILE=$(OUTPUT)libperf.a @@ -852,8 +851,6 @@ help: @echo ' html - make html documentation' @echo ' info - make GNU info documentation (access with info )' @echo ' pdf - make pdf documentation' - @echo ' event-parser - make event parser code' - @echo ' pmu-parser - make pmu format parser code' @echo ' TAGS - use etags to make tag information for source browsing' @echo ' tags - use ctags to make tag information for source browsing' @echo ' cscope - use cscope to make interactive browsing database' From 77394ad6e465ee3cc3d3cf448c8500c57ced60bf Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 9 Apr 2012 14:11:14 +0900 Subject: [PATCH 251/438] perf tools: Ignore auto-generated bison/flex files The commit 65f3e56e0c81 ("perf tools: Remove auto-generated bison/flex files") removed those files from git, so they'll be listed on untracked files after building perf. Fix it. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1333948274-20043-1-git-send-email-namhyung.kim@lge.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 416684be0ad3..26b823b61aa1 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -19,3 +19,5 @@ TAGS cscope* config.mak config.mak.autogen +*-bison.* +*-flex.* From e3b6193378e8549d04849eda496129f94406ed36 Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Mon, 2 Apr 2012 15:28:29 +0900 Subject: [PATCH 252/438] perf archive: Correct cutting of symbolic link If a '$PERF_BUILDID_DIR'(typically $HOME/.debug) is a symbolic link directory, cutting of the path will fail. Here is an example where a buildid directory is a symbolic link. / # ls -al /root lrwxrwxrwx 1 root root 13 Mar 26 2012 /root -> opt/home/root / # cd ~ /opt/home/root # perf record -a -g sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.322 MB perf.data (~14057 samples) ] /opt/home/root # perf archive tar: Removing leading `/' from member names Now please run: $ tar xvf perf.data.tar.bz2 -C ~/.debug wherever you need to run 'perf report' on. /opt/home/root # mkdir temp /opt/home/root # tar xf perf.data.tar.bz2 -C ./temp /opt/home/root # find ./temp -name "*kernel*" ./temp/opt/home/root/.debug/[kernel.kallsyms] -> If successfully cut off the path, [kernel.kallsyms] is located in top of the archived file. This patch enables to cut correctly even if the buildid directory is a symbolic link. Signed-off-by: Chanho Park Signed-off-by: Kyungmin Park Cc: Ingo Molnar Cc: Kyungmin Park Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1333348109-12598-1-git-send-email-chanho61.park@samsung.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf-archive.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index 677e59d62a8d..95b6f8b6177a 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -29,13 +29,14 @@ if [ ! -s $BUILDIDS ] ; then fi MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX) +PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/ cut -d ' ' -f 1 $BUILDIDS | \ while read build_id ; do linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2} filename=$(readlink -f $linkname) echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST - echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST + echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST From eb03f28002c3dc96cbb8d3869df2d8aef3ef3b01 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 12 Apr 2012 10:17:28 -0500 Subject: [PATCH 253/438] ARM: dts: remove blank interrupt-parent properties These were incorrectly introduced and can cause problems for of_irq_init. The correct way to define a root controller is no interrupt-parent set at all or the interrupt-parent is set to the root controller itself when inherited from a parent node. Signed-off-by: Rob Herring Tested-by: Lee Jones Signed-off-by: Olof Johansson --- arch/arm/boot/dts/at91sam9g20.dtsi | 1 - arch/arm/boot/dts/at91sam9g45.dtsi | 1 - arch/arm/boot/dts/at91sam9x5.dtsi | 1 - arch/arm/boot/dts/db8500.dtsi | 1 - arch/arm/boot/dts/highbank.dts | 1 - 5 files changed, 5 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 799ad1889b51..773ef484037a 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -55,7 +55,6 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; - interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 9e6eb6ecea0e..c8042147eaa2 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -56,7 +56,6 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; - interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 70ab3a4e026f..dd4ed748469a 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -54,7 +54,6 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; - interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/arch/arm/boot/dts/db8500.dtsi b/arch/arm/boot/dts/db8500.dtsi index d73dce645667..14bc30705099 100644 --- a/arch/arm/boot/dts/db8500.dtsi +++ b/arch/arm/boot/dts/db8500.dtsi @@ -24,7 +24,6 @@ #interrupt-cells = <3>; #address-cells = <1>; interrupt-controller; - interrupt-parent; reg = <0xa0411000 0x1000>, <0xa0410100 0x100>; }; diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 37c0ff9c8b90..83e72294aefb 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -89,7 +89,6 @@ #size-cells = <0>; #address-cells = <1>; interrupt-controller; - interrupt-parent; reg = <0xfff11000 0x1000>, <0xfff10100 0x100>; }; From 47d9e44d1dbabc53500e86d5597f2737a40f1f42 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 13 Apr 2012 13:52:15 -0700 Subject: [PATCH 254/438] ARM: OMAP: clock: cleanup CPUfreq leftovers, fix build errors Now that we have OPP layer, and OMAP CPUfreq driver is using it, we no longer need/use the clock framework code for filling up CPUfreq tables. Remove it. Removing this code also eliminates build errors when CPU_FREQ_TABLE support is not enabled. Thanks to Russell King for pointing out the parts I missed under plat-omap in the original version and also pointing out the build errors when CPUFREQ_TABLE support was not enabled. Cc: Russell King Signed-off-by: Kevin Hilman Acked-by: Paul Walmsley Acked-by: Tony Lindgren Signed-off-by: Olof Johansson --- arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 80 -------------------- arch/arm/mach-omap2/clock.c | 5 -- arch/arm/mach-omap2/clock.h | 8 -- arch/arm/plat-omap/clock.c | 26 ------- arch/arm/plat-omap/include/plat/clock.h | 10 --- 5 files changed, 129 deletions(-) diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 7072e0d651b1..3d9d746b221a 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -165,83 +165,3 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) return 0; } - -#ifdef CONFIG_CPU_FREQ -/* - * Walk PRCM rate table and fillout cpufreq freq_table - * XXX This should be replaced by an OPP layer in the near future - */ -static struct cpufreq_frequency_table *freq_table; - -void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) -{ - const struct prcm_config *prcm; - int i = 0; - int tbl_sz = 0; - - if (!cpu_is_omap24xx()) - return; - - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sclk->rate) - continue; - - /* don't put bypass rates in table */ - if (prcm->dpll_speed == prcm->xtal_speed) - continue; - - tbl_sz++; - } - - /* - * XXX Ensure that we're doing what CPUFreq expects for this error - * case and the following one - */ - if (tbl_sz == 0) { - pr_warning("%s: no matching entries in rate_table\n", - __func__); - return; - } - - /* Include the CPUFREQ_TABLE_END terminator entry */ - tbl_sz++; - - freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, - GFP_ATOMIC); - if (!freq_table) { - pr_err("%s: could not kzalloc frequency table\n", __func__); - return; - } - - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sclk->rate) - continue; - - /* don't put bypass rates in table */ - if (prcm->dpll_speed == prcm->xtal_speed) - continue; - - freq_table[i].index = i; - freq_table[i].frequency = prcm->mpu_speed / 1000; - i++; - } - - freq_table[i].index = i; - freq_table[i].frequency = CPUFREQ_TABLE_END; - - *table = &freq_table[0]; -} - -void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) -{ - if (!cpu_is_omap24xx()) - return; - - kfree(freq_table); -} - -#endif diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index f57ed5baeccf..d9f4931513f9 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -536,10 +536,5 @@ struct clk_functions omap2_clk_functions = { .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, -#ifdef CONFIG_CPU_FREQ - /* These will be removed when the OPP code is integrated */ - .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, - .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, -#endif }; diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index b8c2a686481c..a1bb23a23351 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -146,14 +146,6 @@ extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; extern const struct clksel_rate dsp_ick_rates[]; -#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) -extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); -extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); -#else -#define omap2_clk_init_cpufreq_table 0 -#define omap2_clk_exit_cpufreq_table 0 -#endif - extern const struct clkops clkops_omap2_iclk_dflt_wait; extern const struct clkops clkops_omap2_iclk_dflt; extern const struct clkops clkops_omap2_iclk_idle_only; diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 8506cbb7fea4..62ec5c452792 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -398,32 +398,6 @@ struct clk dummy_ck = { .ops = &clkops_null, }; -#ifdef CONFIG_CPU_FREQ -void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) -{ - unsigned long flags; - - if (!arch_clock || !arch_clock->clk_init_cpufreq_table) - return; - - spin_lock_irqsave(&clockfw_lock, flags); - arch_clock->clk_init_cpufreq_table(table); - spin_unlock_irqrestore(&clockfw_lock, flags); -} - -void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) -{ - unsigned long flags; - - if (!arch_clock || !arch_clock->clk_exit_cpufreq_table) - return; - - spin_lock_irqsave(&clockfw_lock, flags); - arch_clock->clk_exit_cpufreq_table(table); - spin_unlock_irqrestore(&clockfw_lock, flags); -} -#endif - /* * */ diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 240a7b9fd946..d0ef57c1d71b 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -272,8 +272,6 @@ struct clk { #endif }; -struct cpufreq_frequency_table; - struct clk_functions { int (*clk_enable)(struct clk *clk); void (*clk_disable)(struct clk *clk); @@ -283,10 +281,6 @@ struct clk_functions { void (*clk_allow_idle)(struct clk *clk); void (*clk_deny_idle)(struct clk *clk); void (*clk_disable_unused)(struct clk *clk); -#ifdef CONFIG_CPU_FREQ - void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); - void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); -#endif }; extern int mpurate; @@ -301,10 +295,6 @@ extern void recalculate_root_clocks(void); extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); unsigned long omap_fixed_divisor_recalc(struct clk *clk); -#ifdef CONFIG_CPU_FREQ -extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); -extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); -#endif extern struct clk *omap_clk_get_by_name(const char *name); extern int omap_clk_enable_autoidle_all(void); extern int omap_clk_disable_autoidle_all(void); From 1a87228f5f1d316002c7c161316f5524592be766 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 12 Apr 2012 15:36:34 +1000 Subject: [PATCH 255/438] virtio_balloon: Fix endian bug Although virtio config space fields are usually in guest-native endian, the spec for the virtio balloon device explicitly states that both fields in its config space are little-endian. However, the current virtio_balloon driver does not have a suitable endian swap for the 'num_pages' field, although it does have one for the 'actual' field. This patch corrects the bug, adding sparse annotation while we're at it. Signed-off-by: David Gibson Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_balloon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 05f0a80818a2..9e95ca602006 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -234,11 +234,14 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { - u32 v; + __le32 v; + s64 target; + vb->vdev->config->get(vb->vdev, offsetof(struct virtio_balloon_config, num_pages), &v, sizeof(v)); - return (s64)v - vb->num_pages; + target = le32_to_cpu(v); + return target - vb->num_pages; } static void update_balloon_size(struct virtio_balloon *vb) From 3ccc9372ed0fab33d20f10be3c1efd5776ff5913 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 12 Apr 2012 16:38:00 +0300 Subject: [PATCH 256/438] virtio_balloon: fix handling of PAGE_SIZE != 4k As reported by David Gibson, current code handles PAGE_SIZE != 4k completely wrong which can lead to guest memory corruption errors: - page_to_balloon_pfn is wrong: e.g. on system with 64K page size it gives the same pfn value for 16 different pages. - we also need to convert back to linux pfns when we free. - for each linux page we need to tell host about multiple balloon pages, but code only adds one pfn to the array. This patch fixes all that, tested with a 64k ppc64 kernel. Reported-by: David Gibson Tested-by: David Gibson Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_balloon.c | 51 ++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 9e95ca602006..c2d05a8279fd 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -28,6 +28,13 @@ #include #include +/* + * Balloon device works in 4K page units. So each page is pointed to by + * multiple balloon pages. All memory counters in this driver are in balloon + * page units. + */ +#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) + struct virtio_balloon { struct virtio_device *vdev; @@ -42,8 +49,13 @@ struct virtio_balloon /* Waiting for host to ack the pages we released. */ struct completion acked; - /* The pages we've told the Host we're not using. */ + /* Number of balloon pages we've told the Host we're not using. */ unsigned int num_pages; + /* + * The pages we've told the Host we're not using. + * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE + * to num_pages above. + */ struct list_head pages; /* The array of pfns we tell the Host about. */ @@ -66,7 +78,13 @@ static u32 page_to_balloon_pfn(struct page *page) BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); /* Convert pfn from Linux page size to balloon page size. */ - return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); + return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; +} + +static struct page *balloon_pfn_to_page(u32 pfn) +{ + BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); + return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE); } static void balloon_ack(struct virtqueue *vq) @@ -96,12 +114,23 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) wait_for_completion(&vb->acked); } +static void set_page_pfns(u32 pfns[], struct page *page) +{ + unsigned int i; + + /* Set balloon pfns pointing at this page. + * Note that the first pfn points at start of the page. */ + for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++) + pfns[i] = page_to_balloon_pfn(page) + i; +} + static void fill_balloon(struct virtio_balloon *vb, size_t num) { /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { + for (vb->num_pfns = 0; vb->num_pfns < num; + vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (!page) { @@ -113,9 +142,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) msleep(200); break; } - vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); + set_page_pfns(vb->pfns + vb->num_pfns, page); + vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; totalram_pages--; - vb->num_pages++; list_add(&page->lru, &vb->pages); } @@ -130,8 +159,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) { unsigned int i; - for (i = 0; i < num; i++) { - __free_page(pfn_to_page(pfns[i])); + /* Find pfns pointing at start of each page, get pages and free them. */ + for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { + __free_page(balloon_pfn_to_page(pfns[i])); totalram_pages++; } } @@ -143,11 +173,12 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { + for (vb->num_pfns = 0; vb->num_pfns < num; + vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { page = list_first_entry(&vb->pages, struct page, lru); list_del(&page->lru); - vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); - vb->num_pages--; + set_page_pfns(vb->pfns + vb->num_pfns, page); + vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; } /* From 919f797a4c9c22ff5ec059744dba364dc600ece2 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Sat, 14 Apr 2012 23:01:28 -0400 Subject: [PATCH 257/438] SCSI: Fix error handling when no ULD is attached Commit 18a4d0a22ed6 ("[SCSI] Handle disk devices which can not process medium access commands") introduced a bug in which we would attempt to dereference the scsi driver even when the device had no ULD attached. Ensure that a driver is registered and make the driver accessor function more resilient to errors during device discovery. Reported-by: Elric Fu Reported-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Linus Torvalds --- drivers/scsi/scsi_error.c | 2 +- include/scsi/scsi_cmnd.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 2cfcbffa41fd..386f0c53bea7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -835,7 +835,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, scsi_eh_restore_cmnd(scmd, &ses); - if (sdrv->eh_action) + if (sdrv && sdrv->eh_action) rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); return rtn; diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 377df4a28512..1e1198546c72 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -134,6 +134,9 @@ struct scsi_cmnd { static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) { + if (!cmd->request->rq_disk) + return NULL; + return *(struct scsi_driver **)cmd->request->rq_disk->private_data; } From ebfc5b802fa76baeb4371311ff9fc27a2258d90d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 15 Apr 2012 21:40:40 +0200 Subject: [PATCH 258/438] PCI: Fix regression in pci_restore_state(), v3 Commit 26f41062f28d ("PCI: check for pci bar restore completion and retry") attempted to address problems with PCI BAR restoration on systems where FLR had not been completed before pci_restore_state() was called, but it did that in an utterly wrong way. First off, instead of retrying the writes for the BAR registers only, it did that for all of the PCI config space of the device, including the status register (whose value after the write quite obviously need not be the same as the written one). Second, it added arbitrary delay to pci_restore_state() even for systems where the PCI config space restoration was successful at first attempt. Finally, the mdelay(10) it added to every iteration of the writing loop was way too much of a delay for any reasonable device. All of this actually caused resume failures for some devices on Mikko's system. To fix the regression, make pci_restore_state() only retry the writes for BAR registers and only wait if the first read from the register doesn't return the written value. Additionaly, make it wait for 1 ms, instead of 10 ms, after every failing attempt to write into config space. Reported-by: Mikko Vinni Signed-off-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds --- drivers/pci/pci.c | 57 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 815674415267..d20f1334792b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -967,16 +967,47 @@ pci_save_state(struct pci_dev *dev) return 0; } +static void pci_restore_config_dword(struct pci_dev *pdev, int offset, + u32 saved_val, int retry) +{ + u32 val; + + pci_read_config_dword(pdev, offset, &val); + if (val == saved_val) + return; + + for (;;) { + dev_dbg(&pdev->dev, "restoring config space at offset " + "%#x (was %#x, writing %#x)\n", offset, val, saved_val); + pci_write_config_dword(pdev, offset, saved_val); + if (retry-- <= 0) + return; + + pci_read_config_dword(pdev, offset, &val); + if (val == saved_val) + return; + + mdelay(1); + } +} + +static void pci_restore_config_space(struct pci_dev *pdev, int start, int end, + int retry) +{ + int index; + + for (index = end; index >= start; index--) + pci_restore_config_dword(pdev, 4 * index, + pdev->saved_config_space[index], + retry); +} + /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ void pci_restore_state(struct pci_dev *dev) { - int i; - u32 val; - int tries; - if (!dev->state_saved) return; @@ -984,24 +1015,14 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_pcie_state(dev); pci_restore_ats_state(dev); + pci_restore_config_space(dev, 10, 15, 0); /* * The Base Address register should be programmed before the command * register(s) */ - for (i = 15; i >= 0; i--) { - pci_read_config_dword(dev, i * 4, &val); - tries = 10; - while (tries && val != dev->saved_config_space[i]) { - dev_dbg(&dev->dev, "restoring config " - "space at offset %#x (was %#x, writing %#x)\n", - i, val, (int)dev->saved_config_space[i]); - pci_write_config_dword(dev,i * 4, - dev->saved_config_space[i]); - pci_read_config_dword(dev, i * 4, &val); - mdelay(10); - tries--; - } - } + pci_restore_config_space(dev, 4, 9, 10); + pci_restore_config_space(dev, 0, 3, 0); + pci_restore_pcix_state(dev); pci_restore_msi_state(dev); pci_restore_iov_state(dev); From 9f85550347f51c79a917b2aec04c90691c11e20a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 10 Apr 2012 12:37:42 +0100 Subject: [PATCH 259/438] ARM: 7359/2: smp_twd: Only wait for reprogramming on active cpus During booting of cpu1, there is a short window where cpu1 is online, but not active where cpu1 is occupied by waiting to become active. If cpu0 then decides to schedule something on cpu1 and wait for it to complete, before cpu0 has set cpu1 active, we have a deadlock. Typically it's this CPU frequency transition that happens at this time, so let's just not wait for it to happen, it will happen whenever the CPU eventually comes online instead. Cc: Peter Zijlstra Cc: stable@kernel.org Signed-off-by: Jonas Aaberg Reviewed-by: Rickard Andersson Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/kernel/smp_twd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index fef42b21cecb..5b150afb995b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -118,10 +118,14 @@ static int twd_cpufreq_transition(struct notifier_block *nb, * The twd clock events must be reprogrammed to account for the new * frequency. The timer is local to a cpu, so cross-call to the * changing cpu. + * + * Only wait for it to finish, if the cpu is active to avoid + * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during + * booting of that cpu. */ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, 1); + NULL, cpu_active(freqs->cpu)); return NOTIFY_OK; } From e5ab85800820edd907d3f43f285e1232f84d5a41 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 12 Apr 2012 17:15:08 +0100 Subject: [PATCH 260/438] ARM: 7382/1: mm: truncate memory banks to fit in 4GB space for classic MMU If a bank of memory spanning the 4GB boundary is added on a !CONFIG_LPAE kernel then we will hang early during boot since the memory bank will have wrapped around to zero. This patch truncates memory banks for !LPAE configurations when the end address is not representable in 32 bits. Acked-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b91411371ae1..ebfac782593f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -523,7 +523,21 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); - bank->size = size & PAGE_MASK; + +#ifndef CONFIG_LPAE + if (bank->start + size < bank->start) { + printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " + "32-bit physical address space\n", (long long)start); + /* + * To ensure bank->start + bank->size is representable in + * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. + * This means we lose a page after masking. + */ + size = ULONG_MAX - bank->start; + } +#endif + + bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or From 078c04545ba56da21567728a909a496df5ff730d Mon Sep 17 00:00:00 2001 From: Jonathan Austin Date: Thu, 12 Apr 2012 17:45:25 +0100 Subject: [PATCH 261/438] ARM: 7384/1: ThumbEE: Disable userspace TEEHBR access for !CONFIG_ARM_THUMBEE Currently when ThumbEE is not enabled (!CONFIG_ARM_THUMBEE) the ThumbEE register states are not saved/restored at context switch. The default state of the ThumbEE Ctrl register (TEECR) allows userspace accesses to the ThumbEE Base Handler register (TEEHBR). This can cause unexpected behaviour when people use ThumbEE on !CONFIG_ARM_THUMBEE kernels, as well as allowing covert communication - eg between userspace tasks running inside chroot jails. This patch sets up TEECR in order to prevent user-space access to TEEHBR when !CONFIG_ARM_THUMBEE. In this case, tasks are sent SIGILL if they try to access TEEHBR. Cc: stable@vger.kernel.org Reviewed-by: Will Deacon Signed-off-by: Jonathan Austin Signed-off-by: Russell King --- arch/arm/mm/proc-v7.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index f1c8486f7501..c2e2b66f72b5 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -254,6 +254,18 @@ __v7_setup: ldr r6, =NMRR @ NMRR mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR +#endif +#ifndef CONFIG_ARM_THUMBEE + mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE + and r0, r0, #(0xf << 12) @ ThumbEE enabled field + teq r0, #(1 << 12) @ check if ThumbEE is present + bne 1f + mov r5, #0 + mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0 + mrc p14, 6, r0, c0, c0, 0 @ load TEECR + orr r0, r0, #1 @ set the 1st bit in order to + mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access +1: #endif adr r5, v7_crval ldmia r5, {r5, r6} From 708e5978dfee0090a27c5531ce3b017dd6d190a2 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sat, 14 Apr 2012 21:51:32 +0100 Subject: [PATCH 262/438] ARM: 7386/1: jump_label: fixup for rename to static_key c5905afb0 ("static keys: Introduce 'struct static_key'...") renamed struct jump_label_key to struct static_key. Fixup ARM for this to eliminate these build warnings: include/linux/jump_label.h:113:2: warning: passing argument 1 of 'arch_static_branch' from incompatible pointer type include/asm/jump_label.h:17:82: note: expected 'struct jump_label_key *' but argument is of type 'struct static_key *' Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/include/asm/jump_label.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h index 5c5ca2ea62b0..bfc198c75913 100644 --- a/arch/arm/include/asm/jump_label.h +++ b/arch/arm/include/asm/jump_label.h @@ -14,7 +14,7 @@ #define JUMP_LABEL_NOP "nop" #endif -static __always_inline bool arch_static_branch(struct jump_label_key *key) +static __always_inline bool arch_static_branch(struct static_key *key) { asm goto("1:\n\t" JUMP_LABEL_NOP "\n\t" From 12e993b89464707398e4209bd99983e376454985 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 15 Apr 2012 17:23:00 -0700 Subject: [PATCH 263/438] x86-32: fix up strncpy_from_user() sign error The 'max' range needs to be unsigned, since the size of the user address space is bigger than 2GB. We know that 'count' is positive in 'long' (that is checked in the caller), so we will truncate 'max' down to something that fits in a signed long, but before we actually do that, that comparison needs to be done in unsigned. Bug introduced in commit 92ae03f2ef99 ("x86: merge 32/64-bit versions of 'strncpy_from_user()' and speed it up"). On x86-64 you can't trigger this, since the user address space is much smaller than 63 bits, and on x86-32 it works in practice, since you would seldom hit the strncpy limits anyway. I had actually tested the corner-cases, I had only tested them on x86-64. Besides, I had only worried about the case of a pointer *close* to the end of the address space, rather than really far away from it ;) This also changes the "we hit the user-specified maximum" to return 'res', for the trivial reason that gcc seems to generate better code that way. 'res' and 'count' are the same in that case, so it really doesn't matter which one we return. Signed-off-by: Linus Torvalds --- arch/x86/lib/usercopy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index 57252c928f56..d6ae30bbd7bb 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c @@ -57,7 +57,7 @@ static inline unsigned long count_bytes(unsigned long mask) * hit it), 'max' is the address space maximum (and we return * -EFAULT if we hit it). */ -static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, long max) +static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) { long res = 0; @@ -100,7 +100,7 @@ static inline long do_strncpy_from_user(char *dst, const char __user *src, long * too? If so, that's ok - we got as much as the user asked for. */ if (res >= count) - return count; + return res; /* * Nope: we hit the address space limit, and we still had more From e816b57a337ea3b755de72bec38c10c864f23015 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 15 Apr 2012 18:28:29 -0700 Subject: [PATCH 264/438] Linux 3.4-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0df3d003a079..f6578f47e21e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Saber-toothed Squirrel # *DOCUMENTATION* From acb0c7accde75f75afc70f662d045827d5126839 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 21 Mar 2012 14:17:43 +1000 Subject: [PATCH 265/438] m68knommu: remove the unused bootlogo.h processing for 68EZ328 and 68VZ328 The 68EZ328 and 68VZ328 platforms currently try to process their bootlogo.h to make it clean to include in asm files. This is no longer used, the bootlogo.h file is now included only in C code, so remove all the processing code in the 68EZ328 and 68VZ328 Makefiles. Signed-off-by: Greg Ungerer --- arch/m68k/platform/68EZ328/Makefile | 6 ------ arch/m68k/platform/68VZ328/Makefile | 9 ++------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/arch/m68k/platform/68EZ328/Makefile b/arch/m68k/platform/68EZ328/Makefile index ee97735a242c..b44d799b1115 100644 --- a/arch/m68k/platform/68EZ328/Makefile +++ b/arch/m68k/platform/68EZ328/Makefile @@ -3,9 +3,3 @@ # obj-y := config.o - -extra-y := bootlogo.rh - -$(obj)/bootlogo.rh: $(src)/bootlogo.h - perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \ - > $(obj)/bootlogo.rh diff --git a/arch/m68k/platform/68VZ328/Makefile b/arch/m68k/platform/68VZ328/Makefile index 447ffa0fd7c7..a49d75e65489 100644 --- a/arch/m68k/platform/68VZ328/Makefile +++ b/arch/m68k/platform/68VZ328/Makefile @@ -3,14 +3,9 @@ # obj-y := config.o -logo-$(UCDIMM) := bootlogo.rh -logo-$(DRAGEN2) := screen.h -extra-y := $(logo-y) - -$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h - perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh +extra-$(DRAGEN2):= screen.h $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h -clean-files := $(obj)/screen.h $(obj)/bootlogo.rh +clean-files := $(obj)/screen.h From 89d786011fcbc89eedca8b6bf9b7c11bbbde350a Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 21 Mar 2012 14:22:43 +1000 Subject: [PATCH 266/438] m68knommu: move and fix the 68VZ328 platform bootlogo.h The 68EZ328/bootlogo.h is not actually used in the 68EZ328 platform code at all. It is used by the 68VZ328 platform code though, so move it to be with the rest of the 68VZ328 platform code. Commit c0e0c89c089f4bd66dbbd1a44da90abe74fe3f02 ("fix broken boot logo inclusion") modified the bootlogo code to not be included in asm code. Modify 68VZ328/bootlogo.h so that the bootlogo bit map is named correctly for direct use in the C code. Signed-off-by: Greg Ungerer --- arch/m68k/platform/{68EZ328 => 68VZ328}/bootlogo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename arch/m68k/platform/{68EZ328 => 68VZ328}/bootlogo.h (99%) diff --git a/arch/m68k/platform/68EZ328/bootlogo.h b/arch/m68k/platform/68VZ328/bootlogo.h similarity index 99% rename from arch/m68k/platform/68EZ328/bootlogo.h rename to arch/m68k/platform/68VZ328/bootlogo.h index e842bdae5839..b38e2b255142 100644 --- a/arch/m68k/platform/68EZ328/bootlogo.h +++ b/arch/m68k/platform/68VZ328/bootlogo.h @@ -1,6 +1,6 @@ #define splash_width 640 #define splash_height 480 -static unsigned char splash_bits[] = { +unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, From 6c7b8e82aab75a25581c4d446fc87f96634e9ef9 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 13 Apr 2012 12:24:27 +0900 Subject: [PATCH 267/438] x86: Handle failures of parsing immediate operands in the instruction decoder This can happen if the instruction is much longer than the maximum length, or if insn->opnd_bytes is manually changed. This patch also fixes warnings from -Wswitch-default flag. Reported-by: Prashanth Nageshappa Signed-off-by: Masami Hiramatsu Cc: Linus Torvalds Cc: Ananth N Mavinakayanahalli Cc: Jim Keniston Cc: Linux-mm Cc: Oleg Nesterov Cc: Andi Kleen Cc: Christoph Hellwig Cc: Steven Rostedt Cc: Arnaldo Carvalho de Melo Cc: Anton Arapov Cc: Srikar Dronamraju Cc: yrl.pp-manager.tt@hitachi.com Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120413032427.32577.42602.stgit@localhost.localdomain Signed-off-by: Ingo Molnar --- arch/x86/lib/insn.c | 53 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index 25feb1ae71c5..b1e6c4b2e8eb 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c @@ -379,8 +379,8 @@ err_out: return; } -/* Decode moffset16/32/64 */ -static void __get_moffset(struct insn *insn) +/* Decode moffset16/32/64. Return 0 if failed */ +static int __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: @@ -397,15 +397,19 @@ static void __get_moffset(struct insn *insn) insn->moffset2.value = get_next(int, insn); insn->moffset2.nbytes = 4; break; + default: /* opnd_bytes must be modified manually */ + goto err_out; } insn->moffset1.got = insn->moffset2.got = 1; + return 1; + err_out: - return; + return 0; } -/* Decode imm v32(Iz) */ -static void __get_immv32(struct insn *insn) +/* Decode imm v32(Iz). Return 0 if failed */ +static int __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -417,14 +421,18 @@ static void __get_immv32(struct insn *insn) insn->immediate.value = get_next(int, insn); insn->immediate.nbytes = 4; break; + default: /* opnd_bytes must be modified manually */ + goto err_out; } + return 1; + err_out: - return; + return 0; } -/* Decode imm v64(Iv/Ov) */ -static void __get_immv(struct insn *insn) +/* Decode imm v64(Iv/Ov), Return 0 if failed */ +static int __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -441,15 +449,18 @@ static void __get_immv(struct insn *insn) insn->immediate2.value = get_next(int, insn); insn->immediate2.nbytes = 4; break; + default: /* opnd_bytes must be modified manually */ + goto err_out; } insn->immediate1.got = insn->immediate2.got = 1; + return 1; err_out: - return; + return 0; } /* Decode ptr16:16/32(Ap) */ -static void __get_immptr(struct insn *insn) +static int __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -462,14 +473,17 @@ static void __get_immptr(struct insn *insn) break; case 8: /* ptr16:64 is not exist (no segment) */ - return; + return 0; + default: /* opnd_bytes must be modified manually */ + goto err_out; } insn->immediate2.value = get_next(unsigned short, insn); insn->immediate2.nbytes = 2; insn->immediate1.got = insn->immediate2.got = 1; + return 1; err_out: - return; + return 0; } /** @@ -489,7 +503,8 @@ void insn_get_immediate(struct insn *insn) insn_get_displacement(insn); if (inat_has_moffset(insn->attr)) { - __get_moffset(insn); + if (!__get_moffset(insn)) + goto err_out; goto done; } @@ -517,16 +532,20 @@ void insn_get_immediate(struct insn *insn) insn->immediate2.nbytes = 4; break; case INAT_IMM_PTR: - __get_immptr(insn); + if (!__get_immptr(insn)) + goto err_out; break; case INAT_IMM_VWORD32: - __get_immv32(insn); + if (!__get_immv32(insn)) + goto err_out; break; case INAT_IMM_VWORD: - __get_immv(insn); + if (!__get_immv(insn)) + goto err_out; break; default: - break; + /* Here, insn must have an immediate, but failed */ + goto err_out; } if (inat_has_second_immediate(insn->attr)) { insn->immediate2.value = get_next(char, insn); From 97b3b7a0d0703df04e8c6d05c9b6c2fa8868db10 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 13 Apr 2012 15:08:01 +0200 Subject: [PATCH 268/438] ARM: ux500: Fix unmet direct dependency A recent change to a Kconfig configuration saw MACH_U8500 remove TPS6105X selection. In doing so Kconfig stopped selecting REGULATORS, which is still required. This patch sees UX500_SOC_DB8500 explicitly select it instead. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 880d02ec89d4..ef7099eea0f2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -17,6 +17,7 @@ config UX500_SOC_DB5500 config UX500_SOC_DB8500 bool select MFD_DB8500_PRCMU + select REGULATOR select REGULATOR_DB8500_PRCMU select CPU_FREQ_TABLE if CPU_FREQ From f27962ac68a9b4cf17958522ecd7c10ce2375ee1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 13 Apr 2012 10:18:36 +0200 Subject: [PATCH 269/438] ARM: ux500: update defconfig Some new drivers and changed Kconfig dependencies for the v3.4 kernel affecting the U8500 defconfig: - The SOC config options are now brought in by default - No need to explicitly select misc devices anymore - I2C is selected by default - We now have support for charging from the AB8500 so compile in this - The regulator framework needs to be explictly selected Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 889d73ac1ae1..7e84f453e8a6 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -8,8 +8,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_U8500=y -CONFIG_UX500_SOC_DB5500=y -CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y @@ -39,7 +37,6 @@ CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_MISC_DEVICES=y CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y @@ -65,16 +62,18 @@ CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y -CONFIG_I2C=y -CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_GPIO_STMPE=y CONFIG_GPIO_TC3589X=y +CONFIG_POWER_SUPPLY=y +CONFIG_AB8500_BM=y +CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y +CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y From f9bef081c3c3f77bec54454872e98d3ec635756f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 15 Apr 2012 19:53:19 +0200 Subject: [PATCH 270/438] drm/i915: don't clobber the special upscaling lvds timings This regression has been introduced in commit ca9bfa7eed20ea34e862804e62aae10eb159edbb Author: Daniel Vetter Date: Sat Jan 28 14:49:20 2012 +0100 drm/i915: fixup interlaced vertical timings confusion, part 1 Unfortunately that commit failed to take into account that the lvds code does some special adjustements to the crtc timings for upscaling an centering. Fix this by explicitly computing crtc timings in the lvds mode fixup function and setting a special flag in mode->private_flags if the crtc timings have been adjusted. v2: Add a comment to explain the new mode driver private flag, suggested by Eugeni Dodonov. v3: Kill the confusing and now redundant set_crtcinfo call in intel_fixed_panel_mode, noticed by Chris Wilson. Reported-and-Tested-by: Hans de Bruin Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43071 Reviewed-by: Eugeni Dodonov Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 +++++-- drivers/gpu/drm/i915/intel_drv.h | 4 ++++ drivers/gpu/drm/i915/intel_lvds.c | 6 ++++++ drivers/gpu/drm/i915/intel_panel.c | 2 -- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bae38acf44dc..8be30917bce3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3478,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, return false; } - /* All interlaced capable intel hw wants timings in frames. */ - drm_mode_set_crtcinfo(adjusted_mode, 0); + /* All interlaced capable intel hw wants timings in frames. Note though + * that intel_lvds_mode_fixup does some funny tricks with the crtc + * timings, so we need to be careful not to clobber these.*/ + if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5a14149b3794..715afa153025 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -105,6 +105,10 @@ #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_DP_FORCE_6BPC (0x10) +/* This flag must be set by the encoder's mode_fixup if it changes the crtc + * timings in the mode to prevent the crtc fixup from overwriting them. + * Currently only lvds needs that. */ +#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) static inline void intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 95db2e988227..30e2c82101de 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode, mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; + + mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static void @@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode, mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; + + mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static inline u32 panel_fitter_scaling(u32 source, u32 target) @@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, for_each_pipe(pipe) I915_WRITE(BCLRPAT(pipe), 0); + drm_mode_set_crtcinfo(adjusted_mode, 0); + switch (intel_lvds->fitting_mode) { case DRM_MODE_SCALE_CENTER: /* diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 230a141dbea3..48177ec4720e 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->clock = fixed_mode->clock; - - drm_mode_set_crtcinfo(adjusted_mode, 0); } /* adjusted_mode has been preset to be the panel's fixed mode */ From 9fce85c7e4357a93457c8fd2534a1cc1c3055bf5 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Wed, 4 Apr 2012 19:15:15 +0200 Subject: [PATCH 271/438] ARM: at91: Export at91_st_base After commit 5e9cf5e (ARM: at91: make ST (System Timer) soc independent) building at91rm9200_wdt as a module fails with following message ERROR: "at91_st_base" [drivers/watchdog/at91rm9200_wdt.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Export symbol to allow wdt driver to be built as a module again. Signed-off-by: Joachim Eastwood [nicolas.ferre@atmel.com: use EXPORT_SYMBOL_GPL()] Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_time.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index dd7f782b0b91..104ca40d8d18 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -176,6 +177,7 @@ static struct clock_event_device clkevt = { }; void __iomem *at91_st_base; +EXPORT_SYMBOL_GPL(at91_st_base); void __init at91rm9200_ioremap_st(u32 addr) { From 9268c6c6fab0b27a01afec8268f7c863783541bf Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Fri, 30 Mar 2012 23:03:50 +0200 Subject: [PATCH 272/438] ARM: at91: Export at91_ramc_base After commit f363c40 (ARM: at91: make sdram/ddr register base soc independent) building at91_cf as a module fails with: ERROR: "at91_ramc_base" [drivers/pcmcia/at91_cf.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Export at91_ramc_base symbol to allow drivers using at91_ramc_* functions to be built as modules again. Signed-off-by: Joachim Eastwood [nicolas.ferre@atmel.com: modify slightly commit message] Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 97cc04dc8073..06078479beba 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -54,6 +54,7 @@ void __init at91_init_interrupts(unsigned int *priority) } void __iomem *at91_ramc_base[2]; +EXPORT_SYMBOL_GPL(at91_ramc_base); void __init at91_ioremap_ramc(int id, u32 addr, u32 size) { From f19b797c08017c9b03d81986b2efc4c5cf4bc453 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sat, 7 Apr 2012 19:30:22 +0200 Subject: [PATCH 273/438] ARM: at91: Export at91_pmc_base After commit b55149529d26 (ARM: at91/PMC: make register base soc independent) building atmel_usba_udc as a module fails with following message ERROR: "at91_pmc_base" [drivers/usb/gadget/atmel_usba_udc.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Export symbol to allow driver to be built as a module again. Signed-off-by: Joachim Eastwood Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/clock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index a0f4d7424cdc..6b692824c988 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -35,6 +35,7 @@ #include "generic.h" void __iomem *at91_pmc_base; +EXPORT_SYMBOL_GPL(at91_pmc_base); /* * There's a lot more which can be done with clocks, including cpufreq From ac8c411c8360c281d1fb5e03a975e9088d069ded Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sat, 7 Apr 2012 19:30:23 +0200 Subject: [PATCH 274/438] ARM: at91: Export at91_matrix_base at91_matrix_* macro's are used by at91_udc usb gadget driver, which can be built as module, therefore we need to export the variable containing matrix base address. Signed-off-by: Joachim Eastwood Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 06078479beba..f44a2e7272e3 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -293,6 +293,7 @@ void __init at91_ioremap_rstc(u32 base_addr) } void __iomem *at91_matrix_base; +EXPORT_SYMBOL_GPL(at91_matrix_base); void __init at91_ioremap_matrix(u32 base_addr) { From 67f3af402aebb0098998d3bbebda2fb44aa3a081 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 10 Apr 2012 14:30:24 +0200 Subject: [PATCH 275/438] ARM: at91: fix typo in at91_pmc_base assembly declaration Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/include/mach/at91_pmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 36604782a78f..ea2c57a86ca6 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base; #define at91_pmc_write(field, value) \ __raw_writel(value, at91_pmc_base + field) #else -.extern at91_aic_base +.extern at91_pmc_base #endif #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ From 926de6d8b90feee26717c01543243b8e07681303 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Fri, 6 Apr 2012 14:36:19 +0200 Subject: [PATCH 276/438] ARM: at91: remove empty at91_init_serial function The real function is long gone and the empty one will generate warnings when configured without Atmel serial: arch/arm/mach-at91/at91rm9200_devices.c:1176: warning: 'struct at91_uart_config' declared inside parameter list arch/arm/mach-at91/at91rm9200_devices.c:1176: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Joachim Eastwood Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_devices.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 99ce5c955e39..05774e5b1cba 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -1173,7 +1173,6 @@ void __init at91_add_device_serial(void) printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else -void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} From bf66b0d1dad30cc1241dc4e3ac193251a4694f5c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 10 Apr 2012 16:02:31 +0200 Subject: [PATCH 277/438] ARM: at91: fix rm9200ek flash size The flash size is 8MiB. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/board-rm9200ek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 11cbaa8946fe..b2e4fe21f346 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { }; #define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE SZ_2M +#define EK_FLASH_SIZE SZ_8M static struct physmap_flash_data ek_flash_data = { .width = 2, From ee9dd7631af6fb5c02964ed5b496217cd4ced059 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 10 Apr 2012 17:32:44 +0200 Subject: [PATCH 278/438] ARM: at91: fix at91sam9261ek Ethernet dm9000 irq You need to setup the dm9000 irq via gpio_to_irq() since d0fbda9add (ARM: at91/gpio: drop PIN_BASE). Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Cc: stable [3.2+] --- arch/arm/mach-at91/board-sam9261ek.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index c3f994462864..065fed342424 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -85,8 +85,6 @@ static struct resource dm9000_resource[] = { .flags = IORESOURCE_MEM }, [2] = { - .start = AT91_PIN_PC11, - .end = AT91_PIN_PC11, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, } @@ -130,6 +128,8 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { + struct resource *r = &dm9000_resource[2]; + /* Configure chip-select 2 (DM9000) */ sam9_smc_configure(0, 2, &dm9000_smc_config); @@ -139,6 +139,7 @@ static void __init ek_add_device_dm9000(void) /* Configure Interrupt pin as input, no pull-up */ at91_set_gpio_input(AT91_PIN_PC11, 0); + r->start = r->end = gpio_to_irq(AT91_PIN_PC11); platform_device_register(&dm9000_device); } #else From 16a5e32b83fd946312b9b13590c75d20c95c5202 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 13 Apr 2012 11:14:50 +0100 Subject: [PATCH 279/438] drm/radeon: disable MSI on RV515 My rv515 card is very flaky with msi enabled. Every so often it loses a rearm and never comes back, manually banging the rearm brings it back. Reviewed-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 66d5fe1c8174..65060b77c805 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x01fd)) return true; + /* RV515 seems to have MSI issues where it loses + * MSI rearms occasionally. This leads to lockups and freezes. + * disable it by default. + */ + if (rdev->family == CHIP_RV515) + return false; if (rdev->flags & RADEON_IS_IGP) { /* APUs work fine with MSIs */ if (rdev->family >= CHIP_PALM) From 5273db706f8b673902638fee7f907909ed6ae3f9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 13 Apr 2012 10:26:36 -0400 Subject: [PATCH 280/438] drm/radeon/si: add missing radeon_bo_unreserve in si_rlc_init() v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forget to unreserve after pinning. This can lead to problems in soft reset and resume. v2: rework patch as per Michel's suggestion. Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/si.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ac7a199ffece..27bda986fc2b 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_gpu_addr); + radeon_bo_unreserve(rdev->rlc.save_restore_obj); if (r) { - radeon_bo_unreserve(rdev->rlc.save_restore_obj); dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); si_rlc_fini(rdev); return r; @@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_gpu_addr); + radeon_bo_unreserve(rdev->rlc.clear_state_obj); if (r) { - - radeon_bo_unreserve(rdev->rlc.clear_state_obj); dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); si_rlc_fini(rdev); return r; From 4accdff7a3e397b43e50f605ee561ba7994745c7 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 2 Apr 2012 17:55:48 +0200 Subject: [PATCH 281/438] mfd : Fix dbx500 compilation error The ux500 default config enables the db5500 and the db8500. The incoming cpuidle driver uses the 'prcmu_enable_wakeups' and the 'prcmu_set_power_state' functions but these ones are defined but not implemented for the db5500, leading to an unresolved symbol error at link time. In order to compile, we have to disable the db5500 support which is not acceptable for the default config. I noticed there are also some other functions which are defined but not implemented. This patch fix this by removing the functions definitions and move out of the config section the empty functions which are normally used when the DB550 config is disabled. Only the functions which are not implemented are concerned by this modification. Signed-off-by: Daniel Lezcano Acked-by: Linus Walleij Signed-off-by: Samuel Ortiz --- include/linux/mfd/db5500-prcmu.h | 120 ++++++++++++++----------------- 1 file changed, 53 insertions(+), 67 deletions(-) diff --git a/include/linux/mfd/db5500-prcmu.h b/include/linux/mfd/db5500-prcmu.h index 9890687f582d..5a049dfaf153 100644 --- a/include/linux/mfd/db5500-prcmu.h +++ b/include/linux/mfd/db5500-prcmu.h @@ -8,70 +8,6 @@ #ifndef __MFD_DB5500_PRCMU_H #define __MFD_DB5500_PRCMU_H -#ifdef CONFIG_MFD_DB5500_PRCMU - -void db5500_prcmu_early_init(void); -int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); -int db5500_prcmu_set_display_clocks(void); -int db5500_prcmu_disable_dsipll(void); -int db5500_prcmu_enable_dsipll(void); -int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); -void db5500_prcmu_enable_wakeups(u32 wakeups); -int db5500_prcmu_request_clock(u8 clock, bool enable); -void db5500_prcmu_config_abb_event_readout(u32 abb_events); -void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); -int prcmu_resetout(u8 resoutn, u8 state); -int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, - bool keep_ap_pll); -int db5500_prcmu_config_esram0_deep_sleep(u8 state); -void db5500_prcmu_system_reset(u16 reset_code); -u16 db5500_prcmu_get_reset_code(void); -bool db5500_prcmu_is_ac_wake_requested(void); -int db5500_prcmu_set_arm_opp(u8 opp); -int db5500_prcmu_get_arm_opp(void); - -#else /* !CONFIG_UX500_SOC_DB5500 */ - -static inline void db5500_prcmu_early_init(void) {} - -static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) -{ - return -ENOSYS; -} - -static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) -{ - return -ENOSYS; -} - -static inline int db5500_prcmu_request_clock(u8 clock, bool enable) -{ - return 0; -} - -static inline int db5500_prcmu_set_display_clocks(void) -{ - return 0; -} - -static inline int db5500_prcmu_disable_dsipll(void) -{ - return 0; -} - -static inline int db5500_prcmu_enable_dsipll(void) -{ - return 0; -} - -static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) -{ - return 0; -} - -static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} - static inline int prcmu_resetout(u8 resoutn, u8 state) { return 0; @@ -82,8 +18,10 @@ static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) return 0; } -static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} -static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} +static inline int db5500_prcmu_request_clock(u8 clock, bool enable) +{ + return 0; +} static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) @@ -91,7 +29,10 @@ static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, return 0; } -static inline void db5500_prcmu_system_reset(u16 reset_code) {} +static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) +{ + return 0; +} static inline u16 db5500_prcmu_get_reset_code(void) { @@ -113,6 +54,51 @@ static inline int db5500_prcmu_get_arm_opp(void) return 0; } +static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} + +static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} + +static inline void db5500_prcmu_system_reset(u16 reset_code) {} + +static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} + +#ifdef CONFIG_MFD_DB5500_PRCMU + +void db5500_prcmu_early_init(void); +int db5500_prcmu_set_display_clocks(void); +int db5500_prcmu_disable_dsipll(void); +int db5500_prcmu_enable_dsipll(void); +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) {} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int db5500_prcmu_set_display_clocks(void) +{ + return 0; +} + +static inline int db5500_prcmu_disable_dsipll(void) +{ + return 0; +} + +static inline int db5500_prcmu_enable_dsipll(void) +{ + return 0; +} #endif /* CONFIG_MFD_DB5500_PRCMU */ From 8eaeb9393397be8eb700ab38a69c450975463b77 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Apr 2012 11:56:51 +0300 Subject: [PATCH 282/438] mfd: Convert twl6040 to i2c driver, and separate it from twl core Complete the separation of the twl6040 from the twl core since it is a separate chip, not part of the twl6030 PMIC. Make the needed Kconfig changes for the depending drivers at the same time to avoid breaking the kernel build (vibra, ASoC components). Signed-off-by: Peter Ujfalusi Reviewed-by: Mark Brown Acked-by: Tony Lindgren Acked-by: Dmitry Torokhov Signed-off-by: Samuel Ortiz --- arch/arm/mach-omap2/board-4430sdp.c | 12 +-- arch/arm/mach-omap2/board-generic.c | 2 +- arch/arm/mach-omap2/board-omap4panda.c | 13 ++- arch/arm/mach-omap2/twl-common.c | 37 ++++++-- arch/arm/mach-omap2/twl-common.h | 10 +-- drivers/input/misc/Kconfig | 3 +- drivers/input/misc/twl6040-vibra.c | 4 +- drivers/mfd/Kconfig | 11 ++- drivers/mfd/twl6040-core.c | 114 +++++++++++++++---------- include/linux/i2c/twl.h | 12 --- include/linux/mfd/twl6040.h | 27 ++++++ sound/soc/codecs/Kconfig | 3 +- sound/soc/codecs/twl6040.c | 3 +- sound/soc/omap/Kconfig | 2 +- 14 files changed, 159 insertions(+), 94 deletions(-) diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index a39fc4bbd2b8..130ab00c09a2 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -560,7 +561,7 @@ static struct regulator_init_data sdp4430_vusim = { }, }; -static struct twl4030_codec_data twl6040_codec = { +static struct twl6040_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -568,7 +569,7 @@ static struct twl4030_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl4030_vibra_data twl6040_vibra = { +static struct twl6040_vibra_data twl6040_vibra = { .vibldrv_res = 8, .vibrdrv_res = 3, .viblmotor_res = 10, @@ -577,16 +578,14 @@ static struct twl4030_vibra_data twl6040_vibra = { .vddvibr_uV = 0, /* fixed volt supply - VBAT */ }; -static struct twl4030_audio_data twl6040_audio = { +static struct twl6040_platform_data twl6040_data = { .codec = &twl6040_codec, .vibra = &twl6040_vibra, .audpwron_gpio = 127, - .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; static struct twl4030_platform_data sdp4430_twldata = { - .audio = &twl6040_audio, /* Regulators */ .vusim = &sdp4430_vusim, .vaux1 = &sdp4430_vaux1, @@ -617,7 +616,8 @@ static int __init omap4_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &sdp4430_twldata); + omap4_pmic_init("twl6030", &sdp4430_twldata, + &twl6040_data, OMAP44XX_IRQ_SYS_2N); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 74e1687b5170..098d183a0086 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = { static void __init omap4_i2c_init(void) { - omap4_pmic_init("twl6030", &sdp4430_twldata); + omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0); } static void __init omap4_init(void) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index d8c0e89f0126..1b782ba53433 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -284,7 +285,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } -static struct twl4030_codec_data twl6040_codec = { +static struct twl6040_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -292,17 +293,14 @@ static struct twl4030_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl4030_audio_data twl6040_audio = { +static struct twl6040_platform_data twl6040_data = { .codec = &twl6040_codec, .audpwron_gpio = 127, - .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; /* Panda board uses the common PMIC configuration */ -static struct twl4030_platform_data omap4_panda_twldata = { - .audio = &twl6040_audio, -}; +static struct twl4030_platform_data omap4_panda_twldata; /* * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM @@ -326,7 +324,8 @@ static int __init omap4_panda_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &omap4_panda_twldata); + omap4_pmic_init("twl6030", &omap4_panda_twldata, + &twl6040_data, OMAP44XX_IRQ_SYS_2N); omap_register_i2c_bus(2, 400, NULL, 0); /* * Bus 3 is attached to the DVI port where devices like the pico DLP diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 4b57757bf9d1..7a7b89304c48 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = { .flags = I2C_CLIENT_WAKE, }; +static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { + { + .addr = 0x48, + .flags = I2C_CLIENT_WAKE, + }, + { + I2C_BOARD_INFO("twl6040", 0x4b), + }, +}; + void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data) @@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } +void __init omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data, + struct twl6040_platform_data *twl6040_data, int twl6040_irq) +{ + /* PMIC part*/ + strncpy(omap4_i2c1_board_info[0].type, pmic_type, + sizeof(omap4_i2c1_board_info[0].type)); + omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; + omap4_i2c1_board_info[0].platform_data = pmic_data; + + /* TWL6040 audio IC part */ + omap4_i2c1_board_info[1].irq = twl6040_irq; + omap4_i2c1_board_info[1].platform_data = twl6040_data; + + omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2); + +} + void __init omap_pmic_late_init(void) { /* Init the OMAP TWL parameters (if PMIC has been registerd) */ - if (!pmic_i2c_board_info.irq) - return; - - omap3_twl_init(); - omap4_twl_init(); + if (pmic_i2c_board_info.irq) + omap3_twl_init(); + if (omap4_i2c1_board_info[0].irq) + omap4_twl_init(); } #if defined(CONFIG_ARCH_OMAP3) diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h index 275dde8cb27a..09627483a57f 100644 --- a/arch/arm/mach-omap2/twl-common.h +++ b/arch/arm/mach-omap2/twl-common.h @@ -29,6 +29,7 @@ struct twl4030_platform_data; +struct twl6040_platform_data; void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data); @@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type, omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data); } -static inline void omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data) -{ - /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ - omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); -} +void omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data, + struct twl6040_platform_data *audio_data, int twl6040_irq); void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 2d787796bf50..7faf4a7fcaa9 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA config INPUT_TWL6040_VIBRA tristate "Support for TWL6040 Vibrator" - depends on TWL4030_CORE - select TWL6040_CORE + depends on TWL6040_CORE select INPUT_FF_MEMLESS help This option enables support for TWL6040 Vibrator Driver. diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 45874fed523a..14e94f56cb7d 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { - struct twl4030_vibra_data *pdata = pdev->dev.platform_data; + struct twl6040_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 29f463cc09cb..11e44386fa9b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -268,10 +268,17 @@ config TWL6030_PWM This is used to control charging LED brightness. config TWL6040_CORE - bool - depends on TWL4030_CORE && GENERIC_HARDIRQS + bool "Support for TWL6040 audio codec" + depends on I2C=y && GENERIC_HARDIRQS select MFD_CORE + select REGMAP_I2C default n + help + Say yes here if you want support for Texas Instruments TWL6040 audio + codec. + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the + functionality of the device (audio, vibra). config MFD_STMPE bool "Support STMicroelectronics STMPE" diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b2d8e512d3cb..2d6bedadca09 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -30,7 +30,9 @@ #include #include #include -#include +#include +#include +#include #include #include @@ -39,7 +41,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) { int ret; - u8 val = 0; + unsigned int val; mutex_lock(&twl6040->io_mutex); /* Vibra control registers from cache */ @@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) reg == TWL6040_REG_VIBCTLR)) { val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; } else { - ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + ret = regmap_read(twl6040->regmap, reg, &val); if (ret < 0) { mutex_unlock(&twl6040->io_mutex); return ret; @@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) int ret; mutex_lock(&twl6040->io_mutex); - ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); + ret = regmap_write(twl6040->regmap, reg, val); /* Cache the vibra control registers */ if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write); int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; - u8 val; mutex_lock(&twl6040->io_mutex); - ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); - if (ret) - goto out; - - val |= mask; - ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: + ret = regmap_update_bits(twl6040->regmap, reg, mask, mask); mutex_unlock(&twl6040->io_mutex); return ret; } @@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits); int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; - u8 val; mutex_lock(&twl6040->io_mutex); - ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); - if (ret) - goto out; - - val &= ~mask; - ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: + ret = regmap_update_bits(twl6040->regmap, reg, mask, 0); mutex_unlock(&twl6040->io_mutex); return ret; } @@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = { }, }; -static int __devinit twl6040_probe(struct platform_device *pdev) +static bool twl6040_readable_reg(struct device *dev, unsigned int reg) { - struct twl4030_audio_data *pdata = pdev->dev.platform_data; + /* Register 0 is not readable */ + if (!reg) + return false; + return true; +} + +static struct regmap_config twl6040_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = TWL6040_REG_STATUS, /* 0x2e */ + + .readable_reg = twl6040_readable_reg, +}; + +static int __devinit twl6040_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct twl6040_platform_data *pdata = client->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int ret, children = 0; if (!pdata) { - dev_err(&pdev->dev, "Platform data is missing\n"); + dev_err(&client->dev, "Platform data is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ - if (!pdata->naudint_irq || !pdata->irq_base) { - dev_err(&pdev->dev, "Invalid IRQ configuration\n"); + if (!client->irq || !pdata->irq_base) { + dev_err(&client->dev, "Invalid IRQ configuration\n"); return -EINVAL; } - twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); - if (!twl6040) - return -ENOMEM; + twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), + GFP_KERNEL); + if (!twl6040) { + ret = -ENOMEM; + goto err; + } - platform_set_drvdata(pdev, twl6040); + twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); + if (IS_ERR(twl6040->regmap)) { + ret = PTR_ERR(twl6040->regmap); + goto err; + } - twl6040->dev = &pdev->dev; - twl6040->irq = pdata->naudint_irq; + i2c_set_clientdata(client, twl6040); + + twl6040->dev = &client->dev; + twl6040->irq = client->irq; twl6040->irq_base = pdata->irq_base; mutex_init(&twl6040->mutex); @@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev) } if (children) { - ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, + ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { - dev_err(&pdev->dev, "No platform data found for children\n"); + dev_err(&client->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } @@ -608,14 +622,15 @@ gpio2_err: if (gpio_is_valid(twl6040->audpwron)) gpio_free(twl6040->audpwron); gpio1_err: - platform_set_drvdata(pdev, NULL); - kfree(twl6040); + i2c_set_clientdata(client, NULL); + regmap_exit(twl6040->regmap); +err: return ret; } -static int __devexit twl6040_remove(struct platform_device *pdev) +static int __devexit twl6040_remove(struct i2c_client *client) { - struct twl6040 *twl6040 = platform_get_drvdata(pdev); + struct twl6040 *twl6040 = i2c_get_clientdata(client); if (twl6040->power_count) twl6040_power(twl6040, 0); @@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev) free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); twl6040_irq_exit(twl6040); - mfd_remove_devices(&pdev->dev); - platform_set_drvdata(pdev, NULL); - kfree(twl6040); + mfd_remove_devices(&client->dev); + i2c_set_clientdata(client, NULL); + regmap_exit(twl6040->regmap); return 0; } -static struct platform_driver twl6040_driver = { +static const struct i2c_device_id twl6040_i2c_id[] = { + { "twl6040", 0, }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); + +static struct i2c_driver twl6040_driver = { + .driver = { + .name = "twl6040", + .owner = THIS_MODULE, + }, .probe = twl6040_probe, .remove = __devexit_p(twl6040_remove), - .driver = { - .owner = THIS_MODULE, - .name = "twl6040", - }, + .id_table = twl6040_i2c_id, }; -module_platform_driver(twl6040_driver); +module_i2c_driver(twl6040_driver); MODULE_DESCRIPTION("TWL6040 MFD"); MODULE_AUTHOR("Misael Lopez Cruz "); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 2463b6100333..1f90de0cfdbe 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -666,23 +666,11 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; - u16 hs_left_step; - u16 hs_right_step; - u16 hf_left_step; - u16 hf_right_step; void (*set_hs_extmute)(int mute); }; struct twl4030_vibra_data { unsigned int coexist; - - /* twl6040 */ - unsigned int vibldrv_res; /* left driver resistance */ - unsigned int vibrdrv_res; /* right driver resistance */ - unsigned int viblmotor_res; /* left motor resistance */ - unsigned int vibrmotor_res; /* right motor resistance */ - int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ - int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ }; struct twl4030_audio_data { diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 9bc9ac651dad..b15b5f03f5c4 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -174,8 +174,35 @@ #define TWL6040_SYSCLK_SEL_LPPLL 0 #define TWL6040_SYSCLK_SEL_HPPLL 1 +struct twl6040_codec_data { + u16 hs_left_step; + u16 hs_right_step; + u16 hf_left_step; + u16 hf_right_step; +}; + +struct twl6040_vibra_data { + unsigned int vibldrv_res; /* left driver resistance */ + unsigned int vibrdrv_res; /* right driver resistance */ + unsigned int viblmotor_res; /* left motor resistance */ + unsigned int vibrmotor_res; /* right motor resistance */ + int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ + int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ +}; + +struct twl6040_platform_data { + int audpwron_gpio; /* audio power-on gpio */ + unsigned int irq_base; + + struct twl6040_codec_data *codec; + struct twl6040_vibra_data *vibra; +}; + +struct regmap; + struct twl6040 { struct device *dev; + struct regmap *regmap; struct mutex mutex; struct mutex io_mutex; struct mutex irq_mutex; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6508e8b790bb..59d8efaa17e9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C select SND_SOC_TWL4030 if TWL4030_CORE - select SND_SOC_TWL6040 if TWL4030_CORE + select SND_SOC_TWL6040 if TWL6040_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WL1273 if MFD_WL1273_CORE @@ -276,7 +276,6 @@ config SND_SOC_TWL4030 tristate config SND_SOC_TWL6040 - select TWL6040_CORE tristate config SND_SOC_UDA134X diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2d8c6b825e57..dc7509b9d53a 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -1528,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec) static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; - struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); + struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev); struct platform_device *pdev = container_of(codec->dev, struct platform_device, dev); int ret = 0; diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index e00dd0b1139c..deafbfaacdbf 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 + depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 From 9cd70b347e9761ea2d2ac3d758c529a48a8193e6 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 16 Apr 2012 12:16:20 -0400 Subject: [PATCH 283/438] ext4: address scalability issue by removing extent cache statistics Andi Kleen and Tim Chen have reported that under certain circumstances the extent cache statistics are causing scalability problems due to cache line bounces. Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/ext4.h | 3 --- fs/ext4/extents.c | 4 ---- fs/ext4/super.c | 16 ---------------- 3 files changed, 23 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ab2594a30f86..0e01e90add8b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1203,9 +1203,6 @@ struct ext4_sb_info { unsigned long s_ext_blocks; unsigned long s_ext_extents; #endif - /* ext4 extent cache stats */ - unsigned long extent_cache_hits; - unsigned long extent_cache_misses; /* for buddy allocator */ struct ext4_group_info ***s_group_info; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1421938e6792..8a12cd207679 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2066,10 +2066,6 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block, ret = 1; } errout: - if (!ret) - sbi->extent_cache_misses++; - else - sbi->extent_cache_hits++; trace_ext4_ext_in_cache(inode, block, ret); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); return ret; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ceebaf853beb..ef7db5044262 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2366,18 +2366,6 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, EXT4_SB(sb)->s_sectors_written_start) >> 1))); } -static ssize_t extent_cache_hits_show(struct ext4_attr *a, - struct ext4_sb_info *sbi, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits); -} - -static ssize_t extent_cache_misses_show(struct ext4_attr *a, - struct ext4_sb_info *sbi, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses); -} - static ssize_t inode_readahead_blks_store(struct ext4_attr *a, struct ext4_sb_info *sbi, const char *buf, size_t count) @@ -2435,8 +2423,6 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) EXT4_RO_ATTR(delayed_allocation_blocks); EXT4_RO_ATTR(session_write_kbytes); EXT4_RO_ATTR(lifetime_write_kbytes); -EXT4_RO_ATTR(extent_cache_hits); -EXT4_RO_ATTR(extent_cache_misses); EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show, inode_readahead_blks_store, s_inode_readahead_blks); EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); @@ -2452,8 +2438,6 @@ static struct attribute *ext4_attrs[] = { ATTR_LIST(delayed_allocation_blocks), ATTR_LIST(session_write_kbytes), ATTR_LIST(lifetime_write_kbytes), - ATTR_LIST(extent_cache_hits), - ATTR_LIST(extent_cache_misses), ATTR_LIST(inode_readahead_blks), ATTR_LIST(inode_goal), ATTR_LIST(mb_stats), From 1fcb57d0f6e1150003d222051aaaf4bc4a9ccc94 Mon Sep 17 00:00:00 2001 From: Keshava Munegowda Date: Mon, 19 Mar 2012 12:12:47 +0530 Subject: [PATCH 284/438] ARM: OMAP3: USB: Fix the EHCI ULPI PHY reset issue It is observed that the echi ports of 3430 sdp board are not working due to the random timing of programming the associated GPIOs of the ULPI PHYs of the EHCI for reset. If the PHYs are reset at during usbhs core driver, host ports will not work because EHCI driver is loaded after the resetting PHYs. The PHYs should be in reset state while initializing the EHCI controller. The code which does the GPIO pins associated with the PHYs are programmed to reset is moved from the USB host core driver to EHCI driver. Signed-off-by: Keshava Munegowda Reviewed-by: Partha Basak Acked-by: Felipe Balbi Tested-by: Igor Grinberg Signed-off-by: Samuel Ortiz --- drivers/mfd/omap-usb-host.c | 44 ------------------------------------ drivers/usb/host/ehci-omap.c | 39 ++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 95a2e546a489..c8aae6640e64 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev) pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_request_one(pdata->ehci_data->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_request_one(pdata->ehci_data->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev) usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } - if (pdata->ehci_data->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_set_value - (pdata->ehci_data->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_set_value - (pdata->ehci_data->reset_gpio_port[1], 1); - } - spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); } -static void omap_usbhs_deinit(struct device *dev) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = &omap->platdata; - - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_free(pdata->ehci_data->reset_gpio_port[0]); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_free(pdata->ehci_data->reset_gpio_port[1]); - } -} - /** * usbhs_omap_probe - initialize TI-based HCDs @@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); - omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bba9850f32f0..5c78f9e71466 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -42,6 +42,7 @@ #include #include #include +#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } + if (pdata->phy_reset) { + if (gpio_is_valid(pdata->reset_gpio_port[0])) + gpio_request_one(pdata->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + + if (gpio_is_valid(pdata->reset_gpio_port[1])) + gpio_request_one(pdata->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); + if (pdata->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->reset_gpio_port[0])) + gpio_set_value(pdata->reset_gpio_port[0], 1); + + if (gpio_is_valid(pdata->reset_gpio_port[1])) + gpio_set_value(pdata->reset_gpio_port[1], 1); + } + return 0; err_add_hcd: @@ -259,8 +286,9 @@ err_io: */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usb_hcd *hcd = dev_get_drvdata(dev); + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); @@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) pm_runtime_put_sync(dev); pm_runtime_disable(dev); + if (pdata->phy_reset) { + if (gpio_is_valid(pdata->reset_gpio_port[0])) + gpio_free(pdata->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->reset_gpio_port[1])) + gpio_free(pdata->reset_gpio_port[1]); + } return 0; } From 02269ab10f1130d35dc35db72ab026d16ba31abf Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Thu, 12 Apr 2012 15:33:34 +0400 Subject: [PATCH 285/438] mfd: Fix asic3_gpio_to_irq Assumption that irq numbers of asic3 gpios start at IRQ_BOARD_START is certainly wrong - driver may as well use any other base for its irqs (consider for example the imaginary case of two ASIC3 chips onboard) Furthermore, some platforms even don't have IRQ_BOARD_START defined, so driver will fail to build on them: ------------------------------------------------------- drivers/mfd/asic3.c: In function 'asic3_gpio_to_irq': drivers/mfd/asic3.c:530: error: 'IRQ_BOARD_START' undeclared (first use in this function) drivers/mfd/asic3.c:530: error: (Each undeclared identifier is reported only once drivers/mfd/asic3.c:530: error: for each function it appears in.) ------------------------------------------------------- Fix it by using irq_base from driver data. Signed-off-by: Dmitry Artamonow Signed-off-by: Samuel Ortiz --- drivers/mfd/asic3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 1895cf9fab8c..1582c3d95257 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip, static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; + struct asic3 *asic = container_of(chip, struct asic3, gpio); + + return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; } static __init int asic3_gpio_probe(struct platform_device *pdev, From 32998cc96a76cc3f42f66b55fec301377e439c66 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 14 Apr 2012 14:38:54 +0200 Subject: [PATCH 286/438] bcma: use fallback sprom if no on chip sprom is available bcma should check for a fallback sprom every time it can not find a sprom on the card itself or a normal external sprom mapped into the memory of the chip. When otp sprom support was introduced it tried to read out the sprom from the wireless chip also if no otp sprom was available. This caused a Data bus error in bcma_sprom_get() when reading out the sprom for the SoC. This fixes a regression introduced in commit: commit 10d8493cd9efd38b1947b7a74276dbdc8311aa1a Author: Arend van Spriel Date: Tue Mar 6 15:50:48 2012 +0100 bcma: add support for on-chip OTP memory used for SPROM storage This patch was tested on a Netgear WNDR3400 (Broadcom BCM4718 SoC). Reported-by: Nick Bowler Signed-off-by: Hauke Mehrtens Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index cdcf75c0954f..3e2a6002aae6 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -404,16 +404,19 @@ int bcma_sprom_get(struct bcma_bus *bus) return -EOPNOTSUPP; if (!bcma_sprom_ext_available(bus)) { + bool sprom_onchip; + /* * External SPROM takes precedence so check * on-chip OTP only when no external SPROM * is present. */ - if (bcma_sprom_onchip_available(bus)) { + sprom_onchip = bcma_sprom_onchip_available(bus); + if (sprom_onchip) { /* determine offset */ offset = bcma_sprom_onchip_offset(bus); } - if (!offset) { + if (!offset || !sprom_onchip) { /* * Maybe there is no SPROM on the device? * Now we ask the arch code if there is some sprom From c291be9dba370ba696a0d482249a212cf5c15f45 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Apr 2012 15:16:42 +0100 Subject: [PATCH 287/438] drm/i915: Hold mode_config lock whilst changing mode for lastclose() Upon lastclose(), we switch back to the fbcon configuration. This requires taking the mode_config lock in order to serialise the change with output probing elsewhere. Reported-by: Oleksij Rempel References: https://bugs.freedesktop.org/show_bug.cgi?id=48652 Signed-off-by: Chris Wilson Cc: stable@kernel.org Acked-by: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 19ecd78b8a2c..6e9ee33fd412 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev) struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; + mutex_lock(&dev->mode_config.mutex); + ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); @@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev) /* Be sure to shut off any planes that may be active */ list_for_each_entry(plane, &config->plane_list, head) plane->funcs->disable_plane(plane); + + mutex_unlock(&dev->mode_config.mutex); } From d22053cdbd914a6c97ea101adf411a8fd7e282ad Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 16 Apr 2012 12:07:02 -0400 Subject: [PATCH 288/438] nfsd: include cld.h in the headers_install target The cld.h file contains the definition of the upcall format to talk with nfsdcld. When I added the file though, I neglected to add it to the headers-y target, so make headers_install wasn't installing it. Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- include/linux/nfsd/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild index b8d4001212b3..5b7d84ac954a 100644 --- a/include/linux/nfsd/Kbuild +++ b/include/linux/nfsd/Kbuild @@ -1,3 +1,4 @@ +header-y += cld.h header-y += debug.h header-y += export.h header-y += nfsfh.h From 82ea267f7dc853a5e6a724916a70a10656efdfc2 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 16 Apr 2012 21:24:32 +0200 Subject: [PATCH 289/438] mfd: Fix modular builds of rc5t583 regulator support The combination of commit 1b1247dd75aa5cf5fae54a3bec7280046e9c7957 "mfd: Add support for RICOH PMIC RC5T583" and commit 6ffc3270210efa2bea526953a142ffc908f5bd86 "regulator: Add support for RICOH PMIC RC5T583 regulator" are causing the i386 allmodconfig builds to fail with this: ERROR: "rc5t583_update" [drivers/regulator/rc5t583-regulator.ko] undefined! ERROR: "rc5t583_set_bits" [drivers/regulator/rc5t583-regulator.ko] undefined! ERROR: "rc5t583_clear_bits" [drivers/regulator/rc5t583-regulator.ko] undefined! ERROR: "rc5t583_read" [drivers/regulator/rc5t583-regulator.ko] undefined! and this: ERROR: "rc5t583_ext_power_req_config" [drivers/regulator/rc5t583-regulator.ko] undefined! For the 1st four, make the simple ops static inline, instead of polluting the namespace with trivial exports. For the last one, add an EXPORT_SYMBOL. Signed-off-by: Paul Gortmaker Signed-off-by: Samuel Ortiz --- drivers/mfd/rc5t583.c | 39 +----------------------------- include/linux/mfd/rc5t583.h | 47 ++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index 99ef944c621d..44afae0a69ce 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = { {.name = "rc5t583-key", } }; -int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_write(rc5t583->regmap, reg, val); -} - -int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - unsigned int ival; - int ret; - ret = regmap_read(rc5t583->regmap, reg, &ival); - if (!ret) - *val = (uint8_t)ival; - return ret; -} - -int rc5t583_set_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -int rc5t583_clear_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -int rc5t583_update(struct device *dev, unsigned int reg, - unsigned int val, unsigned int mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} - static int __rc5t583_set_ext_pwrreq1_control(struct device *dev, int id, int ext_pwr, int slots) { @@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id, ds_id, ext_pwr_req); return 0; } +EXPORT_SYMBOL(rc5t583_ext_power_req_config); static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, struct rc5t583_platform_data *pdata) diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h index a2c61609d21d..0b64b19d81ab 100644 --- a/include/linux/mfd/rc5t583.h +++ b/include/linux/mfd/rc5t583.h @@ -26,6 +26,7 @@ #include #include +#include #define RC5T583_MAX_REGS 0xF8 @@ -279,14 +280,44 @@ struct rc5t583_platform_data { bool enable_shutdown; }; -int rc5t583_write(struct device *dev, u8 reg, uint8_t val); -int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val); -int rc5t583_set_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask); -int rc5t583_clear_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask); -int rc5t583_update(struct device *dev, unsigned int reg, - unsigned int val, unsigned int mask); +static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_write(rc5t583->regmap, reg, val); +} + +static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + unsigned int ival; + int ret; + ret = regmap_read(rc5t583->regmap, reg, &ival); + if (!ret) + *val = (uint8_t)ival; + return ret; +} + +static inline int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); +} + +static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); +} + +static inline int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, mask, val); +} + int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id, int ext_pwr_req, int deepsleep_slot_nr); int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base); From a49bcabedc18319f673319d5e71b5751e3978179 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 11 Apr 2012 23:23:41 +0200 Subject: [PATCH 290/438] can: usb: PCAN-USB Pro: fix mem leaks in pcan_usb_pro_init() on error paths If either call to pcan_usb_pro_send_req() in drivers/net/can/usb/peak_usb/pcan_usb_pro.c::pcan_usb_pro_init() fails, we'll leak the memory we allocated to 'usb_if' with kzalloc() when the 'usb_if' variable goes out of scope without having been assigned to anything as we 'return err;'. Fix this by adding appropriate kfree(usb_if) calls to the error paths. Signed-off-by: Jesper Juhl Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 5234586dff15..629c4ba5d49d 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_FW, &fi, sizeof(fi)); if (err) { + kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s firmware info (err %d)\n", pcan_usb_pro.name, err); @@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_BL, &bi, sizeof(bi)); if (err) { + kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s bootloader info (err %d)\n", pcan_usb_pro.name, err); From c06a9ebdb7a4f4823d4225fe789d8c20a1d534eb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 16 Apr 2012 13:35:11 -0600 Subject: [PATCH 291/438] checkpatch: revert --strict test for net/ and drivers/net block comment style Revert the --strict test for the old preferred block comment style in drivers/net and net/ Reported-by: Ingo Molnar Signed-off-by: Joe Perches Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index de639eeeed50..faea0ec612bf 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1869,12 +1869,6 @@ sub process { "No space is necessary after a cast\n" . $hereprev); } - if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && - $prevrawline =~ /^\+[ \t]*$/) { - CHK("BLOCK_COMMENT_STYLE", - "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev); - } - # check for spaces at the beginning of a line. # Exceptions: # 1) within comments From 57f73c2c89a5d3b2ed87201c8100d1fa989a1a65 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 16 Apr 2012 18:55:26 -0400 Subject: [PATCH 292/438] ext4: fix handling of journalled quota options Commit 26092bf5 broke handling of journalled quota mount options by trying to parse argument of every mount option as a number. Fix this by dealing with the quota options before we call match_int(). Thanks to Jan Kara for discovering this regression. Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara --- fs/ext4/super.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ef7db5044262..6da193564e43 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) ext4_msg(sb, KERN_ERR, "Cannot change journaled " "quota options when quota turned on"); - return 0; + return -1; } qname = match_strdup(args); if (!qname) { ext4_msg(sb, KERN_ERR, "Not enough memory for storing quotafile name"); - return 0; + return -1; } if (sbi->s_qf_names[qtype] && strcmp(sbi->s_qf_names[qtype], qname)) { ext4_msg(sb, KERN_ERR, "%s quota file already specified", QTYPE2NAME(qtype)); kfree(qname); - return 0; + return -1; } sbi->s_qf_names[qtype] = qname; if (strchr(sbi->s_qf_names[qtype], '/')) { @@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) "quotafile must be on filesystem root"); kfree(sbi->s_qf_names[qtype]); sbi->s_qf_names[qtype] = NULL; - return 0; + return -1; } set_opt(sb, QUOTA); return 1; @@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) sbi->s_qf_names[qtype]) { ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" " when quota turned on"); - return 0; + return -1; } /* * The space will be released later when all options are confirmed @@ -1450,6 +1450,16 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, const struct mount_opts *m; int arg = 0; +#ifdef CONFIG_QUOTA + if (token == Opt_usrjquota) + return set_qf_name(sb, USRQUOTA, &args[0]); + else if (token == Opt_grpjquota) + return set_qf_name(sb, GRPQUOTA, &args[0]); + else if (token == Opt_offusrjquota) + return clear_qf_name(sb, USRQUOTA); + else if (token == Opt_offgrpjquota) + return clear_qf_name(sb, GRPQUOTA); +#endif if (args->from && match_int(args, &arg)) return -1; switch (token) { @@ -1549,18 +1559,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, sbi->s_mount_opt |= m->mount_opt; } #ifdef CONFIG_QUOTA - } else if (token == Opt_usrjquota) { - if (!set_qf_name(sb, USRQUOTA, &args[0])) - return -1; - } else if (token == Opt_grpjquota) { - if (!set_qf_name(sb, GRPQUOTA, &args[0])) - return -1; - } else if (token == Opt_offusrjquota) { - if (!clear_qf_name(sb, USRQUOTA)) - return -1; - } else if (token == Opt_offgrpjquota) { - if (!clear_qf_name(sb, GRPQUOTA)) - return -1; } else if (m->flags & MOPT_QFMT) { if (sb_any_quota_loaded(sb) && sbi->s_jquota_fmt != m->mount_opt) { From c76f39bddb84f93f70a5520d9253ec0317bec216 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Mon, 16 Apr 2012 16:28:01 -0700 Subject: [PATCH 293/438] ia64: fix futex_atomic_cmpxchg_inatomic() Michel Lespinasse cleaned up the futex calling conventions in commit 37a9d912b24f ("futex: Sanitize cmpxchg_futex_value_locked API"). But the ia64 implementation was subtly broken. Gcc does not know that register "r8" will be updated by the fault handler if the cmpxchg instruction takes an exception. So it feels safe in letting the initialization of r8 slide to after the cmpxchg. Result: we always return 0 whether the user address faulted or not. Fix by moving the initialization of r8 into the __asm__ code so gcc won't move it. Reported-by: Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42757 Tested-by: Acked-by: Michel Lespinasse Cc: stable@vger.kernel.org # v2.6.39+ Signed-off-by: Tony Luck Signed-off-by: Linus Torvalds --- arch/ia64/include/asm/futex.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index 0ab82cc2dc8f..d2bf1fd5e44f 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h @@ -106,15 +106,16 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8") = 0; + register unsigned long r8 __asm ("r8"); unsigned long prev; __asm__ __volatile__( " mf;; \n" - " mov ar.ccv=%3;; \n" - "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n" + " mov %0=r0 \n" + " mov ar.ccv=%4;; \n" + "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "=r" (prev) + : "=r" (r8), "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); From 5191d566c023079fa283adc48b71854e9d74ffd5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 16 Apr 2012 19:21:39 -0700 Subject: [PATCH 294/438] Documentation: maintainer change I'm dropping off as Documentation/ maintainer. Rob Landley has agreed to take it over. Thanks, Rob. I'll still be around reviewing patches and testing. Signed-off-by: Randy Dunlap Acked-by: Rob Landley Signed-off-by: Linus Torvalds --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index b0f1073c40b0..1a2f8f5823e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2321,9 +2321,9 @@ S: Supported F: drivers/acpi/dock.c DOCUMENTATION -M: Randy Dunlap +M: Rob Landley L: linux-doc@vger.kernel.org -T: quilt http://xenotime.net/kernel-doc-patches/current/ +T: TBD S: Maintained F: Documentation/ From a6cb9ee7cabe68002c3f2ab07224ea27d2617cf1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 16 Apr 2012 23:07:50 +0200 Subject: [PATCH 295/438] PCI: Retry BARs restoration for Type 0 headers only Some shortcomings introduced into pci_restore_state() by commit 26f41062f28d ("PCI: check for pci bar restore completion and retry") have been fixed by recent commit ebfc5b802fa76 ("PCI: Fix regression in pci_restore_state(), v3"), but that commit treats all PCI devices as those with Type 0 configuration headers. That is not entirely correct, because Type 1 and Type 2 headers have different layouts. In particular, the area occupied by BARs in Type 0 config headers contains the secondary status register in Type 1 ones and it doesn't make sense to retry the restoration of that register even if the value read back from it after a write is not the same as the written one (it very well may be different). For this reason, make pci_restore_state() only retry the restoration of BARs for Type 0 config headers. This effectively makes it behave as before commit 26f41062f28d for all header types except for Type 0. Tested-by: Mikko Vinni Signed-off-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds --- drivers/pci/pci.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d20f1334792b..111569ccab43 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -991,8 +991,8 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset, } } -static void pci_restore_config_space(struct pci_dev *pdev, int start, int end, - int retry) +static void pci_restore_config_space_range(struct pci_dev *pdev, + int start, int end, int retry) { int index; @@ -1002,6 +1002,18 @@ static void pci_restore_config_space(struct pci_dev *pdev, int start, int end, retry); } +static void pci_restore_config_space(struct pci_dev *pdev) +{ + if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { + pci_restore_config_space_range(pdev, 10, 15, 0); + /* Restore BARs before the command register. */ + pci_restore_config_space_range(pdev, 4, 9, 10); + pci_restore_config_space_range(pdev, 0, 3, 0); + } else { + pci_restore_config_space_range(pdev, 0, 15, 0); + } +} + /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with @@ -1015,13 +1027,7 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_pcie_state(dev); pci_restore_ats_state(dev); - pci_restore_config_space(dev, 10, 15, 0); - /* - * The Base Address register should be programmed before the command - * register(s) - */ - pci_restore_config_space(dev, 4, 9, 10); - pci_restore_config_space(dev, 0, 3, 0); + pci_restore_config_space(dev); pci_restore_pcix_state(dev); pci_restore_msi_state(dev); From 244b65dbfede788f2fa3fe2463c44d0809e97c6b Mon Sep 17 00:00:00 2001 From: David Ward Date: Sun, 15 Apr 2012 12:31:45 +0000 Subject: [PATCH 296/438] net_sched: gred: Fix oops in gred_dump() in WRED mode A parameter set exists for WRED mode, called wred_set, to hold the same values for qavg and qidlestart across all VQs. The WRED mode values had been previously held in the VQ for the default DP. After these values were moved to wred_set, the VQ for the default DP was no longer created automatically (so that it could be omitted on purpose, to have packets in the default DP enqueued directly to the device without using RED). However, gred_dump() was overlooked during that change; in WRED mode it still reads qavg/qidlestart from the VQ for the default DP, which might not even exist. As a result, this command sequence will cause an oops: tc qdisc add dev $DEV handle $HANDLE parent $PARENT gred setup \ DPs 3 default 2 grio tc qdisc change dev $DEV handle $HANDLE gred DP 0 prio 8 $RED_OPTIONS tc qdisc change dev $DEV handle $HANDLE gred DP 1 prio 8 $RED_OPTIONS This fixes gred_dump() in WRED mode to use the values held in wred_set. Signed-off-by: David Ward Signed-off-by: David S. Miller --- net/sched/sch_gred.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 0b15236be7b6..8179494c269a 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -565,11 +565,8 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) opt.packets = q->packetsin; opt.bytesin = q->bytesin; - if (gred_wred_mode(table)) { - q->vars.qidlestart = - table->tab[table->def]->vars.qidlestart; - q->vars.qavg = table->tab[table->def]->vars.qavg; - } + if (gred_wred_mode(table)) + gred_load_wred_set(table, q); opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); From 4362aaf6054b9760652c7047cdf6fa852acb6cf7 Mon Sep 17 00:00:00 2001 From: David Ward Date: Mon, 16 Apr 2012 03:17:22 +0000 Subject: [PATCH 297/438] net_sched: red: Make minor corrections to comments Signed-off-by: David Ward Signed-off-by: David S. Miller --- include/net/red.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/red.h b/include/net/red.h index 77d4c3745cb5..ef46058d35bf 100644 --- a/include/net/red.h +++ b/include/net/red.h @@ -245,7 +245,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms * * dummy packets as a burst after idle time, i.e. * - * p->qavg *= (1-W)^m + * v->qavg *= (1-W)^m * * This is an apparently overcomplicated solution (f.e. we have to * precompute a table to make this calculation in reasonable time) @@ -279,7 +279,7 @@ static inline unsigned long red_calc_qavg_no_idle_time(const struct red_parms *p unsigned int backlog) { /* - * NOTE: p->qavg is fixed point number with point at Wlog. + * NOTE: v->qavg is fixed point number with point at Wlog. * The formula below is equvalent to floating point * version: * @@ -390,7 +390,7 @@ static inline void red_adaptative_algo(struct red_parms *p, struct red_vars *v) if (red_is_idling(v)) qavg = red_calc_qavg_from_idle_time(p, v); - /* p->qavg is fixed point number with point at Wlog */ + /* v->qavg is fixed point number with point at Wlog */ qavg >>= p->Wlog; if (qavg > p->target_max && p->max_P <= MAX_P_MAX) From a99ff7d0123b19ecad3b589480b6542716ab6b52 Mon Sep 17 00:00:00 2001 From: Stephane Fillod Date: Sun, 15 Apr 2012 11:38:29 +0000 Subject: [PATCH 298/438] net: usb: smsc75xx: fix mtu Make smsc75xx recalculate the hard_mtu after adjusting the hard_header_len. Without this, usbnet adjusts the MTU down to 1492 bytes, and the host is unable to receive standard 1500-byte frames from the device. Inspired by same fix on cdc_eem 78fb72f7936c01d5b426c03a691eca082b03f2b9. Tested on ARM/Omap3 with EVB-LAN7500-LC. Signed-off-by: Stephane Fillod Signed-off-by: David S. Miller --- drivers/net/usb/smsc75xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 187d01ccb973..a2349483cd2a 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1051,6 +1051,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc75xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } From 890fdf2a0cb88202d1427589db2cf29c1bdd3c1d Mon Sep 17 00:00:00 2001 From: Hiroaki SHIMODA Date: Sun, 15 Apr 2012 13:26:01 +0000 Subject: [PATCH 299/438] dummy: Add ndo_uninit(). In register_netdevice(), when ndo_init() is successful and later some error occurred, ndo_uninit() will be called. So dummy deivce is desirable to implement ndo_uninit() method to free percpu stats for this case. And, ndo_uninit() is also called along with dev->destructor() when device is unregistered, so in order to prevent dev->dstats from being freed twice, dev->destructor is modified to free_netdev(). Signed-off-by: Hiroaki SHIMODA Signed-off-by: David S. Miller --- drivers/net/dummy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index d5c6d92f1ee7..442d91a2747b 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev) return 0; } -static void dummy_dev_free(struct net_device *dev) +static void dummy_dev_uninit(struct net_device *dev) { free_percpu(dev->dstats); - free_netdev(dev); } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, + .ndo_uninit = dummy_dev_uninit, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = dummy_dev_free; + dev->destructor = free_netdev; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; From 6b5e7d9ef793c55d72679f058514f33c4258f286 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 15 Apr 2012 11:27:12 +0200 Subject: [PATCH 300/438] xen/grant-table: add error-handling code on failure of gnttab_resume Jump to the label ini_nomem as done on the failure of the page allocations above. The code at ini_nomem is modified to accommodate different return values. Signed-off-by: Julia Lawall Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/grant-table.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 1cd94daa71db..f805918a993f 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -1026,6 +1026,7 @@ int gnttab_init(void) int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; + int ret; nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1044,12 +1045,16 @@ int gnttab_init(void) nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); - if (gnttab_list[i] == NULL) + if (gnttab_list[i] == NULL) { + ret = -ENOMEM; goto ini_nomem; + } } - if (gnttab_resume() < 0) - return -ENODEV; + if (gnttab_resume() < 0) { + ret = -ENODEV; + goto ini_nomem; + } nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1067,7 +1072,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); - return -ENOMEM; + return ret; } EXPORT_SYMBOL_GPL(gnttab_init); From bfdd769ac51cb68cb99902192fac81bc67cb23b0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 17 Apr 2012 16:58:35 +1000 Subject: [PATCH 301/438] m68knommu: fix id number for second eth device on 5275 ColdFire The second ColdFire FEC ethernet device should have an id number of 1, not 0. Otherwise it clashes with the first FEC ethernet device. On booting a kernel on a 5275 based board you will get messages out of the kernel like this: <4>------------[ cut here ]------------ <4>WARNING: at fs/sysfs/dir.c:508 0x0a8b50() <4>sysfs: cannot create duplicate filename 'fec.0' And likely you won't be able to completely boot up after this at all. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c index fa50c48292ff..7af97362b95c 100644 --- a/arch/m68k/platform/coldfire/device.c +++ b/arch/m68k/platform/coldfire/device.c @@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = { static struct platform_device mcf_fec1 = { .name = "fec", - .id = 0, + .id = 1, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, }; From 938ed25008d665d1dd937ca251d1aabb363113c6 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 17 Apr 2012 17:06:34 +1000 Subject: [PATCH 302/438] m68knommu: make sure 2nd FEC eth interface pins are enabled on 5275 ColdFire The CONFIG_FEC2 define was removed from the kernel many versions ago. But it is still being used to set the multi-function pins when compiling for a ColdFire 527[45] SoC that has 2 ethernet interfaces. Remove the last remaining uses of this define, and so fix the setting of the pins for the 2nd ethernet interface. Signed-off-by: Greg Ungerer --- arch/m68k/configs/m5275evb_defconfig | 1 - arch/m68k/platform/527x/config.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/arch/m68k/configs/m5275evb_defconfig b/arch/m68k/configs/m5275evb_defconfig index 33c32aeca12b..a1230e82bb1e 100644 --- a/arch/m68k/configs/m5275evb_defconfig +++ b/arch/m68k/configs/m5275evb_defconfig @@ -49,7 +49,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_FEC=y -CONFIG_FEC2=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_PPP=y diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c index 7ed848c3b848..f91a53294c35 100644 --- a/arch/m68k/platform/527x/config.c +++ b/arch/m68k/platform/527x/config.c @@ -74,9 +74,7 @@ static void __init m527x_fec_init(void) writew(par | 0xf00, MCF_IPSBAR + 0x100082); v = readb(MCF_IPSBAR + 0x100078); writeb(v | 0xc0, MCF_IPSBAR + 0x100078); -#endif -#ifdef CONFIG_FEC2 /* Set multi-function pins to ethernet mode for fec1 */ par = readw(MCF_IPSBAR + 0x100082); writew(par | 0xa0, MCF_IPSBAR + 0x100082); From 5509fea59bb1bad4ead7d9a194cb4555c1350e1c Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 6 Apr 2012 12:52:53 +0200 Subject: [PATCH 303/438] leds-atmel-pwm.c: Make pwmled_probe() __devinit Commit 892a884 (leds: convert led platform drivers to module_platform_driver) is omitting the section mismatch error: so change annotation of the probe function to __devinit instead of __init. Signed-off-by: Nicolas Ferre Cc: Richard Purdie Cc: Andrew Morton --- drivers/leds/leds-atmel-pwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c index 800243b6037e..64ad702a2ecc 100644 --- a/drivers/leds/leds-atmel-pwm.c +++ b/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b) * NOTE: we reuse the platform_data structure of GPIO leds, * but repurpose its "gpio" number as a PWM channel number. */ -static int __init pwmled_probe(struct platform_device *pdev) +static int __devinit pwmled_probe(struct platform_device *pdev) { const struct gpio_led_platform_data *pdata; struct pwmled *leds; From b548a27b2e92ad171cc8b8d00bac5e15bb2d2956 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 6 Apr 2012 14:35:38 +0200 Subject: [PATCH 304/438] USB: ohci-at91: change annotations for probe/remove functions Add __devinit and __devexit on *_probe() and *_remove() functions with proper modification of struct platform_driver. Signed-off-by: Nicolas Ferre Acked-by: Alan Stern Cc: linux-usb@vger.kernel.org --- drivers/usb/host/ohci-at91.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 09f597ad6e00..13ebeca8e73e 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int usb_hcd_at91_probe(const struct hc_driver *driver, +static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { int retval; @@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, * context, "rmmod" or something similar. * */ -static void usb_hcd_at91_remove(struct usb_hcd *hcd, +static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); @@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) { struct at91_usbh_data *pdata; int i; @@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); } -static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev) { struct at91_usbh_data *pdata = pdev->dev.platform_data; int i; @@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove = ohci_hcd_at91_drv_remove, + .remove = __devexit_p(ohci_hcd_at91_drv_remove), .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, From 70756027b0a01cb0bebf2e20d8d28e8103025734 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Mon, 16 Apr 2012 10:58:12 +0200 Subject: [PATCH 305/438] USB: gadget/at91_udc: add gpio_to_irq() function to vbus interrupt Now that we are using irqdomains, we need to convert GPIO pins to Linux IRQ numbers using the gpio_to_irq() function. This call is added to request/free_irq calls. Signed-off-by: Nicolas Ferre Acked-by: Felipe Balbi Cc: linux-usb@vger.kernel.org --- drivers/usb/gadget/at91_udc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 0c935d7c65bd..9d7bcd910074 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } else { - if (request_irq(udc->board.vbus_pin, at91_vbus_irq, - 0, driver_name, udc)) { + if (request_irq(gpio_to_irq(udc->board.vbus_pin), + at91_vbus_irq, 0, driver_name, udc)) { DBG("request vbus irq %d failed\n", udc->board.vbus_pin); retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return 0; fail4: if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) - free_irq(udc->board.vbus_pin, udc); + free_irq(gpio_to_irq(udc->board.vbus_pin), udc); fail3: if (gpio_is_valid(udc->board.vbus_pin)) gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); if (gpio_is_valid(udc->board.vbus_pin)) { - free_irq(udc->board.vbus_pin, udc); + free_irq(gpio_to_irq(udc->board.vbus_pin), udc); gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); From f898fed0c27b2d46c3d8331e7825c25b6432b9f4 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 15 Mar 2012 11:31:58 +0100 Subject: [PATCH 306/438] dmaengine: Kconfig: fix Atmel at_hdmac entry Remove SoC dependency and make it generic for every Atmel ARM AT91. That will allow to select this driver for newer chips. Keep dependency on AT91 because of the use of an header file located in include/mach directory. Modify the comment to reflect this. Signed-off-by: Nicolas Ferre Acked-by: Vinod Koul --- drivers/dma/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cf9da362d64f..ef378b5b17e4 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -91,11 +91,10 @@ config DW_DMAC config AT_HDMAC tristate "Atmel AHB DMA support" - depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 + depends on ARCH_AT91 select DMA_ENGINE help - Support the Atmel AHB DMA controller. This can be integrated in - chips such as the Atmel AT91SAM9RL. + Support the Atmel AHB DMA controller. config FSL_DMA tristate "Freescale Elo and Elo Plus DMA support" From 63878acfafbc7a6ff90a2f8b3e31f0889bc61af6 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 7 Apr 2012 00:53:21 +0300 Subject: [PATCH 307/438] ARM: OMAP: sram: fix BUG in dpll code for !PM case _omap3_sram_configure_core_dpll is called when SDRC is reprogrammed, which is done regardless of CONFIG_PM setting, so we always need it's setup code too. Without this, we hit a BUG() on OMAP3 when kernel is built without CONFIG_PM: Reprogramming SDRC clock to 332000000 Hz ------------[ cut here ]------------ kernel BUG at arch/arm/plat-omap/sram.c:342! Internal error: Oops - BUG: 0 [#1] ARM ... [] (omap3_configure_core_dpll+0x68/0x6c) from [] (omap3_core_dpll_m2_set_rate+0x1) [] (omap3_core_dpll_m2_set_rate+0x138/0x1b0) from [] (omap2_clk_set_rate+0x14/0x2) [] (omap2_clk_set_rate+0x14/0x20) from [] (clk_set_rate+0x54/0x74) [] (clk_set_rate+0x54/0x74) from [] (omap_sdrc_init+0x70/0x90) [] (omap_sdrc_init+0x70/0x90) from [] (omap3pandora_init+0x11c/0x164) [] (omap3pandora_init+0x11c/0x164) from [] (customize_machine+0x20/0x28) [] (customize_machine+0x20/0x28) from [] (do_one_initcall+0xa0/0x16c) [] (do_one_initcall+0xa0/0x16c) from [] (kernel_init+0x104/0x1ac) [] (kernel_init+0x104/0x1ac) from [] (kernel_thread_exit+0x0/0x8) Signed-off-by: Grazvydas Ignotas Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index eec98afa0f83..f9a8c5341ee9 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -348,7 +348,6 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, sdrc_actim_ctrl_b_1, sdrc_mr_1); } -#ifdef CONFIG_PM void omap3_sram_restore_context(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; @@ -358,17 +357,18 @@ void omap3_sram_restore_context(void) omap3_sram_configure_core_dpll_sz); omap_push_sram_idle(); } -#endif /* CONFIG_PM */ - -#endif /* CONFIG_ARCH_OMAP3 */ static inline int omap34xx_sram_init(void) { -#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) omap3_sram_restore_context(); -#endif return 0; } +#else +static inline int omap34xx_sram_init(void) +{ + return 0; +} +#endif /* CONFIG_ARCH_OMAP3 */ static inline int am33xx_sram_init(void) { From e8e937be971d706061dc56220ff3605ab77622a7 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Tue, 3 Apr 2012 18:05:47 +0100 Subject: [PATCH 308/438] xen/gntdev: do not set VM_PFNMAP Since we are using the m2p_override we do have struct pages corresponding to the user vma mmap'ed by gntdev. Removing the VM_PFNMAP flag makes get_user_pages work on that vma. An example test case would be using a Xen userspace block backend (QDISK) on a file on NFS using O_DIRECT. CC: stable@kernel.org Signed-off-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/gntdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 99d8151c824a..1ffd03bf8e10 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; if (use_ptemod) - vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; + vma->vm_flags |= VM_DONTCOPY; vma->vm_private_data = map; From b960d6c43a63ebd2d8518b328da3816b833ee8cc Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Tue, 27 Mar 2012 14:52:44 +0100 Subject: [PATCH 309/438] xen/p2m: m2p_find_override: use list_for_each_entry_safe Use list_for_each_entry_safe and remove the spin_lock acquisition in m2p_find_override. Signed-off-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/p2m.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 1b267e75158d..7ed8cc3434c5 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -809,21 +809,17 @@ struct page *m2p_find_override(unsigned long mfn) { unsigned long flags; struct list_head *bucket = &m2p_overrides[mfn_hash(mfn)]; - struct page *p, *ret; + struct page *p, *t, *ret; ret = NULL; - spin_lock_irqsave(&m2p_override_lock, flags); - - list_for_each_entry(p, bucket, lru) { + list_for_each_entry_safe(p, t, bucket, lru) { if (page_private(p) == mfn) { ret = p; break; } } - spin_unlock_irqrestore(&m2p_override_lock, flags); - return ret; } From bce492c04ba8fc66a4ea0a52b181ba255daaaf54 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 17 Apr 2012 10:35:47 -0700 Subject: [PATCH 310/438] ARM: OMAP2+: UART: Fix incorrect population of default uart pads Commit (7496ba3 ARM: OMAP2+: UART: Add default mux for all uarts) wrongly added muxing of default pads for all uarts. This causes breakage on multiple boards using uart pins for alternate functions. For example, on zoom3 random oopses can be seen with nfsroot as the smsc911x ethernet FIFO timings on GPMC bus are controlled by gpmc_wait2 and gpmc_wait3 pins. This means we can't mux these pads to uart4 functionality as commit 7496ba3 was doing. Not all boards tend to use all uarts and most of unused uart pins are muxed for other purpose. This commit breaks the modules which where trying to use unused uart pins on their boards. So remove the default pad muxing. Note that this is not a complete fix, as we now rely on bootloader set muxing for the uart wake-up events. Further patching is needed to enable wake-up events for uarts that are already muxed to uart mode. Cc: Felipe Balbi Cc: Kevin Hilman Acked-by: Russ Dill Reported-by: Tony Lindgren Signed-off-by: Govindraj.R [tony@atomide.com: updated comments to describe oops on zoom3] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/serial.c | 116 ----------------------------------- 1 file changed, 116 deletions(-) diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 0cdd359a128e..2e351f52938a 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -120,124 +120,8 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX -static struct omap_device_pad default_uart1_pads[] __initdata = { - { - .name = "uart1_cts.uart1_cts", - .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - }, - { - .name = "uart1_rts.uart1_rts", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart1_tx.uart1_tx", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart1_rx.uart1_rx", - .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, - .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - }, -}; - -static struct omap_device_pad default_uart2_pads[] __initdata = { - { - .name = "uart2_cts.uart2_cts", - .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - }, - { - .name = "uart2_rts.uart2_rts", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart2_tx.uart2_tx", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart2_rx.uart2_rx", - .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, - .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - }, -}; - -static struct omap_device_pad default_uart3_pads[] __initdata = { - { - .name = "uart3_cts_rctx.uart3_cts_rctx", - .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, - }, - { - .name = "uart3_rts_sd.uart3_rts_sd", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart3_tx_irtx.uart3_tx_irtx", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart3_rx_irrx.uart3_rx_irrx", - .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, - .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, - .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, - }, -}; - -static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { - { - .name = "gpmc_wait2.uart4_tx", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "gpmc_wait3.uart4_rx", - .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, - .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, - .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, - }, -}; - -static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { - { - .name = "uart4_tx.uart4_tx", - .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, - }, - { - .name = "uart4_rx.uart4_rx", - .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, - .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, - .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, - }, -}; - static void omap_serial_fill_default_pads(struct omap_board_data *bdata) { - switch (bdata->id) { - case 0: - bdata->pads = default_uart1_pads; - bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); - break; - case 1: - bdata->pads = default_uart2_pads; - bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); - break; - case 2: - bdata->pads = default_uart3_pads; - bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); - break; - case 3: - if (cpu_is_omap44xx()) { - bdata->pads = default_omap4_uart4_pads; - bdata->pads_cnt = - ARRAY_SIZE(default_omap4_uart4_pads); - } else if (cpu_is_omap3630()) { - bdata->pads = default_omap36xx_uart4_pads; - bdata->pads_cnt = - ARRAY_SIZE(default_omap36xx_uart4_pads); - } - break; - default: - break; - } } #else static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} From 973ef21a676e55a8e1a100a6e109f0c116ea75e8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 16 Apr 2012 14:56:48 +0200 Subject: [PATCH 311/438] mac80211: fix truncated packets in cooked monitor rx Cooked monitor rx was recently changed to use ieee80211_add_rx_radiotap_header instead of generating only limited radiotap information. ieee80211_add_rx_radiotap_header assumes that FCS info is still present if the hardware supports receiving it, however when cooked monitor rx packets are processed, FCS info has already been stripped. Fix this by adding an extra flag indicating FCS presence. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bcfe8c77c839..d64e285400aa 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -103,7 +103,7 @@ static void ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_rate *rate, - int rtap_len) + int rtap_len, bool has_fcs) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_header *rthdr; @@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, } /* IEEE80211_RADIOTAP_FLAGS */ - if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) + if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)) *pos |= IEEE80211_RADIOTAP_F_FCS; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) *pos |= IEEE80211_RADIOTAP_F_BADFCS; @@ -294,7 +294,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, } /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, + true); skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2571,7 +2572,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, goto out_free_skb; /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, + false); skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; From 15fae50a9bd28a9fe490b053ff4353f8a38ea5a0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 16 Apr 2012 12:03:35 -0700 Subject: [PATCH 312/438] MAINTAINERS: Add maintainer for iwlwifi Add Johannes Berg as the primary maintainer for iwlwifi driver Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6010b9d13b47..f6dfba3d96a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3592,6 +3592,7 @@ S: Supported F: drivers/net/wireless/iwlegacy/ INTEL WIRELESS WIFI LINK (iwlwifi) +M: Johannes Berg M: Wey-Yi Guy M: Intel Linux Wireless L: linux-wireless@vger.kernel.org From 6741e7f048dacc92e37c5d724ff5c64e45f6c2c9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 16 Apr 2012 22:10:42 +0200 Subject: [PATCH 313/438] mac80211: fix logic error in ibss channel type check The broken check leads to rate control attempting to use HT40 while the driver is configured for HT20. This leads to interesting hardware issues. HT40 can only be used if the channel type is either HT40- or HT40+ and if the channel type of the cell matches the local type. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- net/mac80211/ibss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 33fd8d9f714e..cef7c29214a8 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -457,8 +457,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, * fall back to HT20 if we don't use or use * the other extension channel */ - if ((channel_type == NL80211_CHAN_HT40MINUS || - channel_type == NL80211_CHAN_HT40PLUS) && + if (!(channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS) || channel_type != sdata->u.ibss.channel_type) sta_ht_cap_new.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; From fd09c85fe15aa66a69f091ba178817d5ef82476d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 17 Apr 2012 08:34:50 +0530 Subject: [PATCH 314/438] ath9k: Fix TX fragmentation Assigning sequence number for frames without taking care of the fragment field breaks transmission of fragmented frames. Fix this by assigning the fragment number properly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 834e6bc45e8b..23eaa1b26ebe 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_frame_info *fi = get_frame_info(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_buf *bf; + int fragno; u16 seqno; bf = ath_tx_get_buffer(sc); @@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ATH_TXBUF_RESET(bf); if (tid) { + fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; seqno = tid->seq_next; hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); - INCR(tid->seq_next, IEEE80211_SEQ_MAX); + + if (fragno) + hdr->seq_ctrl |= cpu_to_le16(fragno); + + if (!ieee80211_has_morefrags(hdr->frame_control)) + INCR(tid->seq_next, IEEE80211_SEQ_MAX); + bf->bf_state.seqno = seqno; } From 5ae256dcd91bf308826a4ac19598b27ebb86a536 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 13 Apr 2012 23:25:04 +0530 Subject: [PATCH 315/438] ARM: OMAP: serial: Fix the ocp smart idlemode handling bug The current serial UART code, while fidling with ocp idlemode bits, forget about the smart idle wakeup bit even if it is supported by UART IP block. This will lead to missing the module wakeup on OMAP's where the smart idle wakeup is supported. This was the root cause of the console sluggishness issue, I have been observing on OMAP4 devices and also can be potential reason for some other UART wakeup issues. Signed-off-by: Santosh Shilimkar Acked-by: Kevin Hilman Acked-by: Govindraj.R Reviewed-by: Paul Walmsley Cc: stable@vger.kernel.org Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/serial.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 2e351f52938a..9fc2f44188cb 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -108,8 +108,14 @@ static void omap_uart_set_noidle(struct platform_device *pdev) static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); + u8 idlemode; - omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); + if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + + omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); } #else From 6aaec67da1e41a0752a2b903b989e73b9f02e182 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 10 Apr 2012 18:36:02 -0600 Subject: [PATCH 316/438] ARM: OMAP1: DMTIMER: fix broken timer clock source selection DMTIMER source selection on OMAP1 is broken. omap1_dm_timer_set_src() tries to use __raw_{read,write}l() to read from and write to physical addresses, but those functions take virtual addresses. sparse caught this: arch/arm/mach-omap1/timer.c:50:13: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap1/timer.c:50:13: expected void const volatile [noderef] * arch/arm/mach-omap1/timer.c:50:13: got unsigned int arch/arm/mach-omap1/timer.c:52:9: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap1/timer.c:52:9: expected void const volatile [noderef] * arch/arm/mach-omap1/timer.c:52:9: got unsigned int Fix by using omap_{read,writel}(), just like the other users of the MOD_CONF_CTRL_1 register in the OMAP1 codebase. Of course, in the long term, removing omap_{read,write}l() is the appropriate thing to do; but this will take some work to do this cleanly. Looks like this was caused by 97933d6 (ARM: OMAP1: dmtimer: conversion to platform devices) that dangerously moved code and changed it in the same patch. Signed-off-by: Paul Walmsley Cc: Tarun Kanti DebBarma Cc: stable@vger.kernel.org [tony@atomide.com: updated comments to include the breaking commit] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 6e90665a7c47..fb202af01d0d 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev, int n = (pdev->id - 1) << 1; u32 l; - l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); + l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); l |= source << n; - __raw_writel(l, MOD_CONF_CTRL_1); + omap_writel(l, MOD_CONF_CTRL_1); return 0; } From 34948a947d1a576c10afee6d14792fd237549577 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Fri, 6 Apr 2012 07:20:21 +0000 Subject: [PATCH 317/438] ixgbe: add missing rtnl_lock in PM resume path Upon resume from standby, ixgbe may trigger the ASSERT_RTNL() in netif_set_real_num_tx_queues(). The call stack is: netif_set_real_num_tx_queues ixgbe_set_num_queues ixgbe_init_interrupt_scheme ixgbe_resume Signed-off-by: Benjamin Poirier Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index dac7c01f8332..9e2be8c45c2d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -4836,7 +4836,9 @@ static int ixgbe_resume(struct pci_dev *pdev) pci_wake_from_d3(pdev, false); + rtnl_lock(); err = ixgbe_init_interrupt_scheme(adapter); + rtnl_unlock(); if (err) { e_dev_err("Cannot initialize interrupts for device\n"); return err; From b2db497eb25510052fc2d3152384f964b3312004 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 7 Apr 2012 04:57:29 +0000 Subject: [PATCH 318/438] ixgbe: Identify FCoE rings earlier to resolve memory corruption w/ FCoE This patch makes it so that we identify FCoE rings earlier than ixgbe_set_rx_buffer_len. Instead we identify the Rx FCoE rings at allocation time in ixgbe_alloc_q_vector. The motivation behind this change is to avoid memory corruption when FCoE is enabled. Without this change we were initializing the rings at 0, and 2K on systems with 4K pages, then when we bumped the buffer size to 4K with order 1 pages we were accessing offsets 2K and 6K instead of 0 and 4K. This was resulting in memory corruptions. Signed-off-by: Alexander Duyck Acked-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 10 ++++++++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 027d7a75be39..ed1b47dc0834 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx, if (adapter->hw.mac.type == ixgbe_mac_82599EB) set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); +#ifdef IXGBE_FCOE + if (adapter->netdev->features & NETIF_F_FCOE_MTU) { + struct ixgbe_ring_feature *f; + f = &adapter->ring_feature[RING_F_FCOE]; + if ((rxr_idx >= f->mask) && + (rxr_idx < f->mask + f->indices)) + set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); + } + +#endif /* IXGBE_FCOE */ /* apply Rx specific ring traits */ ring->count = adapter->rx_ring_count; ring->queue_index = rxr_idx; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 9e2be8c45c2d..a7f3cd872caf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) set_ring_rsc_enabled(rx_ring); else clear_ring_rsc_enabled(rx_ring); -#ifdef IXGBE_FCOE - if (netdev->features & NETIF_F_FCOE_MTU) { - struct ixgbe_ring_feature *f; - f = &adapter->ring_feature[RING_F_FCOE]; - if ((i >= f->mask) && (i < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); - } -#endif /* IXGBE_FCOE */ } } From 8963c487a80b4688c9e68dcc504a90074aacc145 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 17 Apr 2012 15:22:39 -0400 Subject: [PATCH 319/438] USB: fix deadlock in bConfigurationValue attribute method This patch (as154) fixes a self-deadlock that occurs when userspace writes to the bConfigurationValue sysfs attribute for a hub with children. The task tries to lock the bandwidth_mutex at a time when it already owns the lock: The attribute's method calls usb_set_configuration(), which calls usb_disable_device() with the bandwidth_mutex held. usb_disable_device() unregisters the existing interfaces, which causes the hub driver to be unbound. The hub_disconnect() routine calls hub_quiesce(), which calls usb_disconnect() for each of the hub's children. usb_disconnect() attempts to acquire the bandwidth_mutex around a call to usb_disable_device(). The solution is to make usb_disable_device() acquire the mutex for itself instead of requiring the caller to hold it. Then the mutex can cover only the bandwidth deallocation operation and not the region where the interfaces are unregistered. This has the potential to change system behavior slightly when a config change races with another config or altsetting change. Some of the bandwidth released from the old config might get claimed by the other config or altsetting, make it impossible to restore the old config in case of a failure. But since we don't try to recover from config-change failures anyway, this doesn't matter. [This should be marked for stable kernels that contain the commit fccf4e86200b8f5edd9a65da26f150e32ba79808 "USB: Free bandwidth when usb_disable_device is called." That commit was marked for stable kernels as old as 2.6.32.] Signed-off-by: Alan Stern Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 3 --- drivers/usb/core/message.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a2aa9d652c67..ec6c97dadbe4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; - struct usb_hcd *hcd = bus_to_hcd(udev->bus); /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); - mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); - mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index aed3e07942d4..ca717da3be95 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. - * - * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ + mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,7 +1750,6 @@ free_interfaces: /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ - mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1763,6 +1762,7 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); From e65cdfae71cecec0fcd43a3f9ac8b5e4ae52db08 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Mon, 9 Apr 2012 15:48:55 -0400 Subject: [PATCH 320/438] usb: usbtest: avoid integer overflow in test_ctrl_queue() Avoid overflowing context.count = param->sglen * param->iterations, where both `sglen' and `iterations' are from userspace. | test_ctrl_queue() | usbtest_ioctl() Keep -EOPNOTSUPP for error code. Signed-off-by: Xi Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 959145baf3cf..967254afb6e8 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) struct ctrl_ctx context; int i; + if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) + return -EOPNOTSUPP; + spin_lock_init(&context.lock); context.dev = dev; init_completion(&context.complete); @@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) /* queued control messaging */ case 10: - if (param->sglen == 0) - break; retval = 0; dev_info(&intf->dev, "TEST 10: queue %d control calls, %d times\n", From 8bde9a62ee74afa89f593c563e926d163b1f6ada Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Mon, 9 Apr 2012 15:48:45 -0400 Subject: [PATCH 321/438] usb: usbtest: avoid integer overflow in alloc_sglist() A large `nents' from userspace could overflow the allocation size, leading to memory corruption. | alloc_sglist() | usbtest_ioctl() Use kmalloc_array() to avoid the overflow. Signed-off-by: Xi Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 967254afb6e8..cac67dea2bac 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); + sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); if (!sg) return NULL; sg_init_table(sg, nents); From 749541d19e70905e3971f2a08335a206a98e4d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 17 Apr 2012 21:37:29 +0200 Subject: [PATCH 322/438] USB: sierra: avoid QMI/wwan interface on MC77xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These devices have a number of non serial interfaces as well. Use the existing "Direct IP" blacklist to prevent binding to interfaces which are handled by other drivers. We also extend the "Direct IP" blacklist with with interfaces only seen in "QMI" mode, assuming that these devices use the same interface numbers for serial interfaces both in "Direct IP" and in "QMI" mode. Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index fdd5aa2c8d82..8c8bf806f6fa 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ - { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */ /* Sierra Wireless C885 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ @@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, From dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 17 Apr 2012 15:24:15 -0400 Subject: [PATCH 323/438] EHCI: fix criterion for resuming the root hub This patch (as1542) changes the criterion ehci-hcd uses to tell when it needs to resume the controller's root hub. A resume is needed when a port status change is detected, obviously, but only if the root hub is currently suspended. Right now the driver tests whether the root hub is running, and that is not the correct test. In particular, if the controller has died then the root hub should not be restarted. In addition, some buggy hardware occasionally requires the root hub to be running and sending out SOF packets even while it is nominally supposed to be suspended. In the end, the test needs to be changed. Rather than checking whether the root hub is currently running, the driver will now check whether the root hub is currently suspended. This will yield the correct behavior in all cases. Signed-off-by: Alan Stern CC: Peter Chen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 806cc95317aa..95ca07a8e1b5 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -910,7 +910,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (!(cmd & CMD_RUN)) + if (ehci->rh_state == EHCI_RH_SUSPENDED) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ From 86812bb0de1a3758dc6c7aa01a763158a7c0638a Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Tue, 17 Apr 2012 18:55:46 -0700 Subject: [PATCH 324/438] Smack: move label list initialization A kernel with Smack enabled will fail if tmpfs has xattr support. Move the initialization of predefined Smack label list entries to the LSM initialization from the smackfs setup. This became an issue when tmpfs acquired xattr support, but was never correct. Signed-off-by: Casey Schaufler Signed-off-by: James Morris --- security/smack/smack_lsm.c | 44 ++++++++++++++++++++++++++++---------- security/smack/smackfs.c | 14 ------------ 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 10056f2f6df3..45c32f074166 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3640,8 +3640,38 @@ struct security_operations smack_ops = { }; -static __init void init_smack_know_list(void) +static __init void init_smack_known_list(void) { + /* + * Initialize CIPSO locks + */ + spin_lock_init(&smack_known_huh.smk_cipsolock); + spin_lock_init(&smack_known_hat.smk_cipsolock); + spin_lock_init(&smack_known_star.smk_cipsolock); + spin_lock_init(&smack_known_floor.smk_cipsolock); + spin_lock_init(&smack_known_invalid.smk_cipsolock); + spin_lock_init(&smack_known_web.smk_cipsolock); + /* + * Initialize rule list locks + */ + mutex_init(&smack_known_huh.smk_rules_lock); + mutex_init(&smack_known_hat.smk_rules_lock); + mutex_init(&smack_known_floor.smk_rules_lock); + mutex_init(&smack_known_star.smk_rules_lock); + mutex_init(&smack_known_invalid.smk_rules_lock); + mutex_init(&smack_known_web.smk_rules_lock); + /* + * Initialize rule lists + */ + INIT_LIST_HEAD(&smack_known_huh.smk_rules); + INIT_LIST_HEAD(&smack_known_hat.smk_rules); + INIT_LIST_HEAD(&smack_known_star.smk_rules); + INIT_LIST_HEAD(&smack_known_floor.smk_rules); + INIT_LIST_HEAD(&smack_known_invalid.smk_rules); + INIT_LIST_HEAD(&smack_known_web.smk_rules); + /* + * Create the known labels list + */ list_add(&smack_known_huh.list, &smack_known_list); list_add(&smack_known_hat.list, &smack_known_list); list_add(&smack_known_star.list, &smack_known_list); @@ -3676,16 +3706,8 @@ static __init int smack_init(void) cred = (struct cred *) current->cred; cred->security = tsp; - /* initialize the smack_know_list */ - init_smack_know_list(); - /* - * Initialize locks - */ - spin_lock_init(&smack_known_huh.smk_cipsolock); - spin_lock_init(&smack_known_hat.smk_cipsolock); - spin_lock_init(&smack_known_star.smk_cipsolock); - spin_lock_init(&smack_known_floor.smk_cipsolock); - spin_lock_init(&smack_known_invalid.smk_cipsolock); + /* initialize the smack_known_list */ + init_smack_known_list(); /* * Register with LSM diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 5c32f36ff706..038811cb7e62 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1614,20 +1614,6 @@ static int __init init_smk_fs(void) smk_cipso_doi(); smk_unlbl_ambient(NULL); - mutex_init(&smack_known_floor.smk_rules_lock); - mutex_init(&smack_known_hat.smk_rules_lock); - mutex_init(&smack_known_huh.smk_rules_lock); - mutex_init(&smack_known_invalid.smk_rules_lock); - mutex_init(&smack_known_star.smk_rules_lock); - mutex_init(&smack_known_web.smk_rules_lock); - - INIT_LIST_HEAD(&smack_known_floor.smk_rules); - INIT_LIST_HEAD(&smack_known_hat.smk_rules); - INIT_LIST_HEAD(&smack_known_huh.smk_rules); - INIT_LIST_HEAD(&smack_known_invalid.smk_rules); - INIT_LIST_HEAD(&smack_known_star.smk_rules); - INIT_LIST_HEAD(&smack_known_web.smk_rules); - return err; } From 09c79b60960bdd4b00916219402eabfa5e479c5a Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 6 Feb 2012 20:07:04 +1100 Subject: [PATCH 325/438] mpi: Avoid using freed pointer in mpi_lshift_limbs() At the start of the function we assign 'a->d' to 'ap'. Then we use the RESIZE_IF_NEEDED macro on 'a' - this may free 'a->d' and replace it with newly allocaetd storage. In that case, we'll be operating on freed memory further down in the function when we index into 'ap[]'. Since we don't actually need 'ap' until after the use of the RESIZE_IF_NEEDED macro we can just delay the assignment to it until after we've potentially resized, thus avoiding the issue. While I was there anyway I also changed the integer variable 'n' to be const. It might as well be since we only assign to it once and use it as a constant, and then the compiler will tell us if we ever assign to it in the future. Signed-off-by: Jesper Juhl Acked-by: Dmitry Kasatkin Signed-off-by: James Morris --- lib/mpi/mpi-bit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c index 2f526627e4f5..0c505361da19 100644 --- a/lib/mpi/mpi-bit.c +++ b/lib/mpi/mpi-bit.c @@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n) */ int mpi_lshift_limbs(MPI a, unsigned int count) { - mpi_ptr_t ap = a->d; - int n = a->nlimbs; + const int n = a->nlimbs; + mpi_ptr_t ap; int i; if (!count || !n) @@ -187,6 +187,7 @@ int mpi_lshift_limbs(MPI a, unsigned int count) if (RESIZE_IF_NEEDED(a, n + count) < 0) return -ENOMEM; + ap = a->d; for (i = n - 1; i >= 0; i--) ap[i + count] = ap[i]; for (i = 0; i < count; i++) From b95465c8fcd7c8619ff9ff7bbf8038ab31c7f34b Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 16 Apr 2012 02:02:48 +0000 Subject: [PATCH 326/438] arcnet: rimi: Fix device name in debug output arcrimi_probe() calls BUGMSG() before register_netdev() happens. BUGMSG() itself prints dev->name, but as the format string hasn't been expanded by register_netdev() yet, the output contains bogus device name such as arc%d: Given: node 00h, shmem 0h, irq 0 As we don't know the device name yet, just drop the prefix completely from the debugging messages. Reported-by: Steven Young Signed-off-by: Jiri Kosina Signed-off-by: David S. Miller --- drivers/net/arcnet/arc-rimi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 25197b698dd6..b8b4c7ba884f 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev) BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); - BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", + BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0], dev->mem_start, dev->irq); if (dev->mem_start <= 0 || dev->irq <= 0) { - BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " + BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (dev->dev_addr[0] == 0) { - BUGMSG(D_NORMAL, "You need to specify your card's station " + BUGLVL(D_NORMAL) printk("You need to specify your card's station " "ID!\n"); return -ENODEV; } @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev) * will be taken. */ if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { - BUGMSG(D_NORMAL, "Card memory already allocated\n"); + BUGLVL(D_NORMAL) printk("Card memory already allocated\n"); return -ENODEV; } return arcrimi_found(dev); From edfb5d4687d587c9f714799c7ee27517118e12e6 Mon Sep 17 00:00:00 2001 From: Jiri Bohac Date: Mon, 16 Apr 2012 03:34:39 +0000 Subject: [PATCH 327/438] ipv6: fix rt6_update_expires Commit 1716a961 (ipv6: fix problem with expired dst cache) broke PMTU discovery. rt6_update_expires() calls dst_set_expires(), which only updates dst->expires if it has not been set previously (expires == 0) or if the new expires is earlier than the current dst->expires. rt6_update_expires() needs to zero rt->dst.expires, otherwise it will contain ivalid data left over from rt->dst.from and will confuse dst_set_expires(). Signed-off-by: Jiri Bohac Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index c64778fd5e13..cb8da1dac512 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -143,8 +143,14 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) static inline void rt6_update_expires(struct rt6_info *rt, int timeout) { - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); + if (!(rt->rt6i_flags & RTF_EXPIRES)) { + if (rt->dst.from) + dst_release(rt->dst.from); + /* dst_set_expires relies on expires == 0 + * if it has not been set previously. + */ + rt->dst.expires = 0; + } dst_set_expires(&rt->dst, timeout); rt->rt6i_flags |= RTF_EXPIRES; From cda31e10baf47a8a7d9360d9488fb76294be1ca3 Mon Sep 17 00:00:00 2001 From: Jiri Bohac Date: Mon, 16 Apr 2012 03:35:41 +0000 Subject: [PATCH 328/438] ipv6: clean up rt6_clean_expires Functionally, this change is a NOP. Semantically, rt6_clean_expires() wants to do rt->dst.from = NULL instead of rt->dst.expires = 0. It is clearing the RTF_EXPIRES flag, so the union is going to be treated as a pointer (dst.from) not a long (dst.expires). Signed-off-by: Jiri Bohac Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index cb8da1dac512..0ae759a6c76e 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -129,7 +129,7 @@ static inline void rt6_clean_expires(struct rt6_info *rt) dst_release(rt->dst.from); rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.expires = 0; + rt->dst.from = NULL; } static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) From 5b76d0600b2b08eef77f8e9226938b7b6bde3099 Mon Sep 17 00:00:00 2001 From: Christian Riesch Date: Mon, 16 Apr 2012 04:35:25 +0000 Subject: [PATCH 329/438] davinci_mdio: Fix MDIO timeout check Under heavy load (flood ping) it is possible for the MDIO timeout to expire before the loop checks the GO bit again. This patch adds an additional check whether the operation was done before actually returning -ETIMEDOUT. To reproduce this bug, flood ping the device, e.g., ping -f -l 1000 After some time, a "timed out waiting for user access" warning may appear. And even worse, link may go down since the PHY reported a timeout. Signed-off-by: Christian Riesch Cc: Cc: Cyril Chemparathy Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_mdio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 2757c7d6e633..e4e47088e26b 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data) __davinci_mdio_reset(data); return -EAGAIN; } + + reg = __raw_readl(®s->user[0].access); + if ((reg & USERACCESS_GO) == 0) + return 0; + dev_err(data->dev, "timed out waiting for user access\n"); return -ETIMEDOUT; } From 48159f009f5f92ef5962e7c278ac615d74242fa5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Apr 2012 05:22:12 +0000 Subject: [PATCH 330/438] drivers/net/wan/farsync.c: add missing iounmap Free card->mem in the error-handling code since it was successfully allocated just above. Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/wan/farsync.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index ebb9f24eefb5..1a623183cbe5 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) pr_err("Control memory remap failed\n"); pci_release_regions(pdev); pci_disable_device(pdev); + iounmap(card->mem); kfree(card); return -ENODEV; } From 4d846f02392a710f9604892ac3329e628e60a230 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 16 Apr 2012 23:28:07 +0000 Subject: [PATCH 331/438] tcp: fix tcp_grow_window() for large incoming frames tcp_grow_window() has to grow rcv_ssthresh up to window_clamp, allowing sender to increase its window. tcp_grow_window() still assumes a tcp frame is under MSS, but its no longer true with LRO/GRO. This patch fixes one of the performance issue we noticed with GRO on. Signed-off-by: Eric Dumazet Cc: Neal Cardwell Cc: Tom Herbert Acked-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9944c1d9a218..3ff364065376 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -335,6 +335,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) incr = __tcp_grow_window(sk, skb); if (incr) { + incr = max_t(int, incr, 2 * skb->len); tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp); inet_csk(sk)->icsk_ack.quick |= 1; From d3d4f0a025e621b82da08a76df4036d4267739dd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Apr 2012 14:03:53 +0000 Subject: [PATCH 332/438] net/sock.h: fix sk_peek_off kernel-doc warning Fix kernel-doc warning in net/sock.h: Warning(include/net/sock.h:377): No description found for parameter 'sk_peek_off' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/net/sock.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/sock.h b/include/net/sock.h index a6ba1f8871fd..188532ee88b6 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -246,6 +246,7 @@ struct cg_proto; * @sk_user_data: RPC layer private data * @sk_sndmsg_page: cached page for sendmsg * @sk_sndmsg_off: cached offset for sendmsg + * @sk_peek_off: current peek_offset value * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules * @sk_mark: generic packet mark From d52fc5dde171f030170a6cb78034d166b13c9445 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 17 Apr 2012 16:26:54 -0400 Subject: [PATCH 333/438] fcaps: clear the same personality flags as suid when fcaps are used If a process increases permissions using fcaps all of the dangerous personality flags which are cleared for suid apps should also be cleared. Thus programs given priviledge with fcaps will continue to have address space randomization enabled even if the parent tried to disable it to make it easier to attack. Signed-off-by: Eric Paris Reviewed-by: Serge Hallyn Signed-off-by: James Morris --- security/commoncap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/security/commoncap.c b/security/commoncap.c index 0cf4b53480a7..0ecf4ba321cb 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -505,6 +505,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) } skip: + /* if we have fs caps, clear dangerous personality flags */ + if (!cap_issubset(new->cap_permitted, old->cap_permitted)) + bprm->per_clear |= PER_CLEAR_ON_SETID; + + /* Don't let someone trace a set[ug]id/setpcap binary with the revised * credentials unless they have the appropriate permit */ From b922934d017f1cc831b017913ed7d1a56c558b43 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Mon, 16 Apr 2012 04:43:15 +0000 Subject: [PATCH 334/438] netns: do not leak net_generic data on failed init ops_init should free the net_generic data on init failure and __register_pernet_operations should not call ops_free when NET_NS is not enabled. Signed-off-by: Julian Anastasov Reviewed-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/core/net_namespace.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 0e950fda9a0a..31a5ae51a45c 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -83,21 +83,29 @@ assign: static int ops_init(const struct pernet_operations *ops, struct net *net) { - int err; + int err = -ENOMEM; + void *data = NULL; + if (ops->id && ops->size) { - void *data = kzalloc(ops->size, GFP_KERNEL); + data = kzalloc(ops->size, GFP_KERNEL); if (!data) - return -ENOMEM; + goto out; err = net_assign_generic(net, *ops->id, data); - if (err) { - kfree(data); - return err; - } + if (err) + goto cleanup; } + err = 0; if (ops->init) - return ops->init(net); - return 0; + err = ops->init(net); + if (!err) + return 0; + +cleanup: + kfree(data); + +out: + return err; } static void ops_free(const struct pernet_operations *ops, struct net *net) @@ -448,12 +456,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) { - int err = 0; - err = ops_init(ops, &init_net); - if (err) - ops_free(ops, &init_net); - return err; - + return ops_init(ops, &init_net); } static void __unregister_pernet_operations(struct pernet_operations *ops) From f2ec52d4c3698c995c89c579c34d818eab589d8b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Apr 2012 17:03:42 -0700 Subject: [PATCH 335/438] ALSA: fix core/vmaster.c kernel-doc warning Fix kernel-doc warning in sound/core/vmaster.c: Warning(sound/core/vmaster.c:429): No description found for parameter 'private_data' Signed-off-by: Randy Dunlap Signed-off-by: Takashi Iwai --- sound/core/vmaster.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 14a286a7bf2b..857586135d18 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -419,6 +419,7 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master); * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control * @kcontrol: vmaster kctl element * @hook: the hook function + * @private_data: the private_data pointer to be saved * * Adds the given hook to the vmaster control element so that it's called * at each time when the value is changed. From 99d9acdd0c5ce970eaf8e8671c0bc4cb7c6fb0c1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Apr 2012 20:37:00 +0100 Subject: [PATCH 336/438] drm/i915: Do not set "Enable Panel Fitter" on SNB pageflips Not only do the pageflip work without it at non-native modes (i.e. with the panel fitter enabled), it also causes normal (non-pageflipped) modesets to fail. Reported-by: Adam Jackson Tested-by: Adam Jackson Signed-off-by: Chris Wilson Wanted-by-for-fixes: Dave Airlie Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8be30917bce3..5908cd563400 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7468,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitches[0] | obj->tiling_mode); OUT_RING(obj->gtt_offset); - pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; + /* Contrary to the suggestions in the documentation, + * "Enable Panel Fitter" does not seem to be required when page + * flipping with a non-native mode, and worse causes a normal + * modeset to fail. + * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; + */ + pf = 0; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); ADVANCE_LP_RING(); From 9fd4a50a12d699207c6a65558dfa674a3fd3f150 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 11 Apr 2012 20:24:39 -0300 Subject: [PATCH 337/438] ARM: imx_v4_v5_defconfig: Add support for CONFIG_REGULATOR_FIXED_VOLTAGE Add support for CONFIG_REGULATOR_FIXED_VOLTAGE. Without this option the mx27_3ds cannot have the external Ethernet functional due to the need of smsc regulators. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer --- arch/arm/configs/imx_v4_v5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index b5ac644e12af..6b31cb60daab 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -112,6 +112,7 @@ CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_FB=y From de1de1594faac901670356e09c8c42b73e35ebbf Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 11 Apr 2012 22:12:09 -0300 Subject: [PATCH 338/438] ARM: imx27-dt: Fix build due to removal of irq_domain_add_simple() commit 6b783f7c (irq_domain: Remove irq_domain_add_simple() replaced irq_domain_add_simple with irq_domain_add_legacy() Implement this conversion so that imx27-dt can be built again. Reported-by: Chris Ball Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/imx27-dt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c index 861ceb8232d6..ed38d03c61f2 100644 --- a/arch/arm/mach-imx/imx27-dt.c +++ b/arch/arm/mach-imx/imx27-dt.c @@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { static int __init imx27_avic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_simple(np, 0); + irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL); return 0; } @@ -44,7 +44,9 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np, { static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - irq_domain_add_simple(np, gpio_irq_base); + gpio_irq_base -= 32; + irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, + NULL); return 0; } From 4659b7f1fa3eb33a8f9a9dd209a5823602dc6dcf Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 16 Apr 2012 18:37:48 -0500 Subject: [PATCH 339/438] ARM: imx: Fix imx5 idle logic bug The imx5_idle() check of the tzic_eanble_wake() return value uses incorrect (inverted) logic causing all attempt to idle to fail. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mm-imx5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 05250aed61fb..e10f3914fcfe 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -35,7 +35,7 @@ static void imx5_idle(void) } clk_enable(gpc_dvfs_clk); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (tzic_enable_wake() != 0) + if (!tzic_enable_wake()) cpu_do_idle(); clk_disable(gpc_dvfs_clk); } From 3626479e482aa3247aac03724094ba6c13ea1e46 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Apr 2012 18:32:19 -0300 Subject: [PATCH 340/438] [media] dvb_frontend: Fix a regression when switching back to DVB-S There are some softwares (Kaffeine and likely xine) that uses a DVBv5 call to switch to DVB-S2, but expects that a DVBv3 call to switch back to DVB-S. Well, this is not right, as a DVBv3 call doesn't know anything about delivery systems. However, as, by accident, this used to work, we need to restore its behavior, in order to avoid regressions with those softwares. Reported on this Fedora 16 bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=812895 Reported-by: Dieter Roever Cc: stable@kernel.org # for version 3.3 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 39696c6a4ed7..0f64d7182657 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1446,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } + /* + * Get a delivery system that is compatible with DVBv3 + * NOTE: in order for this to work with softwares like Kaffeine that + * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to + * DVB-S, drivers that support both should put the SYS_DVBS entry + * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. + * The real fix is that userspace applications should not use DVBv3 + * and not trust on calling FE_SET_FRONTEND to switch the delivery + * system. + */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if (fe->ops.delsys[ncaps] == desired_system) { + delsys = desired_system; + break; + } + ncaps++; + } + if (delsys == SYS_UNDEFINED) { + dprintk("%s() Couldn't find a delivery system that matches %d\n", + __func__, desired_system); + } } else { /* * This is a DVBv5 call. So, it likely knows the supported @@ -1494,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } - c->delivery_system = delsys; } + c->delivery_system = delsys; + /* * The DVBv3 or DVBv5 call is requesting a different system. So, * emulation is needed. From e4459e1682c107d7ee1bf102c1ba534230e9b50b Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Thu, 5 Apr 2012 18:53:20 -0300 Subject: [PATCH 341/438] [media] drxk: Does not unlock mutex if sanity check failed in scu_command() If sanity check fails in scu_command(), goto error leads to unlock of an unheld mutex. The check should not fail in reality, but it nevertheless worth fixing. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk_hard.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 36d11756492f..a414b1f2b6a5 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state, dprintk(1, "\n"); if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || - ((resultLen > 0) && (result == NULL))) - goto error; + ((resultLen > 0) && (result == NULL))) { + printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } mutex_lock(&state->mutex); From d9b786955f80fb306471fdb9ea24c6d03af6ca36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= Date: Sun, 8 Apr 2012 06:13:04 -0300 Subject: [PATCH 342/438] [media] rc-core: set mode for winbond-cir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting the correct mode is required by rc-core or scancodes won't be generated (which isn't very user-friendly). This one-line fix should be suitable for 3.4-rc2. Signed-off-by: David Härdeman Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/winbond-cir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index b09c5fae489b..af526586fa26 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_unregister_led; } + data->dev->driver_type = RC_DRIVER_IR_RAW; data->dev->driver_name = WBCIR_NAME; data->dev->input_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; From 9ecf8c0d4f2ea5eb39e0924d9b102b5c3300f291 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 Apr 2012 12:29:32 +0200 Subject: [PATCH 343/438] Revert "ACPI: Make ACPI interrupt threaded" This reverts commit 6fe0d0628245fdcd6fad8b837c81e8f7ebc3364d. Paul bisected this regression. The conversion was done blindly and is wrong, as it does not provide a primary handler to disable the level type irq on the device level. Neither does it set the IRQF_ONESHOT flag which handles that at the irq line level. This can't be done as the interrupt might be shared, though we might extend the core to force it. So an interrupt on this line will wake up the thread, but immediately unmask the irq after that. Due to the interrupt being level type the hardware interrupt is raised over and over and prevents the irq thread from handling it. Fail. request_irq() unfortunately does not refuse such a request and the patch was obviously never tested with real interrupts. Bisected-by: Paul Bolle Signed-off-by: Thomas Gleixner Signed-off-by: Linus Torvalds --- drivers/acpi/osl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index ba14fb93c929..c3881b2eb8b2 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -607,8 +607,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, acpi_irq_handler = handler; acpi_irq_context = context; - if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", - acpi_irq)) { + if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); acpi_irq_handler = NULL; return AE_NOT_ACQUIRED; From 00250ec90963b7ef6678438888f3244985ecde14 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 9 Apr 2012 18:16:34 -0400 Subject: [PATCH 344/438] hwmon: fam15h_power: fix bogus values with current BIOSes Newer BKDG[1] versions recommend a different initialization value for the running average range register in the northbridge. This improves the power reading by avoiding counter saturations resulting in bogus values for anything below about 80% of TDP power consumption. Updated BIOSes will have this new value set up from the beginning, but meanwhile we correct this value ourselves. This needs to be done on all northbridges, even on those where the driver itself does not register at. This fixes the driver on all current machines to provide proper values for idle load. [1] http://support.amd.com/us/Processor_TechDocs/42301_15h_Mod_00h-0Fh_BKDG.pdf Chapter 3.8: D18F5xE0 Processor TDP Running Average (p. 452) Signed-off-by: Andre Przywara Acked-by: Jean Delvare [guenter.roeck@ericsson.com: Removed unnecessary return statement] Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ --- drivers/hwmon/fam15h_power.c | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index b7494af1e4a9..37a8fc92b44a 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } +/* + * Newer BKDG versions have an updated recommendation on how to properly + * initialize the running average range (was: 0xE, now: 0x9). This avoids + * counter saturations resulting in bogus power readings. + * We correct this value ourselves to cope with older BIOSes. + */ +static void __devinit tweak_runavg_range(struct pci_dev *pdev) +{ + u32 val; + const struct pci_device_id affected_device = { + PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }; + + /* + * let this quirk apply only to the current version of the + * northbridge, since future versions may change the behavior + */ + if (!pci_match_id(&affected_device, pdev)) + return; + + pci_bus_read_config_dword(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), + REG_TDP_RUNNING_AVERAGE, &val); + if ((val & 0xf) != 0xe) + return; + + val &= ~0xf; + val |= 0x9; + pci_bus_write_config_dword(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), + REG_TDP_RUNNING_AVERAGE, val); +} + static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; + /* + * though we ignore every other northbridge, we still have to + * do the tweaking on _each_ node in MCM processors as the counters + * are working hand-in-hand + */ + tweak_runavg_range(pdev); + if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; From 1196573fe493aeeb826468157313ee84ffbc59f3 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 9 Apr 2012 13:53:00 -0400 Subject: [PATCH 345/438] hwmon: (ads1015) Fix build warning The following build warning is seen in some configurations. drivers/hwmon/ads1015.c: In function 'show_in': drivers/hwmon/ads1015.c:129: warning: 'in' may be used uninitialized in this function Fix by separating the register read function from the code converting the result into mV. Signed-off-by: Guenter Roeck Cc: Dirk Eibach Reviewed-by: Robert Coulson --- drivers/hwmon/ads1015.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 7765e4f74ec5..1958f03efd7a 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -59,14 +59,11 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_value(struct i2c_client *client, unsigned int channel, - int *value) +static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) { u16 config; - s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; - int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, if (res < 0) goto err_unlock; config = res; - fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* setup and start single conversion */ @@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, } res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); - if (res < 0) - goto err_unlock; - conversion = res; - - mutex_unlock(&data->update_lock); - - *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); - - return 0; err_unlock: mutex_unlock(&data->update_lock); return res; } +static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, + s16 reg) +{ + struct ads1015_data *data = i2c_get_clientdata(client); + unsigned int pga = data->channel_data[channel].pga; + int fullscale = fullscale_table[pga]; + + return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +} + /* sysfs callback function */ static ssize_t show_in(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - int in; int res; + int index = attr->index; - res = ads1015_read_value(client, attr->index, &in); + res = ads1015_read_adc(client, index); + if (res < 0) + return res; - return (res < 0) ? res : sprintf(buf, "%d\n", in); + return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); } static const struct sensor_device_attribute ads1015_in[] = { From 0c8d32c27f5cf6e14ca14b4758d1e994eebd50fd Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 18 Apr 2012 09:29:47 +0800 Subject: [PATCH 346/438] libata: forbid port runtime pm by default, fixing regression Forbid port runtime pm by default because it has known hotplug issue. User can allow it by, for example echo auto > /sys/devices/pci0000:00/0000:00:1f.2/ata2/power/control Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/ata/libata-transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 74aaee30e264..c34190485377 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent, device_enable_async_suspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); + pm_runtime_forbid(dev); transport_add_device(dev); transport_configure_device(dev); From e88aa7bbbe3046a125ea1936b16bb921cc9c6349 Mon Sep 17 00:00:00 2001 From: David Miller Date: Thu, 12 Apr 2012 14:37:30 -0400 Subject: [PATCH 347/438] Fix modpost failures in fedora 17 The symbol table on x86-64 starts to have entries that have names like: _GLOBAL__sub_I_65535_0___mod_x86cpu_device_table They are of type STT_FUNCTION and this one had a length of 18. This matched the device ID validation logic and it barfed because the length did not meet the device type's criteria. -------------------- FATAL: arch/x86/crypto/aesni-intel: sizeof(struct x86cpu_device_id)=16 is not a modulo of the size of section __mod_x86cpu_device_table=18. Fix definition of struct x86cpu_device_id in mod_devicetable.h -------------------- These are some kind of compiler tool internal stuff being emitted and not something we want to inspect in modpost's device ID table validation code. So skip the symbol if it is not of type STT_OBJECT. Signed-off-by: David S. Miller Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/mod/file2alias.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8e730ccc3f2b..44ddaa542db6 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1100,6 +1100,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; + /* We're looking for an object */ + if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) + return; + /* All our symbols are of form __mod_XXX_device_table. */ name = strstr(symname, "__mod_"); if (!name) From a71e23d9925517e609dfcb72b5874f33cdb0d2ad Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 16 Apr 2012 21:55:04 -0400 Subject: [PATCH 348/438] xen/blkback: Fix warning error. drivers/block/xen-blkback/xenbus.c: In function 'xen_blkbk_discard': drivers/block/xen-blkback/xenbus.c:419:4: warning: passing argument 1 of 'dev_warn' makes pointer from integer without a cast +[enabled by default] include/linux/device.h:894:5: note: expected 'const struct device *' but argument is of type 'long int' It is unclear how that mistake made it in. It surely is wrong. Acked-by: Jens Axboe Reported-by: Stephen Rothwell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/xenbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 89860f34a7ec..4f66171c6683 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info "discard-secure", "%d", blkif->vbd.discard_secure); if (err) { - dev_warn(dev-dev, "writing discard-secure (%d)", err); + dev_warn(&dev->dev, "writing discard-secure (%d)", err); return; } } From 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 18 Apr 2012 11:33:00 -0400 Subject: [PATCH 349/438] EHCI: always clear the STS_FLR status bit This patch (as1544) fixes a problem affecting some EHCI controllers. They can generate interrupts whenever the STS_FLR status bit is turned on, even though that bit is masked out in the Interrupt Enable register. Since the driver doesn't use STS_FLR anyway, the patch changes the interrupt routine to clear that bit whenever it is set, rather than leaving it alone. Signed-off-by: Alan Stern Reported-and-tested-by: Tomoya MORINAGA Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 95ca07a8e1b5..4a3bc5b7a06f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } + /* + * We don't use STS_FLR, but some controllers don't like it to + * remain on, so mask it out along with the other status bits. + */ + masked_status = status & (INTR_MASK | STS_FLR); + /* Shared IRQ? */ - masked_status = status & INTR_MASK; if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { spin_unlock(&ehci->lock); return IRQ_NONE; From 0db7bd8ca0033c1530bcefcbd49002364dba908a Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 18 Apr 2012 19:55:44 +0300 Subject: [PATCH 350/438] xz: Enable BCJ filters on SPARC and 32-bit x86 The BCJ filters were meant to be enabled already on these archs, but the xz_wrap.sh script was buggy. Enabling the filters should give smaller kernel images. xz_wrap.sh will now use $SRCARCH instead of $ARCH to detect the architecture. That way it doesn't need to care about the subarchs (like i386 vs. x86_64) since the BCJ filters don't care either. Signed-off-by: Lasse Collin Acked-by: Jan Beulich Acked-by: H. Peter Anvin Signed-off-by: Linus Torvalds --- scripts/xz_wrap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index 17a5798c29da..7a2d372f4885 100644 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -12,8 +12,8 @@ BCJ= LZMA2OPTS= -case $ARCH in - x86|x86_64) BCJ=--x86 ;; +case $SRCARCH in + x86) BCJ=--x86 ;; powerpc) BCJ=--powerpc ;; ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; arm) BCJ=--arm ;; From 9426cd05682745d1024dbabdec5631309bd2f480 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 16 Apr 2012 15:28:28 +0200 Subject: [PATCH 351/438] uwb: fix use of del_timer_sync() in interrupt del_timer_sync() cannot be used in interrupt. Replace it with del_timer() and a flag Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/neh.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index a269937be1b8..8cb71bb333c2 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -107,6 +107,7 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; + u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; + unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - del_timer_sync(&neh->timer); + spin_lock_irqsave(&rc->neh_lock, flags); + /* to guard against a timeout */ + neh->completed = 1; + del_timer(&neh->timer); + spin_unlock_irqrestore(&rc->neh_lock, flags); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); + if (neh->completed) { + spin_unlock_irqrestore(&rc->neh_lock, flags); + return; + } if (neh->context) __uwb_rc_neh_rm(rc, neh); else From 5bd7b419ef2eb4989b207753e088c3437159618a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 18 Apr 2012 10:05:55 +0200 Subject: [PATCH 352/438] uwb: fix error handling Fatal errors such as a device disconnect must not trigger error handling. The error returns must be checked. Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/hwa-rc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 66797e9c5010..810c90ae2c55 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0) { + if (result < 0 && result != -ENODEV && result != -EPERM) { + /* ignoring unrecoverable errors */ dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; From 22b4a4f22da4b39c6f7f679fd35f3d35c91bf851 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Apr 2012 10:14:23 +0000 Subject: [PATCH 353/438] tcp: fix retransmit of partially acked frames Alexander Beregalov reported skb_over_panic errors and provided stack trace. I occurs commit a21d45726aca (tcp: avoid order-1 allocations on wifi and tx path) added a regression, when a retransmit is done after a partial ACK. tcp_retransmit_skb() tries to aggregate several frames if the first one has enough available room to hold the following ones payload. This is controlled by /proc/sys/net/ipv4/tcp_retrans_collapse tunable (default : enabled) Problem is we must make sure _pskb_trim_head() doesnt fool skb_availroom() when pulling some bytes from skb (this pull is done when receiver ACK part of the frame). Reported-by: Alexander Beregalov Cc: Marc MERLIN Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 376b2cfbb685..7ac6423117ad 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1096,6 +1096,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) eat = min_t(int, len, skb_headlen(skb)); if (eat) { __skb_pull(skb, eat); + skb->avail_size -= eat; len -= eat; if (!len) return; From f941f6922533316556d4dc6eee9c19d4a832c560 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 10 Apr 2012 10:48:11 +0200 Subject: [PATCH 354/438] USB: ehci-fsl: Fix kernel crash on mpc5121e Since commit 28c56ea1431421dec51b7b229369e991481453df (powerpc/usb: fix bug of kernel hang when initializing usb) the kernel crashes on mpc5121e. mpc5121e doesn't have system interface registers, accessing this register address space cause the machine check exception and a kernel crash: ... [ 1.294596] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 1.316491] fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller [ 1.337334] fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1 [ 1.358548] Machine check in kernel mode. [ 1.375917] Caused by (from SRR1=49030): Transfer error ack signal [ 1.395505] Oops: Machine check, sig: 7 [#1] [ 1.413113] MPC5121 ADS [ 1.428718] Modules linked in: [ 1.444841] NIP: c026efc4 LR: c0278b50 CTR: 00000000 [ 1.463342] REGS: df837ba0 TRAP: 0200 Not tainted (3.3.0-08839-gb5174fa) [ 1.484083] MSR: 00049030 CR: 42042022 XER: 20000000 [ 1.504099] TASK = df834000[1] 'swapper' THREAD: df836000 [ 1.509667] GPR00: 1c000000 df837c50 df834000 df9d74e0 00000003 00000010 00000000 00000000 [ 1.531650] GPR08: 00000020 00000000 c037cdd8 e1088000 22042028 1001a69c 00000000 00000000 [ 1.553762] GPR16: 1ffbce70 00000000 1fef5b28 1fef3e08 00000000 00000000 1ffcbc7c c045b264 [ 1.575824] GPR24: 0000008b 00000002 c04a7dd0 e1088000 df33c960 df9d74e0 00000000 df9d7400 [ 1.612295] NIP [c026efc4] ehci_fsl_setup_phy+0x110/0x124 [ 1.632454] LR [c0278b50] ehci_fsl_setup+0x29c/0x304 [ 1.652065] Call Trace: [ 1.668923] [df837c50] [c0278a40] ehci_fsl_setup+0x18c/0x304 (unreliable) [ 1.690332] [df837c70] [c025cba4] usb_add_hcd+0x1f0/0x66c [ 1.710377] [df837cb0] [c0277ab8] ehci_fsl_drv_probe+0x180/0x308 [ 1.731322] [df837ce0] [c01fc7a8] platform_drv_probe+0x20/0x30 [ 1.752202] [df837cf0] [c01fb0ac] driver_probe_device+0x8c/0x214 [ 1.773491] [df837d10] [c01f956c] bus_for_each_drv+0x6c/0xa8 [ 1.794279] [df837d40] [c01fafdc] device_attach+0xb4/0xd8 [ 1.814574] [df837d60] [c01fa44c] bus_probe_device+0xa4/0xb4 [ 1.835343] [df837d80] [c01f87a8] device_add+0x52c/0x5dc [ 1.855462] [df837dd0] [c01fcd58] platform_device_add+0x124/0x1d0 [ 1.876558] [df837df0] [c036dcec] fsl_usb2_device_register+0xa0/0xd4 [ 1.897512] [df837e10] [c036df28] fsl_usb2_mph_dr_of_probe+0x208/0x264 [ 1.918253] [df837e90] [c01fc7a8] platform_drv_probe+0x20/0x30 [ 1.938300] [df837ea0] [c01fb0ac] driver_probe_device+0x8c/0x214 [ 1.958511] [df837ec0] [c01fb2f0] __driver_attach+0xbc/0xc0 [ 1.978088] [df837ee0] [c01f9608] bus_for_each_dev+0x60/0x9c [ 1.997589] [df837f10] [c01fab88] driver_attach+0x24/0x34 [ 2.016757] [df837f20] [c01fa744] bus_add_driver+0x1ac/0x274 [ 2.036339] [df837f50] [c01fb898] driver_register+0x88/0x150 [ 2.056052] [df837f70] [c01fcabc] platform_driver_register+0x68/0x78 [ 2.076650] [df837f80] [c0446500] fsl_usb2_mph_dr_driver_init+0x18/0x28 [ 2.097734] [df837f90] [c0003988] do_one_initcall+0x148/0x1b0 [ 2.117934] [df837fc0] [c042d89c] kernel_init+0xfc/0x190 [ 2.137667] [df837ff0] [c000d2c4] kernel_thread+0x4c/0x68 [ 2.157240] Instruction dump: [ 2.174119] 90050004 4e800020 2f840003 419e0014 2f840004 409eff64 6400c000 4bffff5c [ 2.196000] 64001000 7c0004ac 812b0500 0c090000 <4c00012c> 61290200 7c0004ac 912b0500 [ 2.218100] ---[ end trace 21659aedb84ad816 ]--- [ 2.237089] [ 3.232940] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007 [ 3.232954] [ 3.271575] Rebooting in 1 seconds.. Check pdata->have_sysif_regs flag before accessing system interface registers. Signed-off-by: Anatolij Gustschin Cc: Shengzhou Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e03..d0a84bd3f3eb 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, u32 portsc; struct usb_hcd *hcd = ehci_to_hcd(ehci); void __iomem *non_ehci = hcd->regs; + struct fsl_usb2_platform_data *pdata; + + pdata = hcd->self.controller->platform_data; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, /* fall through */ case FSL_USB2_PHY_UTMI: /* enable UTMI PHY */ - setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); + if (pdata->have_sysif_regs) + setbits32(non_ehci + FSL_SOC_USB_CTRL, + CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: From f4a728d09a96d6a83d9c3f39035b1aa7726892ea Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 25 Mar 2012 21:08:32 +0200 Subject: [PATCH 355/438] drivers/usb/misc/usbtest.c: add kfrees Free the two previously allocated buffers before exiting the function in an error case. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index cac67dea2bac..9dcb68f04f03 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2277,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) if (status < 0) { WARNING(dev, "couldn't get endpoints, %d\n", status); + kfree(dev->buf); + kfree(dev); return status; } /* may find bulk or ISO pipes */ From 523fc5c14f6cad283e5a266eba0e343aed6e73d5 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Fri, 30 Mar 2012 08:51:28 +0900 Subject: [PATCH 356/438] USB: yurex: Remove allocation of coherent buffer for setup-packet buffer Removes allocation of coherent buffer for the control-request setup-packet buffer from the yurex driver. Using coherent buffers for setup-packet is obsolete and does not work with some USB host implementations. Signed-off-by: Tomoki Sekiyama Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 897edda42270..a4a76fcd41cd 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - if (dev->cntl_req) - usb_free_coherent(dev->udev, YUREX_BUF_SIZE, - dev->cntl_req, dev->cntl_urb->setup_dma); + kfree(dev->cntl_req); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, - GFP_KERNEL, - &dev->cntl_urb->setup_dma); + dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; From 532f17b5d59bf0deb6f1ff9bc1fb27d5b5011c09 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Fri, 30 Mar 2012 08:51:36 +0900 Subject: [PATCH 357/438] USB: yurex: Fix missing URB_NO_TRANSFER_DMA_MAP flag in urb Current probing code is setting URB_NO_TRANSFER_DMA_MAP flag into a wrong urb structure, and this causes BUG_ON with some USB host implementations. This patch fixes the issue. Signed-off-by: Tomoki Sekiyama Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index a4a76fcd41cd..70201462e19c 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -282,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); From 8034761c219ce545a9f4d3b23cfda47a0027cc8c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 18 Apr 2012 14:43:40 -0600 Subject: [PATCH 358/438] USB: ehci-tegra: don't call set_irq_flags(IRQF_VALID) This call is not needed; the IRQ controller should (and does) set up interrupts correctly. set_irq_flags() isn't exported to modules, to this also fixes compilation of ehci-tegra.c as a module. Signed-off-by: Stephen Warren Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 73544bd440bd..86183366647f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -731,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) err = -ENODEV; goto fail; } - set_irq_flags(irq, IRQF_VALID); #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { From 7a6fbc9a887193a1e9f8658703881c528040afbc Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 27 Mar 2012 12:22:49 +0400 Subject: [PATCH 359/438] ARM: clps711x: serial driver hungs are a result of call disable_irq within ISR Since 2.6.30-rc1 clps711x serial driver hungs system. This is a result of call disable_irq from ISR. synchronize_irq waits for end of interrupt and goes to infinite loop. This patch fix this problem. Signed-off-by: Alexander Shiyan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e6c3dbd781d6..836fe2731234 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - clps711xuart_stop_tx(port); - return IRQ_HANDLED; - } + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) + goto disable_tx_irq; count = port->fifosize >> 1; do { @@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) - clps711xuart_stop_tx(port); + if (uart_circ_empty(xmit)) { + disable_tx_irq: + disable_irq_nosync(TX_IRQ(port)); + tx_enabled(port) = 0; + } return IRQ_HANDLED; } From af6d17cdc8c89aeb3101f0d27cd32fc0592b40b2 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Apr 2012 10:47:50 +0900 Subject: [PATCH 360/438] pch_uart: Fix dma channel unallocated issue This driver anticipates pch_uart_verify_port() is not called during installation. However, actually pch_uart_verify_port() is called during installation. As a result, memory access violation occurs like below. 0. initial value: use_dma=0 1. starup() - dma channel is not allocated because use_dma=0 2. pch_uart_verify_port() - Set use_dma=1 3. UART processing acts DMA mode because use_dma=1 - memory access violation occurs! This patch fixes the issue. Solution: Whenever pch_uart_verify_port() is called and then dma channel is not allocated, the channel should be allocated. Signed-off-by: Tomoya MORINAGA Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index bbbec4a74cfb..c2816f494807 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1447,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif - priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); + if (!priv->use_dma) + pch_request_dma(port); + priv->use_dma = 1; } return 0; From 2225fd56049643c1a7d645c0ce9d499d43c7974e Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 18 Apr 2012 15:03:04 +0300 Subject: [PATCH 361/438] KVM: VMX: Fix kvm_set_shared_msr() called in preemptible context kvm_set_shared_msr() may not be called in preemptible context, but vmx_set_msr() does so: BUG: using smp_processor_id() in preemptible [00000000] code: qemu-kvm/22713 caller is kvm_set_shared_msr+0x32/0xa0 [kvm] Pid: 22713, comm: qemu-kvm Not tainted 3.4.0-rc3+ #39 Call Trace: [] debug_smp_processor_id+0xe2/0x100 [] kvm_set_shared_msr+0x32/0xa0 [kvm] [] vmx_set_msr+0x28b/0x2d0 [kvm_intel] ... Making kvm_set_shared_msr() work in preemptible is cleaner, but it's used in the fast path. Making two variants is overkill, so this patch just disables preemption around the call. Reported-by: Dave Jones Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad85adfef843..4ff0ab9bc3c8 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2210,9 +2210,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) msr = find_msr_entry(vmx, msr_index); if (msr) { msr->data = data; - if (msr - vmx->guest_msrs < vmx->save_nmsrs) + if (msr - vmx->guest_msrs < vmx->save_nmsrs) { + preempt_disable(); kvm_set_shared_msr(msr->index, msr->data, msr->mask); + preempt_enable(); + } break; } ret = kvm_set_msr_common(vcpu, msr_index, data); From 51b79bee627d526199b2f6a6bef8ee0c0739b6d1 Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Wed, 18 Apr 2012 17:23:04 -0400 Subject: [PATCH 362/438] security: fix compile error in commoncap.c Add missing "personality.h" security/commoncap.c: In function 'cap_bprm_set_creds': security/commoncap.c:510: error: 'PER_CLEAR_ON_SETID' undeclared (first use in this function) security/commoncap.c:510: error: (Each undeclared identifier is reported only once security/commoncap.c:510: error: for each function it appears in.) Signed-off-by: Jonghwan Choi Acked-by: Serge Hallyn Signed-off-by: James Morris --- security/commoncap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/commoncap.c b/security/commoncap.c index 0ecf4ba321cb..71a166a05975 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * If a non-root user executes a setuid-root binary in From 21a1416a1c945c5aeaeaf791b63c64926018eb77 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 17 Apr 2012 21:46:44 -0600 Subject: [PATCH 363/438] KVM: lock slots_lock around device assignment As pointed out by Jason Baron, when assigning a device to a guest we first set the iommu domain pointer, which enables mapping and unmapping of memory slots to the iommu. This leaves a window where this path is enabled, but we haven't synchronized the iommu mappings to the existing memory slots. Thus a slot being removed at that point could send us down unexpected code paths removing non-existent pinnings and iommu mappings. Take the slots_lock around creating the iommu domain and initial mappings as well as around iommu teardown to avoid this race. Signed-off-by: Alex Williamson Signed-off-by: Marcelo Tosatti --- virt/kvm/iommu.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index fec1723de9b4..e9fff9830bf0 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm) return -ENODEV; } + mutex_lock(&kvm->slots_lock); + kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type); - if (!kvm->arch.iommu_domain) - return -ENOMEM; + if (!kvm->arch.iommu_domain) { + r = -ENOMEM; + goto out_unlock; + } if (!allow_unsafe_assigned_interrupts && !iommu_domain_has_cap(kvm->arch.iommu_domain, @@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm) " module option.\n", __func__); iommu_domain_free(kvm->arch.iommu_domain); kvm->arch.iommu_domain = NULL; - return -EPERM; + r = -EPERM; + goto out_unlock; } r = kvm_iommu_map_memslots(kvm); if (r) - goto out_unmap; + kvm_iommu_unmap_memslots(kvm); - return 0; - -out_unmap: - kvm_iommu_unmap_memslots(kvm); +out_unlock: + mutex_unlock(&kvm->slots_lock); return r; } @@ -340,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm) if (!domain) return 0; + mutex_lock(&kvm->slots_lock); kvm_iommu_unmap_memslots(kvm); + kvm->arch.iommu_domain = NULL; + mutex_unlock(&kvm->slots_lock); + iommu_domain_free(domain); return 0; } From 888073d41680e8244232f3d850e0424a4e9de60f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 16 Apr 2012 15:38:28 -0400 Subject: [PATCH 364/438] ARM: bcmring: fix UART declarations This error appeared in the bcmring_defconfig build: CC arch/arm/mach-bcmring/core.o arch/arm/mach-bcmring/core.c:55: error: macro "AMBA_APB_DEVICE" requires 6 arguments, but only 5 given arch/arm/mach-bcmring/core.c:55: warning: type defaults to 'int' in declaration of 'AMBA_APB_DEVICE' arch/arm/mach-bcmring/core.c:56: error: macro "AMBA_APB_DEVICE" requires 6 arguments, but only 5 given arch/arm/mach-bcmring/core.c:56: warning: type defaults to 'int' in declaration of 'AMBA_APB_DEVICE' arch/arm/mach-bcmring/core.c:134: error: 'uartA_device' undeclared here (not in a function) arch/arm/mach-bcmring/core.c:135: error: 'uartB_device' undeclared here (not in a function) make[2]: *** [arch/arm/mach-bcmring/core.o] Error 1 It appeared as of commit 8ede1ae65e61282cddba39bde4142be3885a6f5a "ARM: amba: bcmring: use common amba device initializers" Note that in include/linux/amba/bus.h we have: #define AMBA_APB_DEVICE(name, busid, id, base, irqs, data) ... There is an a --> A case error in the busid and a missing zero placeholder for the id field. Cc: Russell King Signed-off-by: Paul Gortmaker [olof: reworded patch subject] Signed-off-by: Olof Johansson --- arch/arm/mach-bcmring/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index 22e4e0a28ad1..adbfb1994582 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c @@ -52,8 +52,8 @@ #include #include -static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); -static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); +static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL); +static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL); static struct clk pll1_clk = { .name = "PLL1", From 118cb4a408e1c4021ac85d6c05da66bb6f57e556 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 19 Apr 2012 07:33:27 +0200 Subject: [PATCH 365/438] ALSA: hda/realtek - Fix regression on Quanta/Gericom KN1 Through the transition to the auto-parser, the support for Quanta/Gericom KN1 got broken. There are two problems behind it: - This machine doesn't like the default COEF setup for ALC260 we take now as default - BIOS doesn't set the pins correctly at all; especially the machine uses only the pin 0x0f for both headphone and speaker This patch adds the fixup as a workaround for these issues. Reported-and-tested-by: Uros Vampl Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 49 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2508f8109f11..e65e35433055 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1445,6 +1445,13 @@ enum { ALC_FIXUP_ACT_BUILD, }; +static void alc_apply_pincfgs(struct hda_codec *codec, + const struct alc_pincfg *cfg) +{ + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); +} + static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; @@ -1478,9 +1485,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) snd_printdd(KERN_INFO "hda_codec: %s: " "Apply pincfg for %s\n", codec->chip_name, modelname); - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, - cfg->val); + alc_apply_pincfgs(codec, cfg); break; case ALC_FIXUP_VERBS: if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) @@ -4861,6 +4866,7 @@ enum { ALC260_FIXUP_GPIO1_TOGGLE, ALC260_FIXUP_REPLACER, ALC260_FIXUP_HP_B1900, + ALC260_FIXUP_KN1, }; static void alc260_gpio1_automute(struct hda_codec *codec) @@ -4888,6 +4894,36 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, } } +static void alc260_fixup_kn1(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static const struct alc_pincfg pincfgs[] = { + { 0x0f, 0x02214000 }, /* HP/speaker */ + { 0x12, 0x90a60160 }, /* int mic */ + { 0x13, 0x02a19000 }, /* ext mic */ + { 0x18, 0x01446000 }, /* SPDIF out */ + /* disable bogus I/O pins */ + { 0x10, 0x411111f0 }, + { 0x11, 0x411111f0 }, + { 0x14, 0x411111f0 }, + { 0x15, 0x411111f0 }, + { 0x16, 0x411111f0 }, + { 0x17, 0x411111f0 }, + { 0x19, 0x411111f0 }, + { } + }; + + switch (action) { + case ALC_FIXUP_ACT_PRE_PROBE: + alc_apply_pincfgs(codec, pincfgs); + break; + case ALC_FIXUP_ACT_PROBE: + spec->init_amp = ALC_INIT_NONE; + break; + } +} + static const struct alc_fixup alc260_fixups[] = { [ALC260_FIXUP_HP_DC5750] = { .type = ALC_FIXUP_PINS, @@ -4938,7 +4974,11 @@ static const struct alc_fixup alc260_fixups[] = { .v.func = alc260_fixup_gpio1_toggle, .chained = true, .chain_id = ALC260_FIXUP_COEF, - } + }, + [ALC260_FIXUP_KN1] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc260_fixup_kn1, + }, }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -4948,6 +4988,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), + SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), {} From 9b7f43afd417a6feb80841d30ced4051c362eb5d Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 18 Apr 2012 23:34:46 -0700 Subject: [PATCH 366/438] memcg: fix Bad page state after replace_page_cache My 9ce70c0240d0 "memcg: fix deadlock by inverting lrucare nesting" put a nasty little bug into v3.3's version of mem_cgroup_replace_page_cache(), sometimes used for FUSE. Replacing __mem_cgroup_commit_charge_lrucare() by __mem_cgroup_commit_charge(), I used the "pc" pointer set up earlier: but it's for oldpage, and needs now to be for newpage. Once oldpage was freed, its PageCgroupUsed bit (cleared above but set again here) caused "Bad page state" messages - and perhaps worse, being missed from newpage. (I didn't find this by using FUSE, but in reusing the function for tmpfs.) Signed-off-by: Hugh Dickins Cc: stable@vger.kernel.org [v3.3 only] Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index a7165a60d0a7..b868def9bcc1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3392,6 +3392,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage, * the newpage may be on LRU(or pagevec for LRU) already. We lock * LRU while we overwrite pc->mem_cgroup. */ + pc = lookup_page_cgroup(newpage); __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); } From b10c6d4b50cbbdccce2187c1ccc516a9c7335835 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 19 Apr 2012 09:33:32 +0100 Subject: [PATCH 367/438] drm/usb: fix module license on drm/usb layer. Allows this module to load correctly with certain debugging options on. Reported on irc by scientes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index c8c83dad2ce1..37c9a523dd1c 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -1,6 +1,6 @@ #include "drmP.h" #include -#include +#include int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, @@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver, usb_deregister(udriver); } EXPORT_SYMBOL(drm_usb_exit); + +MODULE_AUTHOR("David Airlie"); +MODULE_DESCRIPTION("USB DRM support"); +MODULE_LICENSE("GPL and additional rights"); From 3e843196c697ee2c319d96e861980fb4c3e04e24 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 19 Apr 2012 12:04:03 +0200 Subject: [PATCH 368/438] ALSA: hda/sigmatel - Fix inverted mute LED While refactoring the mute-LED handling for HP laptops, I messed up the polarity check in a wrong way. The red (or the mute-LED if any) should appear in the muted state, corresponding to GPIO on. Reported-by: Mikko Vinni Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 33a9946b492c..4742cac26aa9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5063,12 +5063,11 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) if (spec->gpio_led_polarity) muted = !muted; - /*polarity defines *not* muted state level*/ if (!spec->vref_mute_led_nid) { if (muted) - spec->gpio_data &= ~spec->gpio_led; /* orange */ + spec->gpio_data |= spec->gpio_led; else - spec->gpio_data |= spec->gpio_led; /* white */ + spec->gpio_data &= ~spec->gpio_led; stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } else { From 590b4775d6b628c7ad215fd0335a0a787032e2dd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 19 Apr 2012 00:00:27 -0700 Subject: [PATCH 369/438] ALSA: workaround: change the timing of alsa_sound_last_init() Current alsa_sound_last_init() was called as __initcall(). So, on current ALSA, only devices that had been properly registered at this point were shown. So, it will show "No soundcards found" if driver requests probe deferment. it's often misleading. This patch delays the timing of alsa_sound_last_init() as workaround. Signed-off-by: Kuninori Morimoto Reviwed-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/last.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/last.c b/sound/last.c index bdd0857b8871..7ffc182e0844 100644 --- a/sound/last.c +++ b/sound/last.c @@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void) return 0; } -__initcall(alsa_sound_last_init); +late_initcall_sync(alsa_sound_last_init); From cd90491bcd63af3f1505de76aa82d5884f1d16e7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 8 Apr 2012 16:31:24 -0300 Subject: [PATCH 370/438] [media] V4L: mt9m032: fix two dead-locks Fix a copy-paste typo and a nested locking function call in mt9m032. Signed-off-by: Guennadi Liakhovetski Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m032.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c index 7636672c3548..645973c5feb0 100644 --- a/drivers/media/video/mt9m032.c +++ b/drivers/media/video/mt9m032.c @@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, } /* Scaling is not supported, the format is thus fixed. */ - ret = mt9m032_get_pad_format(subdev, fh, fmt); + fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); + ret = 0; done: - mutex_lock(&sensor->lock); + mutex_unlock(&sensor->lock); return ret; } From 3bc86c624fe48864cd6e3738d5ff35d1fe31fa6c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 9 Apr 2012 09:31:56 -0300 Subject: [PATCH 371/438] [media] V4L: DocBook: Fix typos in the multi-plane formats description Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/pixfmt-nv12m.xml | 2 +- Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index 3fd3ce5df270..5274c24d11e0 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_NV12M ('NV12M') + V4L2_PIX_FMT_NV12M ('NM12') &manvol; diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index 9957863daf18..60308f1eefdf 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_YUV420M ('YU12M') + V4L2_PIX_FMT_YUV420M ('YM12') &manvol; From 2198edddd8f0245d4c47419310c6cfb0f4e1a197 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 18 Apr 2012 10:05:17 -0400 Subject: [PATCH 372/438] HID: default HID_BATTERY_STRENGTH to no Commit 4f5ca836b "HID: hid-input: add support for HID devices reporting Battery Strength" added the CONFIG_HID_BATTERY_STRENGTH option to report the battery strength of HID devices. The commit log explicitly mentions it not working properly with recent userspace, but it is default y anyway. This is rather odd, and actually causes problems on real systems. This works around Fedora bug https://bugzilla.redhat.com/show_bug.cgi?id=806295 Signed-off-by: Josh Boyer Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a3d033252995..ffddcba32af6 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID config HID_BATTERY_STRENGTH bool depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY - default y + default n config HIDRAW bool "/dev/hidraw raw HID device support" From e36325071832f1ba96ac54fb8ba1459f08b05dd8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 18 Apr 2012 15:21:07 +0200 Subject: [PATCH 373/438] drm/radeon/kms: fix the regression of DVI connector check The check of the encoder type in the commit [e00e8b5e: drm/radeon/kms: fix analog load detection on DVI-I connectors] is obviously wrong, and it's the culprit of the regression on my workstation with DVI-analog connection resulting in the blank output. Fixed the typo now. Signed-off-by: Takashi Iwai Reviewed-by: Alex Deucher Cc: Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index bd05156edbdb..aa8268dd3cd3 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || + if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) continue; From ca3649de026ff95c6f2847e8d096cf2f411c02b3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 19 Apr 2012 15:15:25 +0200 Subject: [PATCH 374/438] ALSA: hda/conexant - Don't set HP pin-control bit unconditionally Some output pins on Conexant chips have no HP control bit, but the auto-parser initializes these pins unconditionally with PIN_HP. Check the pin-capability and avoid the HP bit if not supported. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index d29d6d377904..f52c9ef3cc8c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3951,9 +3951,14 @@ static void cx_auto_init_output(struct hda_codec *codec) int i; mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); - for (i = 0; i < cfg->hp_outs; i++) + for (i = 0; i < cfg->hp_outs; i++) { + unsigned int val = PIN_OUT; + if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & + AC_PINCAP_HP_DRV) + val |= AC_PINCTL_HP_EN; snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + AC_VERB_SET_PIN_WIDGET_CONTROL, val); + } mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); From aef6a7eeac6fd867eda415f65a7f0247fb82baf4 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Wed, 18 Apr 2012 13:47:02 +0900 Subject: [PATCH 375/438] drm: fix page_flip error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Free event and restore event_space only when page_flip->flags has DRM_MODE_PAGE_FLIP_EVENT if page_flip() is failed. Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d3aaeb6ae236..c79870a75c2f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ret = crtc->funcs->page_flip(crtc, fb, e); if (ret) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); + if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); + } } out: From dfc6ae5bd70d3a22a0e977943c31f6d55fc32820 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 17 Apr 2012 16:51:38 -0400 Subject: [PATCH 376/438] radeon: fix r600/agp when vram is after AGP (v3) If AGP is placed in the middle, the size_af is off-by-one, it results in VRAM being placed at 0x7fffffff instead of 0x8000000. v2: fix the vram_start setup. v3: also fix r7xx & newer ASIC Reported-by: russiane39 on #radeon Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 4 ++-- drivers/gpu/drm/radeon/rv770.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index de71243b591f..c8187c4b6ae8 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end + 1; + size_af = 0xFFFFFFFF - mc->gtt_end; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end; + mc->vram_start = mc->gtt_end + 1; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c62ae4be3845..cdab1aeaed6e 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end + 1; + size_af = 0xFFFFFFFF - mc->gtt_end; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end; + mc->vram_start = mc->gtt_end + 1; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", From 5edaad87000a143504a8f8e2864bb415a9287d94 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:02 -0300 Subject: [PATCH 377/438] drivers: gpu: drm: gma500: mdfld_dsi_output.h: Remove not unneeded include of version.h The output of "make versioncheck" points a incorrect include of version.h in the drivers/gpu/drm/gma500/mdfld_dsi_output.h: drivers/gpu/drm/gma500/mdfld_dsi_output.h: 32 linux/version.h not needed. If we take a look in the file, we can agree to remove it. Cc: David Airlie Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/mdfld_dsi_output.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 21071cef92a4..36eb0744841c 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,7 +29,6 @@ #define __MDFLD_DSI_OUTPUT_H__ #include -#include #include #include #include From 5799d9e2eab20ef694fb92a7636f451e1b0e456c Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Tue, 17 Apr 2012 21:27:54 +0200 Subject: [PATCH 378/438] drm/nouveau/pm: don't read/write beyond end of stack buffer NUL-terminate after strncpy. If the parameter "profile" has length 16 or more, then strncpy leaves "string" with no NUL terminator, so the following search for '\n' may read beyond the end of that 16-byte buffer. If it finds a newline there, then it will also write beyond the end of that stack buffer. Signed-off-by: Jim Meyering Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_pm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 34d591b7d4ef..da3e7c3abab7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) return -EPERM; strncpy(string, profile, sizeof(string)); + string[sizeof(string) - 1] = 0; if ((ptr = strchr(string, '\n'))) *ptr = '\0'; From 4e47e02d1ac47b6eb591b2a632a6c059ce3e5002 Mon Sep 17 00:00:00 2001 From: Prathyush Date: Sat, 14 Apr 2012 17:22:13 +0530 Subject: [PATCH 379/438] drm: Releasing FBs before releasing GEM objects during drm_release During DRM release, all the FBs and gem objects are released. If a gem object is being used as a FB and set to a crtc, it must not be freed before releasing the framebuffer first. If FBs are released first, the crtc using the FB is disabled first so now the GEM object can be freed safely. The CRTC will be enabled again when the driver restores fbdev mode. Signed-off-by: Prathyush K Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index cdfbf27b2b3c..123de28f94ef 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp) drm_events_release(file_priv); - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_release(dev, file_priv); - if (dev->driver->driver_features & DRIVER_MODESET) drm_fb_release(file_priv); + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_release(dev, file_priv); + mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; From a09d431f344d854e4fe9cfac44f78cb8202f3eb7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 19 Apr 2012 15:42:58 +0100 Subject: [PATCH 380/438] drm/radeon: fix load detect on rn50 with hardcoded EDIDs. When the force changes went in back in 3.3.0, we ended up returning disconnected in the !force case, and the connected in when forced, as it hit the hardcoded check. Fix it so all exits go via the hardcoded check and stop spurious modesets on platforms with hardcoded EDIDs. Reported-by: Evan McNabb (Red Hat) Reviewed-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index aa8268dd3cd3..3c2e7a000a2a 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) * cases the DVI port is actually a virtual KVM port connected to the service * processor. */ +out: if ((!rdev->is_atom_bios) && (ret == connector_status_disconnected) && rdev->mode_info.bios_hardcoded_edid_size) { @@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_connected; } -out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); return ret; From d70f363222ef373c2037412f09a600357cfa1c7a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 19 Apr 2012 15:18:08 +0200 Subject: [PATCH 381/438] ALSA: hda/conexant - Set up the missing docking-station pins ThinkPad 410,420,510,520 and X201 with cx50585 & co chips have the docking-station ports, but BIOS doesn't initialize for these pins. Thus, like the former X200, we need to set up the pins manually in the driver. The odd part is that the same PCI SSID is used for X200 and T400, thus we need to prepare individual fixup tables for cx5051 and others. Bugzilla entries: https://bugzilla.redhat.com/show_bug.cgi?id=808559 https://bugzilla.redhat.com/show_bug.cgi?id=806217 https://bugzilla.redhat.com/show_bug.cgi?id=810697 Reported-by: Josh Boyer Reported-by: Jens Taprogge Tested-by: Jens Taprogge Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f52c9ef3cc8c..58b5de4a6eed 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -4367,8 +4367,10 @@ static void apply_pin_fixup(struct hda_codec *codec, enum { CXT_PINCFG_LENOVO_X200, + CXT_PINCFG_LENOVO_TP410, }; +/* ThinkPad X200 & co with cxt5051 */ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ { 0x17, 0x21a11000 }, /* dock-mic */ @@ -4376,15 +4378,33 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { {} }; -static const struct cxt_pincfg *cxt_pincfg_tbl[] = { - [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, +/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */ +static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = { + { 0x19, 0x042110ff }, /* HP (seq# overridden) */ + { 0x1a, 0x21a190f0 }, /* dock-mic */ + { 0x1c, 0x212140ff }, /* dock-HP */ + {} }; -static const struct snd_pci_quirk cxt_fixups[] = { +static const struct cxt_pincfg *cxt_pincfg_tbl[] = { + [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, + [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410, +}; + +static const struct snd_pci_quirk cxt5051_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), {} }; +static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), + {} +}; + /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches * can be created (bko#42825) */ @@ -4421,11 +4441,13 @@ static int patch_conexant_auto(struct hda_codec *codec) break; case 0x14f15051: add_cx5051_fake_mutes(codec); + apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl); + break; + default: + apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl); break; } - apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); - err = cx_auto_search_adcs(codec); if (err < 0) return err; From 273a50fbcd2d2c0652bbda58dd1985f932ce6d75 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Fri, 13 Apr 2012 00:37:00 +0200 Subject: [PATCH 382/438] nouveau: Set special lane map for the right chipset The refactoring of the nv50 logic, introduced in 8663bc7c, modified the test for the special lane map used on some Apple computers with Nvidia chipsets. The tested MBA3,1 would still boot, but resume from suspend stopped working. This patch restores the old test, which fixes the problem. Signed-off-by: Henrik Rydberg Acked-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nv50_sor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index a7844ab6a50c..274640212475 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) struct drm_nouveau_private *dev_priv = dev->dev_private; static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ static const u8 nv50[] = { 16, 8, 0, 24 }; - if (dev_priv->card_type == 0xaf) + if (dev_priv->chipset == 0xaf) return nvaf[lane]; return nv50[lane]; } From 3066616ce23aad5719c23a0f21f32676402cb44b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 17 Apr 2012 22:21:38 -0400 Subject: [PATCH 383/438] xen/xenbus: Add quirk to deal with misconfigured backends. A rather annoying and common case is when booting a PVonHVM guest and exposing the PV KBD and PV VFB - as broken toolstacks don't always initialize the backends correctly. Normally The HVM guest is using the VGA driver and the emulated keyboard for this (though upstream version of QEMU implements PV KBD, but still uses a VGA driver). We provide a very basic two-stage wait mechanism - where we wait for 30 seconds for all devices, and then for 270 for all them except the two mentioned. That allows us to wait for the essential devices, like network or disk for the full 6 minutes. To trigger this, put this in your guest config: vfb = [ 'vnc=1, vnclisten=0.0.0.0 ,vncunused=1'] instead of this: vnc=1 vnclisten="0.0.0.0" CC: stable@kernel.org Acked-by: Stefano Stabellini [v3: Split delay in non-essential (30 seconds) and essential devices per Ian and Stefano suggestion] [v4: Added comments per Stefano suggestion] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xenbus/xenbus_probe_frontend.c | 67 +++++++++++++++++----- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index f20c5f178b40..a31b54d48839 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev) return xenbus_read_otherend_details(xendev, "backend-id", "backend"); } -static int is_device_connecting(struct device *dev, void *data) +static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential) { struct xenbus_device *xendev = to_xenbus_device(dev); struct device_driver *drv = data; @@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data) if (drv && (dev->driver != drv)) return 0; + if (ignore_nonessential) { + /* With older QEMU, for PVonHVM guests the guest config files + * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] + * which is nonsensical as there is no PV FB (there can be + * a PVKB) running as HVM guest. */ + + if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) + return 0; + + if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) + return 0; + } xendrv = to_xenbus_driver(dev->driver); return (xendev->state < XenbusStateConnected || (xendev->state == XenbusStateConnected && xendrv->is_ready && !xendrv->is_ready(xendev))); } +static int essential_device_connecting(struct device *dev, void *data) +{ + return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); +} +static int non_essential_device_connecting(struct device *dev, void *data) +{ + return is_device_connecting(dev, data, false); +} -static int exists_connecting_device(struct device_driver *drv) +static int exists_essential_connecting_device(struct device_driver *drv) { return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - is_device_connecting); + essential_device_connecting); +} +static int exists_non_essential_connecting_device(struct device_driver *drv) +{ + return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, + non_essential_device_connecting); } static int print_device_status(struct device *dev, void *data) @@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data) /* We only wait for device setup after most initcalls have run. */ static int ready_to_wait_for_devices; +static bool wait_loop(unsigned long start, unsigned int max_delay, + unsigned int *seconds_waited) +{ + if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { + if (!*seconds_waited) + printk(KERN_WARNING "XENBUS: Waiting for " + "devices to initialise: "); + *seconds_waited += 5; + printk("%us...", max_delay - *seconds_waited); + if (*seconds_waited == max_delay) + return true; + } + + schedule_timeout_interruptible(HZ/10); + + return false; +} /* * On a 5-minute timeout, wait for all devices currently configured. We need * to do this to guarantee that the filesystems and / or network devices @@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv) if (!ready_to_wait_for_devices || !xen_domain()) return; - while (exists_connecting_device(drv)) { - if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { - if (!seconds_waited) - printk(KERN_WARNING "XENBUS: Waiting for " - "devices to initialise: "); - seconds_waited += 5; - printk("%us...", 300 - seconds_waited); - if (seconds_waited == 300) - break; - } + while (exists_non_essential_connecting_device(drv)) + if (wait_loop(start, 30, &seconds_waited)) + break; - schedule_timeout_interruptible(HZ/10); - } + /* Skips PVKB and PVFB check.*/ + while (exists_essential_connecting_device(drv)) + if (wait_loop(start, 270, &seconds_waited)) + break; if (seconds_waited) printk("\n"); From 716af4abd6e6370226f567af50bfaca274515980 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Apr 2012 10:00:19 +0300 Subject: [PATCH 384/438] ksz884x: don't copy too much in netdev_set_mac_address() MAX_ADDR_LEN is 32. ETH_ALEN is 6. mac->sa_data is a 14 byte array, so the memcpy() is doing a read past the end of the array. I asked about this on netdev and Ben Hutchings told me it's supposed to be copying ETH_ALEN bytes (thanks Ben). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ksz884x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index ef723b185d85..eaf9ff0262a9 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); } - memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); + memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); interrupt = hw_block_intr(hw); From 3cd88f993e8b24855ed135b36bc6ed53dff38f08 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Apr 2012 19:35:10 +0100 Subject: [PATCH 385/438] Revert "ARM: 7359/2: smp_twd: Only wait for reprogramming on active cpus" This reverts commit 9f85550347f51c79a917b2aec04c90691c11e20a. Peter Zijlstra says: | Argh, how did that ever make it upstream, please drop. | | Russell, please make that go away upstream. | | Like I said, this is both completely the wrong way to solve, and you're | so not paying attention, see: | | 5fbd036b552f633abb394a319f7c62a5c86a9cd7 | 2baab4e90495ebc9826c93f79d74d6e60a828d24 | e3831edd59edf57ca11fc289f08961b20baf5146 | | What's even worse: | | git describe --contains 9f85550347f51c79a917b2aec04c90691c11e20a --match "v*" | v3.4-rc3~1^2~3 | | that nonsense got merged long after those other commits. Linus Walleij says: | My bad, was because the initial patch was submitted march 9th before | these fixes were merged: | http://marc.info/?l=linux-arm-kernel&m=133159655513844&w=2 | | It was pending for a while in Russell's patch tracker and I | rebased it to -rc2 without paying enough attention to recent | related scheduler fixes ... lesson learned. Signed-off-by: Russell King --- arch/arm/kernel/smp_twd.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 5b150afb995b..fef42b21cecb 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -118,14 +118,10 @@ static int twd_cpufreq_transition(struct notifier_block *nb, * The twd clock events must be reprogrammed to account for the new * frequency. The timer is local to a cpu, so cross-call to the * changing cpu. - * - * Only wait for it to finish, if the cpu is active to avoid - * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during - * booting of that cpu. */ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, cpu_active(freqs->cpu)); + NULL, 1); return NOTIFY_OK; } From 18311c5395ca4d0c3fefa406da87a9d16efaca46 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 18 Apr 2012 03:59:01 -0300 Subject: [PATCH 386/438] [media] V4L: mt9m032: fix compilation breakage Fix the following compilation failure: linux-2.6/drivers/media/video/mt9m032.c: In function '__mt9m032_get_pad_crop': linux-2.6/drivers/media/video/mt9m032.c:337: error: implicit declaration of function 'v4l2_subdev_get_try_crop' linux-2.6/drivers/media/video/mt9m032.c:337: warning: return makes pointer from integer without a cast linux-2.6/drivers/media/video/mt9m032.c: In function '__mt9m032_get_pad_format': linux-2.6/drivers/media/video/mt9m032.c:359: error: implicit declaration of function 'v4l2_subdev_get_try_format' linux-2.6/drivers/media/video/mt9m032.c:359: warning: return makes pointer from integer without a cast linux-2.6/drivers/media/video/mt9m032.c: In function 'mt9m032_probe': linux-2.6/drivers/media/video/mt9m032.c:767: error: 'struct v4l2_subdev' has no member named 'entity' linux-2.6/drivers/media/video/mt9m032.c:826: error: 'struct v4l2_subdev' has no member named 'entity' linux-2.6/drivers/media/video/mt9m032.c: In function 'mt9m032_remove': linux-2.6/drivers/media/video/mt9m032.c:842: error: 'struct v4l2_subdev' has no member named 'entity' make[4]: *** [drivers/media/video/mt9m032.o] Error 1 by adding a dependency on VIDEO_V4L2_SUBDEV_API. Signed-off-by: Guennadi Liakhovetski Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f2479c5c0eb2..ce1e7ba940f6 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624 config VIDEO_MT9M032 tristate "MT9M032 camera sensor support" - depends on I2C && VIDEO_V4L2 + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API select VIDEO_APTINA_PLL ---help--- This driver supports MT9M032 camera sensors from Aptina, monochrome From 186bab1ce04f99153b7eeb3348438b654c24c24b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 17 Apr 2012 14:35:49 -0400 Subject: [PATCH 387/438] xen/resume: Fix compile warnings. linux/drivers/xen/manage.c: In function 'do_suspend': linux/drivers/xen/manage.c:160:5: warning: 'si.cancelled' may be used uninitialized in this function Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 9e14ae6cd49c..412b96cc5305 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -132,6 +132,7 @@ static void do_suspend(void) err = dpm_suspend_end(PMSG_FREEZE); if (err) { printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); + si.cancelled = 0; goto out_resume; } From e631f578048e2afd8bfede2e9dc86aa4592def3a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 16 Apr 2012 14:59:32 -0300 Subject: [PATCH 388/438] [media] xc5000: support 32MHz & 31.875MHz xtal using the 41.024.5 firmware Rather than loading firmware specific for the xtal frequency, just use the standard firmware and set the xtal frequency after firmware upload. The modified firmware will never be released, so we're better off merging this now rather than waiting for v3.5. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 39 +++++++++++++++++++++++++--- drivers/media/common/tuners/xc5000.h | 1 + 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 7f98984e4fad..eab2ea424200 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -54,6 +54,7 @@ struct xc5000_priv { struct list_head hybrid_tuner_instance_list; u32 if_khz; + u32 xtal_khz; u32 freq_hz; u32 bandwidth; u8 video_standard; @@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = { .size = 12401, }; -static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { - .name = "dvb-fe-xc5000c-41.024.5-31875.fw", - .size = 16503, +static const struct xc5000_fw_cfg xc5000c_41_024_5 = { + .name = "dvb-fe-xc5000c-41.024.5.fw", + .size = 16497, }; static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) case XC5000A: return &xc5000a_1_6_114; case XC5000C: - return &xc5000c_41_024_5_31875; + return &xc5000c_41_024_5; } } @@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) return found; } +static int xc_set_xtal(struct dvb_frontend *fe) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret = XC_RESULT_SUCCESS; + + switch (priv->chip_id) { + default: + case XC5000A: + /* 32.000 MHz xtal is default */ + break; + case XC5000C: + switch (priv->xtal_khz) { + default: + case 32000: + /* 32.000 MHz xtal is default */ + break; + case 31875: + /* 31.875 MHz xtal configuration */ + ret = xc_write_reg(priv, 0x000f, 0x8081); + break; + } + break; + } + return ret; +} static int xc5000_fwupload(struct dvb_frontend *fe) { @@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe) } else { printk(KERN_INFO "xc5000: firmware uploading...\n"); ret = xc_load_i2c_sequence(fe, fw->data); + if (XC_RESULT_SUCCESS == ret) + ret = xc_set_xtal(fe); printk(KERN_INFO "xc5000: firmware upload complete...\n"); } @@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, priv->if_khz = cfg->if_khz; } + if (priv->xtal_khz == 0) + priv->xtal_khz = cfg->xtal_khz; + if (priv->radio_input == 0) priv->radio_input = cfg->radio_input; diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index 3396f8e02b40..39a73bf01406 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -34,6 +34,7 @@ struct xc5000_config { u8 i2c_address; u32 if_khz; u8 radio_input; + u32 xtal_khz; int chip_id; }; From 7e5998aa74065d3ab31d17e667f40ffebf4b8425 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Apr 2012 20:53:42 +0000 Subject: [PATCH 389/438] bnx2x: off by one in bnx2x_ets_e3b0_sp_pri_to_cos_set() The sp_pri_to_cos[] array size depends on the config but lets say it is BX_E3B0_MAX_NUM_COS_PORT0 and max_num_of_cos is also DCBX_E3B0_MAX_NUM_COS_PORT0. In the original code "pri == max_num_of_cos" was accepted but it is one past the end of the array. Also we used "pri" before capping it. It's a harmless read past the end of the array, but it would affect which error message gets printed. Signed-off-by: Dan Carpenter Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index ad95324dc042..64392ec410a3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : DCBX_E3B0_MAX_NUM_COS_PORT0; + if (pri >= max_num_of_cos) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " + "parameter Illegal strict priority\n"); + return -EINVAL; + } + if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) { DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " "parameter There can't be two COS's with " @@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, return -EINVAL; } - if (pri > max_num_of_cos) { - DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " - "parameter Illegal strict priority\n"); - return -EINVAL; - } - sp_pri_to_cos[pri] = cos_entry; return 0; From 3bc17d10c9f8ac67eb474737d74894ef2e60d27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 17 Apr 2012 09:38:23 +0000 Subject: [PATCH 390/438] net: qmi_wwan: support Sierra Wireless MC77xx devices in QMI mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MC77xx devices can operate in two modes: "Direct IP" or "QMI", switchable using a password protected AT command. Both product ID and USB interface configuration will change when switched. The "sierra_net" driver supports the "Direct IP" mode. This driver supports the "QMI" mode. There are also multiple possible USB interface configurations in each mode, some providing more than one wwan interface. Like many other devices made for Windows, different interface types are identified using a static interface number. We define a Sierra specific interface whitelist to support this. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 552d24bf862e..d316503b35d4 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -365,6 +365,27 @@ static const struct driver_info qmi_wwan_force_int4 = { .data = BIT(4), /* interface whitelist bitmap */ }; +/* Sierra Wireless provide equally useless interface descriptors + * Devices in QMI mode can be switched between two different + * configurations: + * a) USB interface #8 is QMI/wwan + * b) USB interfaces #8, #19 and #20 are QMI/wwan + * + * Both configurations provide a number of other interfaces (serial++), + * some of which have the same endpoint configuration as we expect, so + * a whitelist or blacklist is necessary. + * + * FIXME: The below whitelist should include BIT(20). It does not + * because I cannot get it to work... + */ +static const struct driver_info qmi_wwan_sierra = { + .description = "Sierra Wireless wwan/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_gobi, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ +}; #define HUAWEI_VENDOR_ID 0x12D1 #define QMI_GOBI_DEVICE(vend, prod) \ @@ -445,6 +466,15 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, + { /* Sierra Wireless MC77xx in QMI mode */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1199, + .idProduct = 0x68a2, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_sierra, + }, {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ From 996f73937cd85031da8dbcd3222a710cb762d428 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Tue, 17 Apr 2012 21:16:40 +0000 Subject: [PATCH 391/438] icplus: fix interrupt for IC+ 101A/G and 1001LF This patch fixes and adds the irq handler for the IC+ 101A/G where we need to read the reg17 to clean the irq. Also remove the flag for the 1001LF where no interrupt can be used for this device. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/phy/icplus.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index f08c85acf761..5ac46f5226f3 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ +#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ static int ip175c_config_init(struct phy_device *phydev) { @@ -185,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev) return 0; } +static int ip101a_g_ack_interrupt(struct phy_device *phydev) +{ + int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); + if (err < 0) + return err; + + return 0; +} + static struct phy_driver ip175c_driver = { .phy_id = 0x02430d80, .name = "ICPlus IP175C", @@ -204,7 +214,6 @@ static struct phy_driver ip1001_driver = { .phy_id_mask = 0x0ffffff0, .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_INTERRUPT, .config_init = &ip1001_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, @@ -220,6 +229,7 @@ static struct phy_driver ip101a_g_driver = { .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, .flags = PHY_HAS_INTERRUPT, + .ack_interrupt = ip101a_g_ack_interrupt, .config_init = &ip101a_g_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, From 3adadc08cc1e2cbcc15a640d639297ef5fcb17f5 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 18 Apr 2012 16:11:23 +0000 Subject: [PATCH 392/438] net ax25: Reorder ax25_exit to remove races. While reviewing the sysctl code in ax25 I spotted races in ax25_exit where it is possible to receive notifications and packets after already freeing up some of the data structures needed to process those notifications and updates. Call unregister_netdevice_notifier early so that the rest of the cleanup code does not need to deal with network devices. This takes advantage of my recent enhancement to unregister_netdevice_notifier to send unregister notifications of all network devices that are current registered. Move the unregistration for packet types, socket types and protocol types before we cleanup any of the ax25 data structures to remove the possibilities of other races. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- net/ax25/af_ax25.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 0906c194a413..9d9a6a3edbd5 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -2011,16 +2011,17 @@ static void __exit ax25_exit(void) proc_net_remove(&init_net, "ax25_route"); proc_net_remove(&init_net, "ax25"); proc_net_remove(&init_net, "ax25_calls"); - ax25_rt_free(); - ax25_uid_free(); - ax25_dev_free(); - ax25_unregister_sysctl(); unregister_netdevice_notifier(&ax25_dev_notifier); + ax25_unregister_sysctl(); dev_remove_pack(&ax25_packet_type); sock_unregister(PF_AX25); proto_unregister(&ax25_proto); + + ax25_rt_free(); + ax25_uid_free(); + ax25_dev_free(); } module_exit(ax25_exit); From 8a95bc8dfe06982fc2b8a0a2adda7baa2346a17b Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Wed, 30 Nov 2011 10:19:17 -0600 Subject: [PATCH 393/438] powerpc/85xx: don't call of_platform_bus_probe() twice Commit 46d026ac ("powerpc/85xx: consolidate of_platform_bus_probe calls") replaced platform-specific of_device_id tables with a single function that probes the most of the busses in 85xx device trees. If a specific platform needed additional busses probed, then it could call of_platform_bus_probe() again. Typically, the additional platform-specific busses are children of existing busses that have already been probed. of_platform_bus_probe() does not handle those child busses automatically. Unfortunately, this doesn't actually work. The second (platform-specific) call to of_platform_bus_probe() never finds any of the busses it's asked to find. To remedy this, the platform-specific of_device_id tables are eliminated, and their entries are merged into mpc85xx_common_ids[], so that all busses are probed at once. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/platforms/85xx/common.c | 6 ++++++ arch/powerpc/platforms/85xx/mpc85xx_mds.c | 11 +---------- arch/powerpc/platforms/85xx/p1022_ds.c | 13 +------------ 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 9fef5302adc1..67dac22b4363 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -21,6 +21,12 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = { { .compatible = "fsl,qe", }, { .compatible = "fsl,cpm2", }, { .compatible = "fsl,srio", }, + /* So that the DMA channel nodes can be probed individually: */ + { .compatible = "fsl,eloplus-dma", }, + /* For the PMC driver */ + { .compatible = "fsl,mpc8548-guts", }, + /* Probably unnecessary? */ + { .compatible = "gpio-leds", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 9a6f04406e0d..d208ebccb91c 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -399,12 +399,6 @@ static int __init board_fixups(void) machine_arch_initcall(mpc8568_mds, board_fixups); machine_arch_initcall(mpc8569_mds, board_fixups); -static struct of_device_id mpc85xx_ids[] = { - { .compatible = "fsl,mpc8548-guts", }, - { .compatible = "gpio-leds", }, - {}, -}; - static int __init mpc85xx_publish_devices(void) { if (machine_is(mpc8568_mds)) @@ -412,10 +406,7 @@ static int __init mpc85xx_publish_devices(void) if (machine_is(mpc8569_mds)) simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); - mpc85xx_common_publish_devices(); - of_platform_bus_probe(NULL, mpc85xx_ids, NULL); - - return 0; + return mpc85xx_common_publish_devices(); } machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index e74b7cde9aee..f700c81a1321 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -460,18 +460,7 @@ static void __init p1022_ds_setup_arch(void) pr_info("Freescale P1022 DS reference board\n"); } -static struct of_device_id __initdata p1022_ds_ids[] = { - /* So that the DMA channel nodes can be probed individually: */ - { .compatible = "fsl,eloplus-dma", }, - {}, -}; - -static int __init p1022_ds_publish_devices(void) -{ - mpc85xx_common_publish_devices(); - return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); -} -machine_device_initcall(p1022_ds, p1022_ds_publish_devices); +machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices); machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); From eda713e219c9a7d02b8263ab3fba44092e919b07 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 19 Apr 2012 09:32:06 +0300 Subject: [PATCH 394/438] powerpc: fix build when CONFIG_BOOKE_WDT is enabled Commit ae3a197e (Disintegrate asm/system.h for PowerPC) broke build of assembly files when CONFIG_BOOKE_WDT is enabled as follows: AS arch/powerpc/lib/string.o /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h: Assembler messages: /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:19: Error: Unrecognized opcode: `extern' /home/baruch/git/stable/arch/powerpc/include/asm/reg_booke.h:20: Error: Unrecognized opcode: `extern' Since setup_32.c is the only user of the booke_wdt configuration variables, move the declarations there. Cc: David Howells Signed-off-by: Baruch Siach Signed-off-by: Kumar Gala --- arch/powerpc/include/asm/reg_booke.h | 5 ----- arch/powerpc/kernel/setup_32.c | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index b86faa9107da..8a97aa7289d3 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -15,11 +15,6 @@ #ifndef __ASM_POWERPC_REG_BOOKE_H__ #define __ASM_POWERPC_REG_BOOKE_H__ -#ifdef CONFIG_BOOKE_WDT -extern u32 booke_wdt_enabled; -extern u32 booke_wdt_period; -#endif /* CONFIG_BOOKE_WDT */ - /* Machine State Register (MSR) Fields */ #define MSR_GS (1<<28) /* Guest state */ #define MSR_UCLE (1<<26) /* User-mode cache lock enable */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 9825f29d1faf..ec8a53fa9e8f 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -150,6 +150,9 @@ notrace void __init machine_init(u64 dt_ptr) } #ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; + /* Checks wdt=x and wdt_period=xx command-line option */ notrace int __init early_parse_wdt(char *p) { From bdce27c7f7bc7cf5c3a264bab9de056bd9cb0c9d Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Mon, 16 Apr 2012 10:05:05 +0800 Subject: [PATCH 395/438] powerpc/mpic_msgr: fix compile error when SMP disabled In file included from arch/powerpc/sysdev/mpic_msgr.c:20:0: ~/arch/powerpc/include/asm/mpic_msgr.h: In function 'mpic_msgr_set_destination': ~/arch/powerpc/include/asm/mpic_msgr.h:117:2: error: implicit declaration of function 'get_hard_smp_processor_id' make[1]: *** [arch/powerpc/sysdev/mpic_msgr.o] Error 1 Signed-off-by: Mingkai Hu Signed-off-by: Kumar Gala --- arch/powerpc/include/asm/mpic_msgr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/mpic_msgr.h b/arch/powerpc/include/asm/mpic_msgr.h index 3ec37dc9003e..326d33ca55cd 100644 --- a/arch/powerpc/include/asm/mpic_msgr.h +++ b/arch/powerpc/include/asm/mpic_msgr.h @@ -13,6 +13,7 @@ #include #include +#include struct mpic_msgr { u32 __iomem *base; From e0a5a6c38190a5016bcb0f1267324a19b846a35a Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Mon, 16 Apr 2012 10:05:06 +0800 Subject: [PATCH 396/438] powerpc/mpic_msgr: add lock for MPIC message global variable Also fix issue of accessing invalid msgr pointer issue. The local msgr pointer in fucntion mpic_msgr_get will be accessed before getting a valid address which will cause kernel crash. Signed-off-by: Mingkai Hu Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/mpic_msgr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 6e7fa386e76a..dc1cfe380070 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -27,6 +27,7 @@ static struct mpic_msgr **mpic_msgrs; static unsigned int mpic_msgr_count; +static DEFINE_RAW_SPINLOCK(msgrs_lock); static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value) { @@ -56,12 +57,11 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num) if (reg_num >= mpic_msgr_count) return ERR_PTR(-ENODEV); - raw_spin_lock_irqsave(&msgr->lock, flags); - if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { - msgr = mpic_msgrs[reg_num]; + raw_spin_lock_irqsave(&msgrs_lock, flags); + msgr = mpic_msgrs[reg_num]; + if (msgr->in_use == MSGR_FREE) msgr->in_use = MSGR_INUSE; - } - raw_spin_unlock_irqrestore(&msgr->lock, flags); + raw_spin_unlock_irqrestore(&msgrs_lock, flags); return msgr; } From dea58bd1cab8f6687a784cdacca242b6cac95ede Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Mon, 16 Apr 2012 10:05:07 +0800 Subject: [PATCH 397/438] powerpc/mpic_msgr: fix offset error when setting mer register Signed-off-by: Mingkai Hu Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/mpic_msgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index dc1cfe380070..483d8fa72e8b 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev) reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i; msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; - msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; + msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET); msgr->in_use = MSGR_FREE; msgr->num = i; raw_spin_lock_init(&msgr->lock); From 4351f30a35b8c6a6b6d4d36e5c2dc8ec0262b2ca Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Mon, 16 Apr 2012 10:05:08 +0800 Subject: [PATCH 398/438] powerpc/mpc85xx: add MPIC message dts node Signed-off-by: Mingkai Hu Signed-off-by: Kumar Gala --- .../boot/dts/fsl/pq3-mpic-message-B.dtsi | 43 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi | 10 +++++ 2 files changed, 53 insertions(+) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi new file mode 100644 index 000000000000..1cf0b77b1efe --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi @@ -0,0 +1,43 @@ +/* + * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ] + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +message@42400 { + compatible = "fsl,mpic-v3.1-msgr"; + reg = <0x42400 0x200>; + interrupts = < + 0xb4 2 0 0 + 0xb5 2 0 0 + 0xb6 2 0 0 + 0xb7 2 0 0>; +}; diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi index fdedf7b1fe0f..71c30eb10056 100644 --- a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi +++ b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi @@ -53,6 +53,16 @@ timer@41100 { 3 0 3 0>; }; +message@41400 { + compatible = "fsl,mpic-v3.1-msgr"; + reg = <0x41400 0x200>; + interrupts = < + 0xb0 2 0 0 + 0xb1 2 0 0 + 0xb2 2 0 0 + 0xb3 2 0 0>; +}; + msi@41600 { compatible = "fsl,mpic-msi"; reg = <0x41600 0x80>; From d3a7b83f865b46bb7b5e1ed18a129ce1af349db4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 19 Apr 2012 18:12:40 +0200 Subject: [PATCH 399/438] drivers/tty/amiserial.c: add missing tty_unlock tty_unlock is used on all other exits from the function. Signed-off-by: Julia Lawall Acked-by: Jiri Slaby Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 24145c30c9b0..6cc4358f68c1 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, (new_serial.close_delay != port->close_delay) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (port->flags & ~ASYNC_USR_MASK))) + (port->flags & ~ASYNC_USR_MASK))) { + tty_unlock(); return -EPERM; + } port->flags = ((port->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); state->custom_divisor = new_serial.custom_divisor; From 2d5733fcd33dd451022d197cb6b476e970519ca7 Mon Sep 17 00:00:00 2001 From: Yuri Matylitski Date: Fri, 20 Apr 2012 12:38:32 +0300 Subject: [PATCH 400/438] USB: serial: cp210x: Fixed usb_control_msg timeout values Fixed too small hardcoded timeout values for usb_control_msg in driver for SiliconLabs cp210x-based usb-to-serial adapters. Replaced with USB_CTRL_GET_TIMEOUT/USB_CTRL_SET_TIMEOUT. Signed-off-by: Yuri Matylitski Acked-by: Kirill A. Shutemov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 0310e2df59f5..ec30f95ef399 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, + USB_CTRL_GET_TIMEOUT); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, + USB_CTRL_SET_TIMEOUT); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, 300); + port_priv->bInterfaceNumber, NULL, 0, + USB_CTRL_SET_TIMEOUT); } kfree(buf); From 3d81acb1cdb242378a1acb3eb1bc28c6bb5895f1 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 20 Apr 2012 11:50:30 -0400 Subject: [PATCH 401/438] Revert "xen/p2m: m2p_find_override: use list_for_each_entry_safe" This reverts commit b960d6c43a63ebd2d8518b328da3816b833ee8cc. If we have another thread (very likely) touched the list, we end up hitting a problem "that the next element is wrong because we should be able to cope with that. The problem is that the next->next pointer would be set LIST_POISON1. " (Stefano's comment on the patch). Reverting for now. Suggested-by: Dan Carpenter Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/p2m.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 7ed8cc3434c5..1b267e75158d 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -809,17 +809,21 @@ struct page *m2p_find_override(unsigned long mfn) { unsigned long flags; struct list_head *bucket = &m2p_overrides[mfn_hash(mfn)]; - struct page *p, *t, *ret; + struct page *p, *ret; ret = NULL; - list_for_each_entry_safe(p, t, bucket, lru) { + spin_lock_irqsave(&m2p_override_lock, flags); + + list_for_each_entry(p, bucket, lru) { if (page_private(p) == mfn) { ret = p; break; } } + spin_unlock_irqrestore(&m2p_override_lock, flags); + return ret; } From b3dc627cabb33fc95f93da78457770c1b2a364d2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Apr 2012 08:31:34 -0700 Subject: [PATCH 402/438] memblock: memblock should be able to handle zero length operations Commit 24aa07882b ("memblock, x86: Replace memblock_x86_reserve/ free_range() with generic ones") replaced x86 specific memblock operations with the generic ones; unfortunately, it lost zero length operation handling in the process making the kernel panic if somebody tries to reserve zero length area. There isn't much to be gained by being cranky to zero length operations and panicking is almost the worst response. Drop the BUG_ON() in memblock_reserve() and update memblock_add_region/isolate_range() so that all zero length operations are handled as noops. Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org Reported-by: Valere Monseur Bisected-by: Joseph Freeman Tested-by: Joseph Freeman Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43098 Signed-off-by: Linus Torvalds --- mm/memblock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/memblock.c b/mm/memblock.c index 99f285599501..a44eab3157f8 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -330,6 +330,9 @@ static int __init_memblock memblock_add_region(struct memblock_type *type, phys_addr_t end = base + memblock_cap_size(base, &size); int i, nr_new; + if (!size) + return 0; + /* special case for empty array */ if (type->regions[0].size == 0) { WARN_ON(type->cnt != 1 || type->total_size); @@ -430,6 +433,9 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, *start_rgn = *end_rgn = 0; + if (!size) + return 0; + /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) if (memblock_double_array(type) < 0) @@ -514,7 +520,6 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) (unsigned long long)base, (unsigned long long)base + size, (void *)_RET_IP_); - BUG_ON(0 == size); return memblock_add_region(_rgn, base, size, MAX_NUMNODES); } From 19244ad06b70ed84931df868583547ce1cd3a186 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 20 Apr 2012 11:19:35 -0700 Subject: [PATCH 403/438] Revert "ACPI: ignore FADT reset-reg-sup flag" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit cf450136bfde77c7f95065c91bffded4aa7fa731. It breaks reboot on at least one Thinkpad T43, as reported by Jörg Otte: "On reboot it shuts down as normal. The last lines displayed are: >Unmounting temporary filesystems.. [OK] >Deactivating swap... [OK] >Unmounting local filesystems... [OK] >Will now restart > Restarting system Then I hear it accessing the cd-drive, but then it's being stuck." Jörg bisected the regression to this commit. That commit fixes another machine (see https://bugzilla.kernel.org/show_bug.cgi?id=11533 for details) that has a BIOS bug and doesn't support ACPI reset. However, at least one of those other reporters no longer even has the machine in question, and had a different workaround to begin with. Besides, it clearly was a buggy BIOS. Let's not break the correct case to fix that case. Reported-and-bisected-by: Jörg Otte Cc: linux-acpi@vger.kernel.org Cc: Len Brown Cc: Peter Anvin Signed-off-by: Linus Torvalds --- drivers/acpi/acpica/hwxface.c | 3 ++- drivers/acpi/reboot.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index ab513a972c95..a716fede4f25 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -74,7 +74,8 @@ acpi_status acpi_reset(void) /* Check if the reset register is supported */ - if (!reset_reg->address) { + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || + !reset_reg->address) { return_ACPI_STATUS(AE_NOT_EXIST); } diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index c1d612435939..a6c77e8b37bd 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -23,7 +23,8 @@ void acpi_reboot(void) /* Is the reset register supported? The spec says we should be * checking the bit width and bit offset, but Windows ignores * these fields */ - /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) + return; reset_value = acpi_gbl_FADT.reset_value; From e4eb1ff61b323d6141614e5458a1f53c7046ff8e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 20 Apr 2012 15:35:40 -0700 Subject: [PATCH 404/438] VM: add "vm_brk()" helper function It does the same thing as "do_brk()", except it handles the VM locking too. It turns out that all external callers want that anyway, so we can make do_brk() static to just mm/mmap.c while at it. Signed-off-by: Linus Torvalds --- arch/x86/ia32/ia32_aout.c | 20 +++++--------------- fs/binfmt_aout.c | 20 +++++--------------- fs/binfmt_elf.c | 15 ++++----------- include/linux/mm.h | 3 ++- mm/mmap.c | 16 ++++++++++++++-- mm/nommu.c | 2 +- 6 files changed, 31 insertions(+), 45 deletions(-) diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index d511d951a052..b6817ee9033f 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end <= start) return; - down_write(¤t->mm->mmap_sem); - do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); + vm_brk(start, end - start); } #ifdef CORE_DUMP @@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) pos = 32; map_size = ex.a_text+ex.a_data; - down_write(¤t->mm->mmap_sem); - error = do_brk(text_addr & PAGE_MASK, map_size); - up_write(¤t->mm->mmap_sem); + error = vm_brk(text_addr & PAGE_MASK, map_size); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); @@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { loff_t pos = fd_offset; - down_write(¤t->mm->mmap_sem); - do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); - up_write(¤t->mm->mmap_sem); + vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -476,9 +470,7 @@ static int load_aout_library(struct file *file) error_time = jiffies; } #endif - down_write(¤t->mm->mmap_sem); - do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); - up_write(¤t->mm->mmap_sem); + vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -503,9 +495,7 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - down_write(¤t->mm->mmap_sem); - error = do_brk(start_addr + len, bss - len); - up_write(¤t->mm->mmap_sem); + error = vm_brk(start_addr + len, bss - len); retval = error; if (error != start_addr + len) goto out; diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 2eb12f13593d..88527492b917 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end > start) { unsigned long addr; - down_write(¤t->mm->mmap_sem); - addr = do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); + addr = vm_brk(start, end - start); if (BAD_ADDR(addr)) return addr; } @@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; #endif - down_write(¤t->mm->mmap_sem); - error = do_brk(text_addr & PAGE_MASK, map_size); - up_write(¤t->mm->mmap_sem); + error = vm_brk(text_addr & PAGE_MASK, map_size); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; - down_write(¤t->mm->mmap_sem); - do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); - up_write(¤t->mm->mmap_sem); + vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -412,9 +406,7 @@ static int load_aout_library(struct file *file) "N_TXTOFF is not page aligned. Please convert library: %s\n", file->f_path.dentry->d_name.name); } - down_write(¤t->mm->mmap_sem); - do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); - up_write(¤t->mm->mmap_sem); + vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -438,9 +430,7 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - down_write(¤t->mm->mmap_sem); - error = do_brk(start_addr + len, bss - len); - up_write(¤t->mm->mmap_sem); + error = vm_brk(start_addr + len, bss - len); retval = error; if (error != start_addr + len) goto out; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 48ffb3dc610a..0708a0bf0ba9 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end) end = ELF_PAGEALIGN(end); if (end > start) { unsigned long addr; - down_write(¤t->mm->mmap_sem); - addr = do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); + addr = vm_brk(start, end - start); if (BAD_ADDR(addr)) return addr; } @@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* Map the last of the bss segment */ - down_write(¤t->mm->mmap_sem); - error = do_brk(elf_bss, last_bss - elf_bss); - up_write(¤t->mm->mmap_sem); + error = vm_brk(elf_bss, last_bss - elf_bss); if (BAD_ADDR(error)) goto out_close; } @@ -1072,11 +1068,8 @@ static int load_elf_library(struct file *file) len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss = eppnt->p_memsz + eppnt->p_vaddr; - if (bss > len) { - down_write(¤t->mm->mmap_sem); - do_brk(len, bss - len); - up_write(¤t->mm->mmap_sem); - } + if (bss > len) + vm_brk(len, bss - len); error = 0; out_free_ph: diff --git a/include/linux/mm.h b/include/linux/mm.h index d8738a464b94..bfee4ad6680b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1415,7 +1415,8 @@ out: extern int do_munmap(struct mm_struct *, unsigned long, size_t); -extern unsigned long do_brk(unsigned long, unsigned long); +/* These take the mm semaphore themselves */ +extern unsigned long vm_brk(unsigned long, unsigned long); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/mm/mmap.c b/mm/mmap.c index a7bf6a31c9f6..df51891c8646 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } +static unsigned long do_brk(unsigned long addr, unsigned long len); + SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; @@ -2136,7 +2138,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm) * anonymous maps. eventually we may be able to do some * brk-specific accounting here. */ -unsigned long do_brk(unsigned long addr, unsigned long len) +static unsigned long do_brk(unsigned long addr, unsigned long len) { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; @@ -2232,7 +2234,17 @@ out: return addr; } -EXPORT_SYMBOL(do_brk); +unsigned long vm_brk(unsigned long addr, unsigned long len) +{ + struct mm_struct *mm = current->mm; + unsigned long ret; + + down_write(&mm->mmap_sem); + ret = do_brk(addr, len); + up_write(&mm->mmap_sem); + return ret; +} +EXPORT_SYMBOL(vm_brk); /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) diff --git a/mm/nommu.c b/mm/nommu.c index f59e170fceb4..634193324a6b 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1744,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm) kleave(""); } -unsigned long do_brk(unsigned long addr, unsigned long len) +unsigned long vm_brk(unsigned long addr, unsigned long len) { return -ENOMEM; } From 7194efb8f063ee3aa0cb50d9002348887e68ec10 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 5 Apr 2012 14:45:47 +0300 Subject: [PATCH 405/438] mmc: fixes for eMMC v4.5 discard operation eMMC v4.5 discard operation is significantly different from the existing trim operation because it is not guaranteed to work with the new sanitize operation. Consequently mmc_can_trim() is separated from mmc_can_discard(). Also the new discard operation does not result in the sectors being set to all-zeros, so discard_zeroes_data must not be set. In addition, the new discard has the same timeout as trim, but from v4.5 trim is defined to use the hc timeout. The timeout calculation is adjusted accordingly. Fixes apply to linux 3.2 on. Signed-off-by: Adrian Hunter Cc: Acked-by: Jaehoon Chung Acked-by: Linus Walleij Signed-off-by: Chris Ball --- drivers/mmc/card/queue.c | 2 +- drivers/mmc/core/core.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 2517547b4366..996f8e36e23d 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); q->limits.max_discard_sectors = max_discard; - if (card->erased_byte == 0) + if (card->erased_byte == 0 && !mmc_can_discard(card)) q->limits.discard_zeroes_data = 1; q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7474c47b9c08..83db5ef96bb0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1409,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, { unsigned int erase_timeout; - if (card->ext_csd.erase_group_def & 1) { + if (arg == MMC_DISCARD_ARG || + (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { + erase_timeout = card->ext_csd.trim_timeout; + } else if (card->ext_csd.erase_group_def & 1) { /* High Capacity Erase Group Size uses HC timeouts */ if (arg == MMC_TRIM_ARG) erase_timeout = card->ext_csd.trim_timeout; @@ -1681,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card) { if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) return 1; - if (mmc_can_discard(card)) - return 1; return 0; } EXPORT_SYMBOL(mmc_can_trim); From 283028122db37621b124f079ca8eae5b64807ad4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 5 Apr 2012 14:45:48 +0300 Subject: [PATCH 406/438] mmc: fixes for eMMC v4.5 sanitize operation eMMC v4.5 sanitize operation erases all copies of unmapped data. However trim or erase operations must be used first to unmap the required sectors. That was not being done. Fixes apply to linux 3.2 on. Signed-off-by: Adrian Hunter Cc: Acked-by: Jaehoon Chung Acked-by: Linus Walleij Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 56 ++++++++++++++++++++++++++++------------ drivers/mmc/core/core.c | 2 ++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index b1809650b7aa..4232bc4d9926 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg; + unsigned int from, nr, arg, trim_arg, erase_arg; int err = 0, type = MMC_BLK_SECDISCARD; if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, goto out; } - /* The sanitize operation is supported at v4.5 only */ - if (mmc_can_sanitize(card)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); - goto out; - } - from = blk_rq_pos(req); nr = blk_rq_sectors(req); - if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) - arg = MMC_SECURE_TRIM1_ARG; - else - arg = MMC_SECURE_ERASE_ARG; + /* The sanitize operation is supported at v4.5 only */ + if (mmc_can_sanitize(card)) { + erase_arg = MMC_ERASE_ARG; + trim_arg = MMC_TRIM_ARG; + } else { + erase_arg = MMC_SECURE_ERASE_ARG; + trim_arg = MMC_SECURE_TRIM1_ARG; + } + + if (mmc_erase_group_aligned(card, from, nr)) + arg = erase_arg; + else if (mmc_can_trim(card)) + arg = trim_arg; + else { + err = -EINVAL; + goto out; + } retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -904,25 +910,41 @@ retry: INAND_CMD38_ARG_SECERASE, 0); if (err) - goto out; + goto out_retry; } + err = mmc_erase(card, from, nr, arg); - if (!err && arg == MMC_SECURE_TRIM1_ARG) { + if (err == -EIO) + goto out_retry; + if (err) + goto out; + + if (arg == MMC_SECURE_TRIM1_ARG) { if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, 0); if (err) - goto out; + goto out_retry; } + err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); + if (err == -EIO) + goto out_retry; + if (err) + goto out; } -out: - if (err == -EIO && !mmc_blk_reset(md, card->host, type)) + + if (mmc_can_sanitize(card)) + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, 0); +out_retry: + if (err && !mmc_blk_reset(md, card->host, type)) goto retry; if (!err) mmc_blk_reset_success(md, type); +out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); spin_unlock_irq(&md->lock); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 83db5ef96bb0..e541efbf3256 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1702,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard); int mmc_can_sanitize(struct mmc_card *card) { + if (!mmc_can_trim(card) && !mmc_can_erase(card)) + return 0; if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) return 1; return 0; From b6d085f6f59108508c1eea9c5251deb765350c50 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Tue, 10 Apr 2012 09:57:36 -0400 Subject: [PATCH 407/438] mmc: omap_hsmmc: build fix for CONFIG_OF=y and CONFIG_MMC_OMAP_HS=m Commit 46856a68dc ("mmc: omap_hsmmc: Convert hsmmc driver to use device tree") introduced in 3.4-rc1 has a missing semi-colon, causing: drivers/mmc/host/omap_hsmmc.c:1745: error: expected ',' or ';' before 'extern' Reported-by: Russell King Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5c2b1c10af9c..cfd049c7349a 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = { .data = &omap4_reg_offset, }, {}, -} +}; MODULE_DEVICE_TABLE(of, omap_mmc_of_match); static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) From 4d048f915f32c8455605b106aa0de2cf68a71903 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 11 Apr 2012 15:33:13 +0530 Subject: [PATCH 408/438] mmc: omap_hsmmc: Get rid of of_have_populated_dt() usage of_have_populated_dt() is not expected to be used in drivers but instead only in early platform init code. Drivers on the other hand should rely on dev->of_node or of_match_device(). Besides usage of of_have_populated_dt() also throws up build error as below which was reported by Balaji TK, when omap_hsmmc is built as a module. ERROR: "allnodes" [drivers/mmc/host/omap_hsmmc.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 So get rid of all of_have_populated_dt() usage in omap_hsmmc driver and instead use dev->of_node to make the same dicisions as earlier. Signed-off-by: Rajendra Nayak Reported-by: Benoit Cousson Cc: Sebastian Andrzej Siewior Acked-by: Rob Herring Reviewed-by: Balaji T K Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index cfd049c7349a..56d4499d4388 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, * the pbias cell programming support is still missing when * booting with Device tree */ - if (of_have_populated_dt() && !vdd) + if (dev->of_node && !vdd) return 0; if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * can't be allowed when booting with device * tree. */ - (!of_have_populated_dt())) { + !host->dev->of_node) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to From a46ef99d80817a167477ed1c8b4d90ee0c2e726f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 20 Apr 2012 16:20:01 -0700 Subject: [PATCH 409/438] VM: add "vm_munmap()" helper function Like the vm_brk() function, this is the same as "do_munmap()", except it does the VM locking for the caller. Signed-off-by: Linus Torvalds --- arch/ia64/kernel/perfmon.c | 11 +++-------- arch/sparc/kernel/sys_sparc_64.c | 7 +------ arch/x86/kvm/x86.c | 4 +--- drivers/gpu/drm/i810/i810_dma.c | 4 +--- fs/aio.c | 7 ++----- include/linux/mm.h | 1 + mm/mmap.c | 21 ++++++++++++--------- mm/nommu.c | 9 +++++++-- 8 files changed, 28 insertions(+), 36 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 9d0fd7d5bb82..2777310b698b 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -605,9 +605,9 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) } static inline unsigned int -pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) +pfm_vm_munmap(struct mm_struct *mm, unsigned long addr, size_t len) { - return do_munmap(mm, addr, len); + return vm_munmap(mm, addr, len); } static inline unsigned long @@ -1473,13 +1473,8 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz /* * does the actual unmapping */ - down_write(&task->mm->mmap_sem); + r = pfm_vm_munmap(task->mm, (unsigned long)vaddr, size); - DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); - - r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); - - up_write(&task->mm->mmap_sem); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); } diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 232df9949530..022e57aadf5d 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -566,15 +566,10 @@ out: SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { - long ret; - if (invalid_64bit_range(addr, len)) return -EINVAL; - down_write(¤t->mm->mmap_sem); - ret = do_munmap(current->mm, addr, len); - up_write(¤t->mm->mmap_sem); - return ret; + return vm_munmap(current->mm, addr, len); } extern unsigned long do_mremap(unsigned long addr, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4044ce0bf7c1..8beb9ce79364 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6366,10 +6366,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (!user_alloc && !old.user_alloc && old.rmap && !npages) { int ret; - down_write(¤t->mm->mmap_sem); - ret = do_munmap(current->mm, old.userspace_addr, + ret = vm_munmap(current->mm, old.userspace_addr, old.npages * PAGE_SIZE); - up_write(¤t->mm->mmap_sem); if (ret < 0) printk(KERN_WARNING "kvm_vm_ioctl_set_memory_region: " diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 2c8a60c3b98e..b85337f06fbf 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -157,11 +157,9 @@ static int i810_unmap_buffer(struct drm_buf *buf) if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; - down_write(¤t->mm->mmap_sem); - retcode = do_munmap(current->mm, + retcode = vm_munmap(current->mm, (unsigned long)buf_priv->virtual, (size_t) buf->total); - up_write(¤t->mm->mmap_sem); buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = NULL; diff --git a/fs/aio.c b/fs/aio.c index da887604dfc5..99bd790e8cd2 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -92,11 +92,8 @@ static void aio_free_ring(struct kioctx *ctx) for (i=0; inr_pages; i++) put_page(info->ring_pages[i]); - if (info->mmap_size) { - down_write(&ctx->mm->mmap_sem); - do_munmap(ctx->mm, info->mmap_base, info->mmap_size); - up_write(&ctx->mm->mmap_sem); - } + if (info->mmap_size) + vm_munmap(ctx->mm, info->mmap_base, info->mmap_size); if (info->ring_pages && info->ring_pages != info->internal_pages) kfree(info->ring_pages); diff --git a/include/linux/mm.h b/include/linux/mm.h index bfee4ad6680b..cb61950a3aa1 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1417,6 +1417,7 @@ extern int do_munmap(struct mm_struct *, unsigned long, size_t); /* These take the mm semaphore themselves */ extern unsigned long vm_brk(unsigned long, unsigned long); +extern int vm_munmap(struct mm_struct *, unsigned long, size_t); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/mm/mmap.c b/mm/mmap.c index df51891c8646..4af45f519f19 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2107,20 +2107,23 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) return 0; } - EXPORT_SYMBOL(do_munmap); +int vm_munmap(struct mm_struct *mm, unsigned long start, size_t len) +{ + int ret; + + down_write(&mm->mmap_sem); + ret = do_munmap(mm, start, len); + up_write(&mm->mmap_sem); + return ret; +} +EXPORT_SYMBOL(vm_munmap); + SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { - int ret; - struct mm_struct *mm = current->mm; - profile_munmap(addr); - - down_write(&mm->mmap_sem); - ret = do_munmap(mm, addr, len); - up_write(&mm->mmap_sem); - return ret; + return vm_munmap(current->mm, addr, len); } static inline void verify_mm_writelocked(struct mm_struct *mm) diff --git a/mm/nommu.c b/mm/nommu.c index 634193324a6b..11a69b22bd4b 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1709,16 +1709,21 @@ erase_whole_vma: } EXPORT_SYMBOL(do_munmap); -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +int vm_munmap(struct mm_struct *mm, unsigned long addr, size_t len) { int ret; - struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } +EXPORT_SYMBOL(vm_munmap); + +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +{ + return vm_munmap(current->mm, addr, len); +} /* * release all the mappings made in a process's VM space From 6be5ceb02e98eaf6cfc4f8b12a896d04023f340d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 20 Apr 2012 17:13:58 -0700 Subject: [PATCH 410/438] VM: add "vm_mmap()" helper function This continues the theme started with vm_brk() and vm_munmap(): vm_mmap() does the same thing as do_mmap(), but additionally does the required VM locking. This uninlines (and rewrites it to be clearer) do_mmap(), which sadly duplicates it in mm/mmap.c and mm/nommu.c. But that way we don't have to export our internal do_mmap_pgoff() function. Some day we hopefully don't have to export do_mmap() either, if all modular users can become the simpler vm_mmap() instead. We're actually very close to that already, with the notable exception of the (broken) use in i810, and a couple of stragglers in binfmt_elf. Signed-off-by: Linus Torvalds --- arch/tile/kernel/single_step.c | 4 +--- arch/x86/ia32/ia32_aout.c | 12 +++------- arch/x86/kvm/x86.c | 4 +--- drivers/gpu/drm/drm_bufs.c | 12 ++++------ drivers/gpu/drm/exynos/exynos_drm_gem.c | 4 +--- drivers/gpu/drm/i810/i810_dma.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 4 +--- fs/binfmt_aout.c | 12 +++------- fs/binfmt_elf.c | 8 ++----- fs/binfmt_elf_fdpic.c | 18 ++++----------- fs/binfmt_flat.c | 12 +++------- fs/binfmt_som.c | 12 +++------- include/linux/mm.h | 23 +++++--------------- mm/mmap.c | 29 +++++++++++++++++++++++-- mm/nommu.c | 29 +++++++++++++++++++++++-- 15 files changed, 87 insertions(+), 97 deletions(-) diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index 9efbc1391b3c..89529c9f0605 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c @@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs) } /* allocate a cache line of writable, executable memory */ - down_write(¤t->mm->mmap_sem); - buffer = (void __user *) do_mmap(NULL, 0, 64, + buffer = (void __user *) vm_mmap(NULL, 0, 64, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); - up_write(¤t->mm->mmap_sem); if (IS_ERR((void __force *)buffer)) { kfree(state); diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index b6817ee9033f..4824fb45560f 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -379,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto beyond_if; } - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset); - up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset + ex.a_text); - up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -482,12 +478,10 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(file, start_addr, ex.a_text + ex.a_data, + error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, N_TXTOFF(ex)); - up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8beb9ce79364..1457be305fb1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, if (npages && !old.rmap) { unsigned long userspace_addr; - down_write(¤t->mm->mmap_sem); - userspace_addr = do_mmap(NULL, 0, + userspace_addr = vm_mmap(NULL, 0, npages * PAGE_SIZE, PROT_READ | PROT_WRITE, map_flags, 0); - up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)userspace_addr)) return PTR_ERR((void *)userspace_addr); diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 30372f7b2d45..348b367debeb 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, * \param arg pointer to a drm_buf_map structure. * \return zero on success or a negative number on failure. * - * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls do_mmap() with + * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls vm_mmap() with * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ @@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data, retcode = -EINVAL; goto done; } - down_write(¤t->mm->mmap_sem); - virtual = do_mmap(file_priv->filp, 0, map->size, + virtual = vm_mmap(file_priv->filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, token); - up_write(¤t->mm->mmap_sem); } else { - down_write(¤t->mm->mmap_sem); - virtual = do_mmap(file_priv->filp, 0, dma->byte_count, + virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, PROT_READ | PROT_WRITE, MAP_SHARED, 0); - up_write(¤t->mm->mmap_sem); } if (virtual > -1024UL) { /* Real error */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 26d51979116b..392ce71ed6a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -581,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, obj->filp->f_op = &exynos_drm_gem_fops; obj->filp->private_data = obj; - down_write(¤t->mm->mmap_sem); - addr = do_mmap(obj->filp, 0, args->size, + addr = vm_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); - up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index b85337f06fbf..a4ba453b3d27 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) if (buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; + /* This is all entirely broken */ down_write(¤t->mm->mmap_sem); old_fops = file_priv->filp->f_op; file_priv->filp->f_op = &i810_buffer_fops; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0e3c6acde955..0d1e4b7b4b99 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - down_write(¤t->mm->mmap_sem); - addr = do_mmap(obj->filp, 0, args->size, + addr = vm_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, args->offset); - up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) return addr; diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 88527492b917..d146e181d10d 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -319,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto beyond_if; } - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset); - up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - down_write(¤t->mm->mmap_sem); - error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); - up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -417,12 +413,10 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(file, start_addr, ex.a_text + ex.a_data, + error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); - up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 0708a0bf0ba9..16f735417072 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -958,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, + error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); } #ifdef ELF_PLAT_INIT @@ -1046,8 +1044,7 @@ static int load_elf_library(struct file *file) eppnt++; /* Now use mmap to map the library into memory. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(file, + error = vm_mmap(file, ELF_PAGESTART(eppnt->p_vaddr), (eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr)), @@ -1055,7 +1052,6 @@ static int load_elf_library(struct file *file) MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr))); - up_write(¤t->mm->mmap_sem); if (error != ELF_PAGESTART(eppnt->p_vaddr)) goto out_free_ph; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 9bd5612a8224..d390a0fffc65 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) stack_prot |= PROT_EXEC; - down_write(¤t->mm->mmap_sem); - current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, + current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED | MAP_GROWSDOWN, 0); if (IS_ERR_VALUE(current->mm->start_brk)) { - up_write(¤t->mm->mmap_sem); retval = current->mm->start_brk; current->mm->start_brk = 0; goto error_kill; } - up_write(¤t->mm->mmap_sem); - current->mm->brk = current->mm->start_brk; current->mm->context.end_brk = current->mm->start_brk; current->mm->context.end_brk += @@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) mflags |= MAP_EXECUTABLE; - down_write(&mm->mmap_sem); - maddr = do_mmap(NULL, load_addr, top - base, + maddr = vm_mmap(NULL, load_addr, top - base, PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); - up_write(&mm->mmap_sem); if (IS_ERR_VALUE(maddr)) return (int) maddr; @@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, /* create the mapping */ disp = phdr->p_vaddr & ~PAGE_MASK; - down_write(&mm->mmap_sem); - maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, + maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp); - up_write(&mm->mmap_sem); kdebug("mmap[%d] sz=%lx pr=%x fl=%x of=%lx --> %08lx", loop, phdr->p_memsz + disp, prot, flags, @@ -1143,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, unsigned long xmaddr; flags |= MAP_FIXED | MAP_ANONYMOUS; - down_write(&mm->mmap_sem); - xmaddr = do_mmap(NULL, xaddr, excess - excess1, + xmaddr = vm_mmap(NULL, xaddr, excess - excess1, prot, flags, 0); - up_write(&mm->mmap_sem); kdebug("mmap[%d] " " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 024d20ee3ca3..6b2daf99fab8 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm, */ DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); - down_write(¤t->mm->mmap_sem); - textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, + textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_EXECUTABLE, 0); - up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) textpos = (unsigned long) -ENOMEM; @@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm, len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - down_write(¤t->mm->mmap_sem); - realdatastart = do_mmap(0, 0, len, + realdatastart = vm_mmap(0, 0, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { if (!realdatastart) @@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm, len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - down_write(¤t->mm->mmap_sem); - textpos = do_mmap(0, 0, len, + textpos = vm_mmap(0, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index e4fc746629a7..4517aaff61b4 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c @@ -147,10 +147,8 @@ static int map_som_binary(struct file *file, code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); current->mm->start_code = code_start; current->mm->end_code = code_start + code_size; - down_write(¤t->mm->mmap_sem); - retval = do_mmap(file, code_start, code_size, prot, + retval = vm_mmap(file, code_start, code_size, prot, flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); - up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; @@ -158,20 +156,16 @@ static int map_som_binary(struct file *file, data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); current->mm->start_data = data_start; current->mm->end_data = bss_start = data_start + data_size; - down_write(¤t->mm->mmap_sem); - retval = do_mmap(file, data_start, data_size, + retval = vm_mmap(file, data_start, data_size, prot | PROT_WRITE, flags, SOM_PAGESTART(hpuxhdr->exec_dfile)); - up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); current->mm->start_brk = current->mm->brk = som_brk; - down_write(¤t->mm->mmap_sem); - retval = do_mmap(NULL, bss_start, som_brk - bss_start, + retval = vm_mmap(NULL, bss_start, som_brk - bss_start, prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); if (retval > 0 || retval < -1024) retval = 0; out: diff --git a/include/linux/mm.h b/include/linux/mm.h index cb61950a3aa1..86a692c3b238 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1393,31 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm, extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, vm_flags_t vm_flags, unsigned long pgoff); - -static inline unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret = -EINVAL; - if ((offset + PAGE_ALIGN(len)) < offset) - goto out; - if (!(offset & ~PAGE_MASK)) - ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -out: - return ret; -} - +extern unsigned long do_mmap(struct file *, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long); extern int do_munmap(struct mm_struct *, unsigned long, size_t); /* These take the mm semaphore themselves */ extern unsigned long vm_brk(unsigned long, unsigned long); extern int vm_munmap(struct mm_struct *, unsigned long, size_t); +extern unsigned long vm_mmap(struct file *, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/mm/mmap.c b/mm/mmap.c index 4af45f519f19..b38b47ef1f77 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -953,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) * The caller must hold down_write(¤t->mm->mmap_sem). */ -unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { @@ -1089,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return mmap_region(file, addr, len, flags, vm_flags, pgoff); } -EXPORT_SYMBOL(do_mmap_pgoff); + +unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + if (unlikely(offset + PAGE_ALIGN(len) < offset)) + return -EINVAL; + if (unlikely(offset & ~PAGE_MASK)) + return -EINVAL; + return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +} +EXPORT_SYMBOL(do_mmap); + +unsigned long vm_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long ret; + struct mm_struct *mm = current->mm; + + down_write(&mm->mmap_sem); + ret = do_mmap(file, addr, len, prot, flag, offset); + up_write(&mm->mmap_sem); + return ret; +} +EXPORT_SYMBOL(vm_mmap); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, diff --git a/mm/nommu.c b/mm/nommu.c index 11a69b22bd4b..dd00383be2d9 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1233,7 +1233,7 @@ enomem: /* * handle mapping creation for uClinux */ -unsigned long do_mmap_pgoff(struct file *file, +static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1470,7 +1470,32 @@ error_getting_region: show_free_areas(0); return -ENOMEM; } -EXPORT_SYMBOL(do_mmap_pgoff); + +unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + if (unlikely(offset + PAGE_ALIGN(len) < offset)) + return -EINVAL; + if (unlikely(offset & ~PAGE_MASK)) + return -EINVAL; + return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +} +EXPORT_SYMBOL(do_mmap); + +unsigned long vm_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long ret; + struct mm_struct *mm = current->mm; + + down_write(&mm->mmap_sem); + ret = do_mmap(file, addr, len, prot, flag, offset); + up_write(&mm->mmap_sem); + return ret; +} +EXPORT_SYMBOL(vm_mmap); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, From 32d317c60e56c2a34463b51fc0336cc96b3e1735 Mon Sep 17 00:00:00 2001 From: Chuanxiao Dong Date: Wed, 11 Apr 2012 19:54:38 +0800 Subject: [PATCH 411/438] mmc: remove MMC bus legacy suspend/resume method MMC bus is using legacy suspend/resume method, which is not compatible if runtime pm callbacks are used. In this scenario, MMC bus suspend/resume callbacks cannot be called when system entering S3. So change to use the new defined dev_pm_ops for system sleeping mode. Tested on AM335x Platform. Solves major issue/crash reported at http://www.mail-archive.com/linux-omap@vger.kernel.org/msg65425.html Signed-off-by: Chuanxiao Dong Tested-by: Hebbar, Gururaja Acked-by: Linus Walleij Acked-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 2 +- drivers/mmc/core/bus.c | 26 +++++++++----------------- include/linux/mmc/card.h | 2 +- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 4232bc4d9926..dabec556ebb8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1824,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card) } #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) +static int mmc_blk_suspend(struct mmc_card *card) { struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 3f606068d552..c60cee92a2b2 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static int mmc_bus_suspend(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->suspend) - ret = drv->suspend(card, state); + ret = drv->suspend(card); return ret; } @@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev) return pm_runtime_suspend(dev); } -static const struct dev_pm_ops mmc_bus_pm_ops = { - .runtime_suspend = mmc_runtime_suspend, - .runtime_resume = mmc_runtime_resume, - .runtime_idle = mmc_runtime_idle, -}; - -#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) - -#else /* !CONFIG_PM_RUNTIME */ - -#define MMC_PM_OPS_PTR NULL - #endif /* !CONFIG_PM_RUNTIME */ +static const struct dev_pm_ops mmc_bus_pm_ops = { + SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, + mmc_runtime_idle) + SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) +}; + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .suspend = mmc_bus_suspend, - .resume = mmc_bus_resume, - .pm = MMC_PM_OPS_PTR, + .pm = &mmc_bus_pm_ops, }; int mmc_register_bus(void) diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 01beae78f079..629b823f8836 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -481,7 +481,7 @@ struct mmc_driver { struct device_driver drv; int (*probe)(struct mmc_card *); void (*remove)(struct mmc_card *); - int (*suspend)(struct mmc_card *, pm_message_t); + int (*suspend)(struct mmc_card *); int (*resume)(struct mmc_card *); }; From a99aa9b9b4f4f3e496d17a1b4e0ff63fb0c9f31d Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 10 Apr 2012 09:53:32 +0900 Subject: [PATCH 412/438] mmc: dw_mmc: Fix switch from DMA to PIO When dw_mci_pre_dma_transfer returns failure in some reasons, dw_mci_submit_data will prepare to switch the PIO mode from DMA. After switching to PIO mode, DMA(IDMAC in particular) is still enabled. This makes the corruption in handling interrupt and the driver lock-up. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bf3c9b456aaf..f3b0fcd002df 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) return -ENODEV; sg_len = dw_mci_pre_dma_transfer(host, data, 0); - if (sg_len < 0) + if (sg_len < 0) { + host->dma_ops->stop(host); return sg_len; + } host->using_dma = 1; From 87b87a3fc0eec58d95e4216392f889a26439ad22 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 10 Apr 2012 00:14:20 +0100 Subject: [PATCH 413/438] mmc: sdhci: refine non-removable card checking for card detection Commit c79396c191bc19 ("mmc: sdhci: prevent card detection activity for non-removable cards") disables card detection where the cards are marked as non-removable. This makes sense, but the implementation detail of calling mmc_card_is_removable() causes some problems, because mmc_card_is_removable() is overloaded with CONFIG_MMC_UNSAFE_RESUME semantics. In the OLPC XO case, we need CONFIG_MMC_UNSAFE_RESUME because our root filesystem is stored on SD, but we also have external SD card slots where we want automatic card detection. Refine the check to only apply to hosts marked as MMC_CAP_NONREMOVABLE, which is defined to mean that the card is *really* nonremovable. This could be revisited in future if we find a way to improve CONFIG_MMC_UNSAFE_RESUME semantics. Signed-off-by: Daniel Drake Acked-by: Chuanxiao Dong [stable@: please apply to 3.3-stable] Cc: stable Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9aa77f3f04a8..ccefdebeff14 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) u32 present, irqs; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - !mmc_card_is_removable(host->mmc)) + (host->mmc->caps & MMC_CAP_NONREMOVABLE)) return; present = sdhci_readl(host, SDHCI_PRESENT_STATE) & From 5ca6518832ac913ac277b50ceddda8372dbf7bea Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 17 Apr 2012 13:03:38 -0700 Subject: [PATCH 414/438] mmc: cd-gpio: Include header to pickup exported symbol prototypes Include the linux/mmc/cd-gpio.h header to pickup the prototypes for the two exported symbols. This quiets the sparse warnings: warning: symbol 'mmc_cd_gpio_request' was not declared. Should it be static? warning: symbol 'mmc_cd_gpio_free' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Acked-by: Guennadi Liakhovetski Acked-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/core/cd-gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index 29de31e260dd..2c14be73254c 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include From b89152824f993a9572b47eb31f4579feadeac34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Wed, 18 Apr 2012 02:30:20 +0200 Subject: [PATCH 415/438] mmc: unbreak sdhci-esdhc-imx on i.MX25 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was broken by me in 37865fe91582582a6f6c00652f6a2b1ff71f8a78 ("mmc: sdhci-esdhc-imx: fix timeout on i.MX's sdhci") where more extensive tests would have shown that read or write of data to the card were failing (even if the partition table was correctly read). Signed-off-by: Eric Bénard Acked-by: Wolfram Sang Cc: stable Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-esdhc-imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6193a0d7bde5..8abdaf6697a8 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) clk_prepare_enable(clk); pltfm_host->clk = clk; - if (!is_imx25_esdhc(imx_data)) - host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ From e1631f989e0c6c8d9b43a2dbdd1097f70da603a5 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 18 Apr 2012 15:42:31 +0900 Subject: [PATCH 416/438] mmc: dw_mmc: prevent NULL dereference for dma_ops Now, dma_ops is assumed that use the IDMAC. But if dma_ops is assigned the pdata->dma_ops, we didn't ensure that callback function is defined. If the callback isn't defined, then we should run in PIO mode. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index f3b0fcd002df..ab3fc4617107 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1881,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host) if (!host->dma_ops) goto no_dma; - if (host->dma_ops->init) { + if (host->dma_ops->init && host->dma_ops->start && + host->dma_ops->stop && host->dma_ops->cleanup) { if (host->dma_ops->init(host)) { dev_err(&host->dev, "%s: Unable to initialize " "DMA Controller.\n", __func__); From 7c5709194096beea1ab6e6db46768d70a068efb0 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 19 Apr 2012 11:55:25 +0200 Subject: [PATCH 417/438] mmc: core: Do not pre-claim host in suspend Since SDIO drivers may want to do some SDIO operations in their suspend callback functions, we must not keep the host claimed when calling them. Daniel Drake reported that libertas_sdio encountered a deadlock in its suspend function. Signed-off-by: Ulf Hansson Tested-by: Daniel Drake [stable@: please apply to 3.2-stable and 3.3-stable] Cc: stable Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 55 +++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index e541efbf3256..ba821fe70bca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2238,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) mmc_card_is_removable(host)) return err; + mmc_claim_host(host); if (card && mmc_card_mmc(card) && (card->ext_csd.cache_size > 0)) { enable = !!enable; @@ -2255,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) card->ext_csd.cache_ctrl = enable; } } + mmc_release_host(host); return err; } @@ -2272,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host) cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); - if (mmc_try_claim_host(host)) { - err = mmc_cache_ctrl(host, 0); - mmc_release_host(host); - } else { - err = -EBUSY; - } + err = mmc_cache_ctrl(host, 0); if (err) goto out; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead) { - /* - * A long response time is not acceptable for device drivers - * when doing suspend. Prevent mmc_claim_host in the suspend - * sequence, to potentially wait "forever" by trying to - * pre-claim the host. - */ - if (mmc_try_claim_host(host)) { - if (host->bus_ops->suspend) { - err = host->bus_ops->suspend(host); - } - mmc_release_host(host); + if (host->bus_ops->suspend) + err = host->bus_ops->suspend(host); - if (err == -ENOSYS || !host->bus_ops->resume) { - /* - * We simply "remove" the card in this case. - * It will be redetected on resume. (Calling - * bus_ops->remove() with a claimed host can - * deadlock.) - */ - if (host->bus_ops->remove) - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); - mmc_release_host(host); - host->pm_flags = 0; - err = 0; - } - } else { - err = -EBUSY; + if (err == -ENOSYS || !host->bus_ops->resume) { + /* + * We simply "remove" the card in this case. + * It will be redetected on resume. (Calling + * bus_ops->remove() with a claimed host can + * deadlock.) + */ + if (host->bus_ops->remove) + host->bus_ops->remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + err = 0; } } mmc_bus_put(host); From 936af1576e4c24b466380fc2b8d93352161d13b0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Apr 2012 21:49:41 -0400 Subject: [PATCH 418/438] aio: don't bother with unmapping when aio_free_ring() is coming from exit_aio() ... since exit_mmap() is coming and it will munmap() everything anyway. In all other cases aio_free_ring() has ctx->mm == current->mm; moreover, all other callers of vm_munmap() have mm == current->mm, so this will allow us to get rid of mm argument of vm_munmap(). Signed-off-by: Al Viro --- fs/aio.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/aio.c b/fs/aio.c index 99bd790e8cd2..976e33d97413 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -92,8 +92,10 @@ static void aio_free_ring(struct kioctx *ctx) for (i=0; inr_pages; i++) put_page(info->ring_pages[i]); - if (info->mmap_size) + if (info->mmap_size) { + BUG_ON(ctx->mm != current->mm); vm_munmap(ctx->mm, info->mmap_base, info->mmap_size); + } if (info->ring_pages && info->ring_pages != info->internal_pages) kfree(info->ring_pages); @@ -386,6 +388,17 @@ void exit_aio(struct mm_struct *mm) "exit_aio:ioctx still alive: %d %d %d\n", atomic_read(&ctx->users), ctx->dead, ctx->reqs_active); + /* + * We don't need to bother with munmap() here - + * exit_mmap(mm) is coming and it'll unmap everything. + * Since aio_free_ring() uses non-zero ->mmap_size + * as indicator that it needs to unmap the area, + * just set it to 0; aio_free_ring() is the only + * place that uses ->mmap_size, so it's safe. + * That way we get all munmap done to current->mm - + * all other callers have ctx->mm == current->mm. + */ + ctx->ring_info.mmap_size = 0; put_ioctx(ctx); } } From 9f3a4afb276e4d8b3be7f3e678d4dbd11470416f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Apr 2012 21:53:35 -0400 Subject: [PATCH 419/438] perfmon: kill some helpers and arguments pfm_vm_munmap() is simply vm_munmap() and pfm_remove_smpl_mapping() always get current as the first argument. Signed-off-by: Al Viro --- arch/ia64/kernel/perfmon.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 2777310b698b..899c0fa5b498 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -604,12 +604,6 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) spin_unlock(&(x)->ctx_lock); } -static inline unsigned int -pfm_vm_munmap(struct mm_struct *mm, unsigned long addr, size_t len) -{ - return vm_munmap(mm, addr, len); -} - static inline unsigned long pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec) { @@ -1458,8 +1452,9 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) * a PROTECT_CTX() section. */ static int -pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size) +pfm_remove_smpl_mapping(void *vaddr, unsigned long size) { + struct task_struct *task = current; int r; /* sanity checks */ @@ -1473,7 +1468,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz /* * does the actual unmapping */ - r = pfm_vm_munmap(task->mm, (unsigned long)vaddr, size); + r = vm_munmap(current->mm, (unsigned long)vaddr, size); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); @@ -1940,7 +1935,7 @@ pfm_flush(struct file *filp, fl_owner_t id) * because some VM function reenables interrupts. * */ - if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size); + if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size); return 0; } From bfce281c287a427d0841fadf5d59242757b4e620 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Apr 2012 21:57:04 -0400 Subject: [PATCH 420/438] kill mm argument of vm_munmap() it's always current->mm Signed-off-by: Al Viro --- arch/ia64/kernel/perfmon.c | 2 +- arch/sparc/kernel/sys_sparc_64.c | 2 +- arch/x86/kvm/x86.c | 2 +- drivers/gpu/drm/i810/i810_dma.c | 3 +-- fs/aio.c | 2 +- include/linux/mm.h | 2 +- mm/mmap.c | 5 +++-- mm/nommu.c | 5 +++-- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 899c0fa5b498..f00ba025375d 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -1468,7 +1468,7 @@ pfm_remove_smpl_mapping(void *vaddr, unsigned long size) /* * does the actual unmapping */ - r = vm_munmap(current->mm, (unsigned long)vaddr, size); + r = vm_munmap((unsigned long)vaddr, size); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 022e57aadf5d..3ee51f189a55 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -569,7 +569,7 @@ SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) if (invalid_64bit_range(addr, len)) return -EINVAL; - return vm_munmap(current->mm, addr, len); + return vm_munmap(addr, len); } extern unsigned long do_mremap(unsigned long addr, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1457be305fb1..91a5e989abcf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6364,7 +6364,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (!user_alloc && !old.user_alloc && old.rmap && !npages) { int ret; - ret = vm_munmap(current->mm, old.userspace_addr, + ret = vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE); if (ret < 0) printk(KERN_WARNING diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index a4ba453b3d27..f920fb5e42b6 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -158,8 +158,7 @@ static int i810_unmap_buffer(struct drm_buf *buf) if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; - retcode = vm_munmap(current->mm, - (unsigned long)buf_priv->virtual, + retcode = vm_munmap((unsigned long)buf_priv->virtual, (size_t) buf->total); buf_priv->currently_mapped = I810_BUF_UNMAPPED; diff --git a/fs/aio.c b/fs/aio.c index 976e33d97413..67a6db3e1b6f 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -94,7 +94,7 @@ static void aio_free_ring(struct kioctx *ctx) if (info->mmap_size) { BUG_ON(ctx->mm != current->mm); - vm_munmap(ctx->mm, info->mmap_base, info->mmap_size); + vm_munmap(info->mmap_base, info->mmap_size); } if (info->ring_pages && info->ring_pages != info->internal_pages) diff --git a/include/linux/mm.h b/include/linux/mm.h index 86a692c3b238..74aa71bea1e4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1403,7 +1403,7 @@ extern int do_munmap(struct mm_struct *, unsigned long, size_t); /* These take the mm semaphore themselves */ extern unsigned long vm_brk(unsigned long, unsigned long); -extern int vm_munmap(struct mm_struct *, unsigned long, size_t); +extern int vm_munmap(unsigned long, size_t); extern unsigned long vm_mmap(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/mm/mmap.c b/mm/mmap.c index b38b47ef1f77..848ef52d9603 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2134,9 +2134,10 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) } EXPORT_SYMBOL(do_munmap); -int vm_munmap(struct mm_struct *mm, unsigned long start, size_t len) +int vm_munmap(unsigned long start, size_t len) { int ret; + struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); ret = do_munmap(mm, start, len); @@ -2148,7 +2149,7 @@ EXPORT_SYMBOL(vm_munmap); SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { profile_munmap(addr); - return vm_munmap(current->mm, addr, len); + return vm_munmap(addr, len); } static inline void verify_mm_writelocked(struct mm_struct *mm) diff --git a/mm/nommu.c b/mm/nommu.c index dd00383be2d9..bb8f4f004a82 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1734,8 +1734,9 @@ erase_whole_vma: } EXPORT_SYMBOL(do_munmap); -int vm_munmap(struct mm_struct *mm, unsigned long addr, size_t len) +int vm_munmap(unsigned long addr, size_t len) { + struct mm_struct *mm = current->mm; int ret; down_write(&mm->mmap_sem); @@ -1747,7 +1748,7 @@ EXPORT_SYMBOL(vm_munmap); SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { - return vm_munmap(current->mm, addr, len); + return vm_munmap(addr, len); } /* From c5a99937a9cf74a623384023201a7d98b51e7e3b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 18 Apr 2012 17:25:58 +0000 Subject: [PATCH 421/438] ks8851: Fix mutex deadlock in ks8851_net_stop() There is a potential deadlock scenario when the ks8851 driver is removed. The interrupt handler schedules a workqueue which acquires a mutex that ks8851_net_stop() also acquires before flushing the workqueue. Previously lockdep wouldn't be able to find this problem but now that it has the support we can trigger this lockdep warning by rmmoding the driver after an ifconfig up. Fix the possible deadlock by disabling the interrupts in the chip and then release the lock across the workqueue flushing. The mutex is only there to proect the registers anyway so this should be ok. ======================================================= [ INFO: possible circular locking dependency detected ] 3.0.21-00021-g8b33780-dirty #2911 ------------------------------------------------------- rmmod/125 is trying to acquire lock: ((&ks->irq_work)){+.+...}, at: [] flush_work+0x0/0xac but task is already holding lock: (&ks->lock){+.+...}, at: [] ks8851_net_stop+0x64/0x138 [ks8851] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&ks->lock){+.+...}: [] __lock_acquire+0x940/0x9f8 [] lock_acquire+0x10c/0x130 [] mutex_lock_nested+0x68/0x3dc [] ks8851_irq_work+0x24/0x46c [ks8851] [] process_one_work+0x2d8/0x518 [] worker_thread+0x220/0x3a0 [] kthread+0x88/0x94 [] kernel_thread_exit+0x0/0x8 -> #0 ((&ks->irq_work)){+.+...}: [] validate_chain+0x914/0x1018 [] __lock_acquire+0x940/0x9f8 [] lock_acquire+0x10c/0x130 [] flush_work+0x4c/0xac [] ks8851_net_stop+0x6c/0x138 [ks8851] [] __dev_close_many+0x98/0xcc [] dev_close_many+0x68/0xd0 [] rollback_registered_many+0xcc/0x2b8 [] rollback_registered+0x28/0x34 [] unregister_netdevice_queue+0x58/0x7c [] unregister_netdev+0x18/0x20 [] ks8851_remove+0x64/0xb4 [ks8851] [] spi_drv_remove+0x18/0x1c [] __device_release_driver+0x7c/0xbc [] driver_detach+0x8c/0xb4 [] bus_remove_driver+0xb8/0xe8 [] sys_delete_module+0x1e8/0x27c [] ret_fast_syscall+0x0/0x3c other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&ks->lock); lock((&ks->irq_work)); lock(&ks->lock); lock((&ks->irq_work)); *** DEADLOCK *** 4 locks held by rmmod/125: #0: (&__lockdep_no_validate__){+.+.+.}, at: [] driver_detach+0x6c/0xb4 #1: (&__lockdep_no_validate__){+.+.+.}, at: [] driver_detach+0x78/0xb4 #2: (rtnl_mutex){+.+.+.}, at: [] unregister_netdev+0xc/0x20 #3: (&ks->lock){+.+...}, at: [] ks8851_net_stop+0x64/0x138 [ks8851] Cc: Ben Dooks Signed-off-by: Stephen Boyd Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index e5dc0757f077..ad10759e3459 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev) netif_stop_queue(dev); mutex_lock(&ks->lock); + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); + mutex_unlock(&ks->lock); /* stop any outstanding work */ flush_work(&ks->irq_work); flush_work(&ks->tx_work); flush_work(&ks->rxctrl_work); - /* turn off the IRQs and ack any outstanding */ - ks8851_wrreg16(ks, KS_IER, 0x0000); - ks8851_wrreg16(ks, KS_ISR, 0xffff); - + mutex_lock(&ks->lock); /* shutdown RX process */ ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev) /* set powermode to soft power down to save power */ ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); + mutex_unlock(&ks->lock); /* ensure any queued tx buffers are dumped */ while (!skb_queue_empty(&ks->txq)) { @@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev) dev_kfree_skb(txb); } - mutex_unlock(&ks->lock); return 0; } From 792df87228965c58c307877af00498641584bd47 Mon Sep 17 00:00:00 2001 From: Wenqi Ma Date: Thu, 19 Apr 2012 00:39:37 +0000 Subject: [PATCH 422/438] net/hyperv: Adding cancellation to ensure rndis filter is closed Although the network interface is down, the RX packets number which could be observed by ifconfig may keep on increasing. This is because the WORK scheduled in netvsc_set_multicast_list() may be executed after netvsc_close(). That means the rndis filter may be re-enabled by do_set_multicast() even if it was closed by netvsc_close(). By canceling possible WORK before close the rndis filter, the issue could be never happened. Signed-off-by: Wenqi Ma Reviewed-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 38 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index dd294783b5c5..2d59138db7f3 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -44,6 +44,7 @@ struct net_device_context { /* point back to our device context */ struct hv_device *device_ctx; struct delayed_work dwork; + struct work_struct work; }; @@ -51,30 +52,22 @@ static int ring_size = 128; module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); -struct set_multicast_work { - struct work_struct work; - struct net_device *net; -}; - static void do_set_multicast(struct work_struct *w) { - struct set_multicast_work *swk = - container_of(w, struct set_multicast_work, work); - struct net_device *net = swk->net; - - struct net_device_context *ndevctx = netdev_priv(net); + struct net_device_context *ndevctx = + container_of(w, struct net_device_context, work); struct netvsc_device *nvdev; struct rndis_device *rdev; nvdev = hv_get_drvdata(ndevctx->device_ctx); - if (nvdev == NULL) - goto out; + if (nvdev == NULL || nvdev->ndev == NULL) + return; rdev = nvdev->extension; if (rdev == NULL) - goto out; + return; - if (net->flags & IFF_PROMISC) + if (nvdev->ndev->flags & IFF_PROMISC) rndis_filter_set_packet_filter(rdev, NDIS_PACKET_TYPE_PROMISCUOUS); else @@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w) NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); - -out: - kfree(w); } static void netvsc_set_multicast_list(struct net_device *net) { - struct set_multicast_work *swk = - kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); - if (swk == NULL) - return; + struct net_device_context *net_device_ctx = netdev_priv(net); - swk->net = net; - INIT_WORK(&swk->work, do_set_multicast); - schedule_work(&swk->work); + schedule_work(&net_device_ctx->work); } static int netvsc_open(struct net_device *net) @@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net) netif_tx_disable(net); + /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ + cancel_work_sync(&net_device_ctx->work); ret = rndis_filter_close(device_obj); if (ret != 0) netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) nvdev->start_remove = true; cancel_delayed_work_sync(&ndevctx->dwork); + cancel_work_sync(&ndevctx->work); netif_tx_disable(ndev); rndis_filter_device_remove(hdev); @@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev, net_device_ctx->device_ctx = dev; hv_set_drvdata(dev, net); INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); + INIT_WORK(&net_device_ctx->work, do_set_multicast); net->netdev_ops = &device_ops; @@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev) ndev_ctx = netdev_priv(net); cancel_delayed_work_sync(&ndev_ctx->dwork); + cancel_work_sync(&ndev_ctx->work); /* Stop outbound asap */ netif_tx_disable(net); From e8195b24feb208f6e944e7542779f4397776794d Mon Sep 17 00:00:00 2001 From: Matt Renzelmann Date: Thu, 19 Apr 2012 07:17:17 +0000 Subject: [PATCH 423/438] ks8851: Fix request_irq/free_irq mismatch The dev_id parameter passed to free_irq needs to match the one passed to the corresponding request_irq. Signed-off-by: Matt Renzelmann Acked-by: Stephen Boyd Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index ad10759e3459..f8dda009d3c0 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1525,7 +1525,7 @@ static int __devinit ks8851_probe(struct spi_device *spi) err_netdev: - free_irq(ndev->irq, ndev); + free_irq(ndev->irq, ks); err_id: err_irq: From bbe362be5368b9f531b95a4a9b502ae2832e1dac Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 Apr 2012 07:16:21 +0000 Subject: [PATCH 424/438] drop_monitor: allow more events per second It seems there is a logic error in trace_drop_common(), since we store only 64 drops, even if they are from same location. This fix is a one liner, but we probably need more work to avoid useless atomic dec/inc Now I can watch 1 Mpps drops through dropwatch... Signed-off-by: Eric Dumazet Cc: Neil Horman Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/core/drop_monitor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 7f36b38e060f..5c3c81a609e5 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -150,6 +150,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) for (i = 0; i < msg->entries; i++) { if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { msg->points[i].count++; + atomic_inc(&data->dm_hit_count); goto out; } } From e9a5ea1852cd8d7e155d2e3a45e4a6ea25110f7d Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Thu, 19 Apr 2012 20:28:32 +0000 Subject: [PATCH 425/438] sparc32,leon: add notify_cpu_starting() Otherwise cpu_active_mask will not set, which lead to other issue. Signed-off-by: Yong Zhang Signed-off-by: Konrad Eisele Reviewed-by: Srivatsa S. Bhat Signed-off-by: David S. Miller --- arch/sparc/kernel/leon_smp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 1210fde18740..160cac9c4036 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,8 @@ void __cpuinit leon_callin(void) local_flush_tlb_all(); leon_configure_cache_smp(); + notify_cpu_starting(cpuid); + /* Get our local ticker going. */ smp_setup_percpu_timer(); From 163faf31778e536ac6125bc8b14f4667adc910e9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 19 Apr 2012 10:36:33 +0000 Subject: [PATCH 426/438] drivers/net: Do not free an IRQ if its request failed Refrain from attempting to free an interrupt line if the request fails and hence, there is no IRQ to free. CC: netdev@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 5aa2dbe2bfb5..cd3defb11ffb 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2378,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) SET_NETDEV_DEV(dev, &pdev->dev); pdata = netdev_priv(dev); - dev->irq = irq_res->start; irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2442,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (retval) { SMSC_WARN(pdata, probe, "Unable to claim requested irq: %d", dev->irq); - goto out_free_irq; + goto out_disable_resources; } retval = register_netdev(dev); From 66f75a5d028beaf67c931435fdc3e7823125730c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 21 Apr 2012 14:47:52 -0700 Subject: [PATCH 427/438] Linux 3.4-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f6578f47e21e..afc868e6c75d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Saber-toothed Squirrel # *DOCUMENTATION* From d135c522f1234f62e81be29cebdf59e9955139ad Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Sun, 22 Apr 2012 09:45:47 +0000 Subject: [PATCH 428/438] tcp: fix TCP_MAXSEG for established IPv6 passive sockets Commit f5fff5d forgot to fix TCP_MAXSEG behavior IPv6 sockets, so IPv6 TCP server sockets that used TCP_MAXSEG would find that the advmss of child sockets would be incorrect. This commit mirrors the advmss logic from tcp_v4_syn_recv_sock in tcp_v6_syn_recv_sock. Eventually this logic should probably be shared between IPv4 and IPv6, but this at least fixes this issue. Signed-off-by: Neal Cardwell Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 86cfe6005f40..98256cf72f9d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1383,6 +1383,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); newtp->advmss = dst_metric_advmss(dst); + if (tcp_sk(sk)->rx_opt.user_mss && + tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) + newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; + tcp_initialize_rcv_mss(newsk); if (tcp_rsk(req)->snt_synack) tcp_valid_rtt_meas(newsk, From 2ef822c55371b20548d4f58193c580407a5d738d Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Mon, 16 Apr 2012 19:55:39 +0000 Subject: [PATCH 429/438] powerpc/eeh: Fix crash caused by null eeh_dev The problem was reported by Anton Blanchard. While EEH error happened to the PCI device without the corresponding device driver, kernel crash was seen. Eventually, I successfully reproduced the problem on Firebird-L machine with utility "errinjct". Initially, the device driver for Emulex ethernet MAC has been disabled from .config and force data parity on the Emulex ethernet MAC with help of "errinjct". Eventually, I saw the kernel crash after issueing couple of "lspci -v" command. The root cause behind is that the PCI device, including the reference to the corresponding eeh device, will be removed from the system while EEH does recovery. Afterwards, the PCI device will be probed again and added into the system accordingly. So it's not safe to retrieve the eeh device from the corresponding PCI device after the PCI device has been removed and not added again. The patch fixes the issue and retrieve the eeh device from OF node instead of PCI device after the PCI device has been removed. Signed-off-by: Gavin Shan Tested-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/eeh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 309d38ef7322..a75e37dc41aa 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -1076,7 +1076,7 @@ static void eeh_add_device_late(struct pci_dev *dev) pr_debug("EEH: Adding device %s\n", pci_name(dev)); dn = pci_device_to_OF_node(dev); - edev = pci_dev_to_eeh_dev(dev); + edev = of_node_to_eeh_dev(dn); if (edev->pdev == dev) { pr_debug("EEH: Already referenced !\n"); return; From 3027691e58bfb21f6ea2e9f1d225d11b4e2b20e2 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 18 Apr 2012 22:16:48 +0000 Subject: [PATCH 430/438] powerpc/pmac: Don't add_timer() twice If the interrupt and the timeout happen roughly at the same time, we can get into a situation where the timer function is run while the interrupt has already been processed. In this case, the timer function might end up doing an add_timer on an already pending timer, causing a BUG_ON() to trigger. Instead, just skip the whole timeout operation if we see that the timer is pending. The spinlock ensures that the only way that happens is if we already started a new operation and thus the timeout can be ignored. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powermac/low_i2c.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 996c5ff7824b..03685a329d7d 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -366,11 +366,20 @@ static void kw_i2c_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(&host->lock, flags); + + /* + * If the timer is pending, that means we raced with the + * irq, in which case we just return + */ + if (timer_pending(&host->timeout_timer)) + goto skip; + kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); if (host->state != state_idle) { host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; add_timer(&host->timeout_timer); } + skip: spin_unlock_irqrestore(&host->lock, flags); } From 3a2b4f7c355ff1c97e4adebadf0a1aefd7c4518a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 19 Apr 2012 17:29:34 +0000 Subject: [PATCH 431/438] powerpc/mpic: Fix confusion between hw_irq and virq mpic_is_ipi() takes a virq and immediately converts it to a hw_irq. However, one of the two call sites calls it with a ... hw_irq. The other call site also happens to have the hw_irq at hand, so let's change it to just take that as an argument. Also change mpic_is_tm() for consistency. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/mpic.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9ac71ebd2c40..665b0f806786 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq) } /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]); } /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src) { - unsigned int src = virq_to_hw(irq); - return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]); } @@ -1555,12 +1551,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) return; raw_spin_lock_irqsave(&mpic_lock, flags); - if (mpic_is_ipi(mpic, irq)) { + if (mpic_is_ipi(mpic, src)) { reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_ipi_write(src - mpic->ipi_vecs[0], reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); - } else if (mpic_is_tm(mpic, irq)) { + } else if (mpic_is_tm(mpic, src)) { reg = mpic_tm_read(src - mpic->timer_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_tm_write(src - mpic->timer_vecs[0], From 3fca40c704dd013797f2c0c518f37cd2cc8e19fe Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 19 Apr 2012 17:29:42 +0000 Subject: [PATCH 432/438] irq: Add IRQ_TYPE_DEFAULT for use by PIC drivers This is meant typically to allow a PIC driver's irq domain map() callback to establish sane defaults for the interrupt (and make sure that the HW and the irq_desc are in sync as far as the trigger is concerned). The irq core may not call the set_trigger callback if it thinks the trigger is already set to the right setting, so we need to ensure new descriptors are properly synchronized with the hardware. Signed-off-by: Benjamin Herrenschmidt --- include/linux/irq.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index 7810406f3d80..b27cfcfd3a59 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -49,6 +49,12 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_TYPE_LEVEL_LOW - low level triggered * IRQ_TYPE_LEVEL_MASK - Mask to filter out the level bits * IRQ_TYPE_SENSE_MASK - Mask for all the above bits + * IRQ_TYPE_DEFAULT - For use by some PICs to ask irq_set_type + * to setup the HW to a sane default (used + * by irqdomain map() callbacks to synchronize + * the HW state and SW flags for a newly + * allocated descriptor). + * * IRQ_TYPE_PROBE - Special flag for probing in progress * * Bits which can be modified via irq_set/clear/modify_status_flags() @@ -77,6 +83,7 @@ enum { IRQ_TYPE_LEVEL_LOW = 0x00000008, IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), IRQ_TYPE_SENSE_MASK = 0x0000000f, + IRQ_TYPE_DEFAULT = IRQ_TYPE_SENSE_MASK, IRQ_TYPE_PROBE = 0x00000010, From 446f6d06fab0b49c61887ecbe8286d6aaa796637 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 19 Apr 2012 17:30:57 +0000 Subject: [PATCH 433/438] powerpc/mpic: Properly set default triggers This gets rid of the unused default senses array, and replaces the incorrect use of IRQ_TYPE_NONE with the new IRQ_TYPE_DEFAULT for the initial set_trigger() call when mapping an interrupt. This in turn makes us read the HW state and update the irq desc accordingly. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/mpic.h | 18 -------------- arch/powerpc/sysdev/mpic.c | 44 +++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index c65b9294376e..c9f698a994be 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -275,9 +275,6 @@ struct mpic unsigned int isu_mask; /* Number of sources */ unsigned int num_sources; - /* default senses array */ - unsigned char *senses; - unsigned int senses_count; /* vector numbers used for internal sources (ipi/timers) */ unsigned int ipi_vecs[4]; @@ -415,21 +412,6 @@ extern struct mpic *mpic_alloc(struct device_node *node, extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, phys_addr_t phys_addr); -/* Set default sense codes - * - * @mpic: controller - * @senses: array of sense codes - * @count: size of above array - * - * Optionally provide an array (indexed on hardware interrupt numbers - * for this MPIC) of default sense codes for the chip. Those are linux - * sense codes IRQ_TYPE_* - * - * The driver gets ownership of the pointer, don't dispose of it or - * anything like that. __init only. - */ -extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count); - /* Initialize the controller. After this has been called, none of the above * should be called again for this mpic diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 665b0f806786..395af1347749 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -872,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (src >= mpic->num_sources) return -EINVAL; - if (flow_type == IRQ_TYPE_NONE) - if (mpic->senses && src < mpic->senses_count) - flow_type = mpic->senses[src]; - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + /* We don't support "none" type */ + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_DEFAULT; + + /* Default: read HW settings */ + if (flow_type == IRQ_TYPE_DEFAULT) { + switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) | + MPIC_INFO(VECPRI_SENSE_MASK))) { + case MPIC_INFO(VECPRI_SENSE_EDGE) | + MPIC_INFO(VECPRI_POLARITY_POSITIVE): + flow_type = IRQ_TYPE_EDGE_RISING; + break; + case MPIC_INFO(VECPRI_SENSE_EDGE) | + MPIC_INFO(VECPRI_POLARITY_NEGATIVE): + flow_type = IRQ_TYPE_EDGE_FALLING; + break; + case MPIC_INFO(VECPRI_SENSE_LEVEL) | + MPIC_INFO(VECPRI_POLARITY_POSITIVE): + flow_type = IRQ_TYPE_LEVEL_HIGH; + break; + case MPIC_INFO(VECPRI_SENSE_LEVEL) | + MPIC_INFO(VECPRI_POLARITY_NEGATIVE): + flow_type = IRQ_TYPE_LEVEL_LOW; + break; + } + } + + /* Apply to irq desc */ irqd_set_trigger_type(d, flow_type); + /* Apply to HW */ if (mpic_is_ht_interrupt(mpic, src)) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | MPIC_VECPRI_SENSE_EDGE; else vecpri = mpic_type_to_vecpri(mpic, flow_type); - vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | MPIC_INFO(VECPRI_SENSE_MASK)); vnew |= vecpri; @@ -1022,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_NONE); + irq_set_irq_type(virq, IRQ_TYPE_DEFAULT); /* If the MPIC was reset, then all vectors have already been * initialized. Otherwise, a per source lazy initialization @@ -1413,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, mpic->num_sources = isu_first + mpic->isu_size; } -void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) -{ - mpic->senses = senses; - mpic->senses_count = count; -} - void __init mpic_init(struct mpic *mpic) { int i, cpu; From 53ad1c980d4fb450722a575ca17c188808939340 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 4 Apr 2012 09:49:15 -0500 Subject: [PATCH 434/438] dlm: fix QUECVT when convert queue is empty The QUECVT flag should not prevent conversions from being granted immediately when the convert queue is empty. Signed-off-by: David Teigland --- fs/dlm/lock.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index fa5c07d51dcc..4c58d4a3adc4 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1736,6 +1736,18 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT)) return 1; + /* + * Even if the convert is compat with all granted locks, + * QUECVT forces it behind other locks on the convert queue. + */ + + if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) { + if (list_empty(&r->res_convertqueue)) + return 1; + else + goto out; + } + /* * The NOORDER flag is set to avoid the standard vms rules on grant * order. From a9ad8526bb1af0741a5c0e01155dac08e7bdde60 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Tue, 24 Apr 2012 10:23:13 +1000 Subject: [PATCH 435/438] DM RAID: Use safe version of rdev_for_each Fix segfault caused by using rdev_for_each instead of rdev_for_each_safe Commit dafb20fa34320a472deb7442f25a0c086e0feb33 mistakenly replaced a safe iterator with an unsafe one when making some macro changes. Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/dm-raid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index b0ba52459ed7..68965e663248 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) int ret; unsigned redundancy = 0; struct raid_dev *dev; - struct md_rdev *rdev, *freshest; + struct md_rdev *rdev, *tmp, *freshest; struct mddev *mddev = &rs->md; switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) } freshest = NULL; - rdev_for_each(rdev, mddev) { + rdev_for_each_safe(rdev, tmp, mddev) { if (!rdev->meta_bdev) continue; From ed209584c38fb74b7eecc03e5b1bfe674e591bd8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 24 Apr 2012 10:23:14 +1000 Subject: [PATCH 436/438] md: don't call ->add_disk unless there is good reason. Commit 7bfec5f35c68121e7b18 md/raid5: If there is a spare and a want_replacement device, start replacement. cause md_check_recovery to call ->add_disk much more often. Instead of only when the array is degraded, it is now called whenever md_check_recovery finds anything useful to do, which includes updating the metadata for clean<->dirty transition. This causes unnecessary work, and causes info messages from ->add_disk to be reported much too often. So refine md_check_recovery to only do any actual recovery checking (including ->add_disk) if MD_RECOVERY_NEEDED is set. This fix is suitable for 3.3.y: Cc: stable@vger.kernel.org Reported-by: Jan Ceuleers Signed-off-by: NeilBrown --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index b572e1e386ce..8beb19c3bb44 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev) * any transients in the value of "sync_action". */ set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); /* Clear some bits that don't mean anything, but * might be left set */ clear_bit(MD_RECOVERY_INTR, &mddev->recovery); clear_bit(MD_RECOVERY_DONE, &mddev->recovery); - if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) + if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || + test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) goto unlock; /* no recovery is running. * remove any failed drives, then From 30b8aa9172dfeaac6d77897c67ee9f9fc574cdbb Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 24 Apr 2012 10:23:16 +1000 Subject: [PATCH 437/438] md: fix possible corruption of array metadata on shutdown. commit c744a65c1e2d59acc54333ce8 md: don't set md arrays to readonly on shutdown. removed the possibility of a 'BUG' when data is written to an array that has just been switched to read-only, but also introduced the possibility that the array metadata could be corrupted. If, when md_notify_reboot gets the mddev lock, the array is in a state where it is assembled but hasn't been started (as can happen if the personality module is not available, or in other unusual situations), then incorrect metadata will be written out making it impossible to re-assemble the array. So only call __md_stop_writes() if the array has actually been activated. This patch is needed for any stable kernel which has had the above commit applied. Cc: stable@vger.kernel.org Reported-by: Christoph Nelles Signed-off-by: NeilBrown --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 8beb19c3bb44..477eb2e180c0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this, for_each_mddev(mddev, tmp) { if (mddev_trylock(mddev)) { - __md_stop_writes(mddev); + if (mddev->pers) + __md_stop_writes(mddev); mddev->safemode = 2; mddev_unlock(mddev); } From aca50bd3b4c4bb5528a1878158ba7abce41de534 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 23 Apr 2012 11:14:50 -0700 Subject: [PATCH 438/438] mm: fix s390 BUG by __set_page_dirty_no_writeback on swap Mel reports a BUG_ON(slot == NULL) in radix_tree_tag_set() on s390 3.0.13: called from __set_page_dirty_nobuffers() when page_remove_rmap() tries to transfer dirty flag from s390 storage key to struct page and radix_tree. That would be because of reclaim's shrink_page_list() calling add_to_swap() on this page at the same time: first PageSwapCache is set (causing page_mapping(page) to appear as &swapper_space), then page->private set, then tree_lock taken, then page inserted into radix_tree - so there's an interval before taking the lock when the radix_tree slot is empty. We could fix this by moving __add_to_swap_cache()'s spin_lock_irq up before the SetPageSwapCache. But a better fix is simply to do what's five years overdue: Ken Chen introduced __set_page_dirty_no_writeback() (if !PageDirty TestSetPageDirty) for tmpfs to skip all the radix_tree overhead, and swap is just the same - it ignores the radix_tree tag, and does not participate in dirty page accounting, so should be using __set_page_dirty_no_writeback() too. s390 testing now confirms that this does indeed fix the problem. Reported-by: Mel Gorman Signed-off-by: Hugh Dickins Acked-by: Mel Gorman Cc: Andrew Morton Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Rik van Riel Cc: Ken Chen Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds --- mm/swap_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/swap_state.c b/mm/swap_state.c index 9d3dd3763cf7..4c5ff7f284d9 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -26,7 +26,7 @@ */ static const struct address_space_operations swap_aops = { .writepage = swap_writepage, - .set_page_dirty = __set_page_dirty_nobuffers, + .set_page_dirty = __set_page_dirty_no_writeback, .migratepage = migrate_page, };