From e3cc067b0a79d3a3672bfe7cfba12f2e8ae56039 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 18 Sep 2009 16:31:22 -0700 Subject: xen/evtchn: track enabled state for each port enable/disable_irq() complain if the enables/disables are unbalanced, so keep track of the state and avoid redundant enables. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 71 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index af031950f9b..4356a9a030d 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -69,10 +69,36 @@ struct per_user_data { const char *name; }; -/* Who's bound to each port? */ -static struct per_user_data *port_user[NR_EVENT_CHANNELS]; +/* + * Who's bound to each port? This is logically an array of struct + * per_user_data *, but we encode the current enabled-state in bit 0. + */ +static unsigned long port_user[NR_EVENT_CHANNELS]; static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */ +static inline struct per_user_data *get_port_user(unsigned port) +{ + return (struct per_user_data *)(port_user[port] & ~1); +} + +static inline void set_port_user(unsigned port, struct per_user_data *u) +{ + port_user[port] = (unsigned long)u; +} + +static inline bool get_port_enabled(unsigned port) +{ + return port_user[port] & 1; +} + +static inline void set_port_enabled(unsigned port, bool enabled) +{ + if (enabled) + port_user[port] |= 1; + else + port_user[port] &= ~1; +} + irqreturn_t evtchn_interrupt(int irq, void *data) { unsigned int port = (unsigned long)data; @@ -80,9 +106,15 @@ irqreturn_t evtchn_interrupt(int irq, void *data) spin_lock(&port_user_lock); - u = port_user[port]; + u = get_port_user(port); + + if (WARN(!get_port_enabled(port), + "Interrupt for port %d, but apparently not enabled; per-user %p\n", + port, u)) + goto out; disable_irq_nosync(irq); + set_port_enabled(port, false); if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port; @@ -92,10 +124,10 @@ irqreturn_t evtchn_interrupt(int irq, void *data) kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN); } - } else { + } else u->ring_overflow = 1; - } +out: spin_unlock(&port_user_lock); return IRQ_HANDLED; @@ -198,9 +230,18 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf, goto out; spin_lock_irq(&port_user_lock); - for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) - if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u)) - enable_irq(irq_from_evtchn(kbuf[i])); + + for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) { + unsigned port = kbuf[i]; + + if (port < NR_EVENT_CHANNELS && + get_port_user(port) == u && + !get_port_enabled(port)) { + set_port_enabled(port, true); + enable_irq(irq_from_evtchn(port)); + } + } + spin_unlock_irq(&port_user_lock); rc = count; @@ -222,8 +263,8 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port) * interrupt handler yet, and our caller has already * serialized bind operations.) */ - BUG_ON(port_user[port] != NULL); - port_user[port] = u; + BUG_ON(get_port_user(port) != NULL); + set_port_user(port, u); rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED, u->name, (void *)(unsigned long)port); @@ -242,7 +283,7 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port) /* make sure we unbind the irq handler before clearing the port */ barrier(); - port_user[port] = NULL; + set_port_user(port, NULL); } static long evtchn_ioctl(struct file *file, @@ -333,7 +374,7 @@ static long evtchn_ioctl(struct file *file, spin_lock_irq(&port_user_lock); rc = -ENOTCONN; - if (port_user[unbind.port] != u) { + if (get_port_user(unbind.port) != u) { spin_unlock_irq(&port_user_lock); break; } @@ -355,7 +396,7 @@ static long evtchn_ioctl(struct file *file, if (notify.port >= NR_EVENT_CHANNELS) { rc = -EINVAL; - } else if (port_user[notify.port] != u) { + } else if (get_port_user(notify.port) != u) { rc = -ENOTCONN; } else { notify_remote_via_evtchn(notify.port); @@ -444,10 +485,10 @@ static int evtchn_release(struct inode *inode, struct file *filp) free_page((unsigned long)u->ring); for (i = 0; i < NR_EVENT_CHANNELS; i++) { - if (port_user[i] != u) + if (get_port_user(i) != u) continue; - evtchn_unbind_from_user(port_user[i], i); + evtchn_unbind_from_user(get_port_user(i), i); } spin_unlock_irq(&port_user_lock); -- cgit v1.2.3-70-g09d2 From 93afe0b75ef3675ca05320919a57de8b9bbb159c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 18 Sep 2009 16:36:58 -0700 Subject: xen/evtchn: dynamically allocate port_user array We only need the array when running as a Xen domain, so dynamically allocate it as needed to save on bss space. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 4356a9a030d..709c32d949b 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -73,7 +73,7 @@ struct per_user_data { * Who's bound to each port? This is logically an array of struct * per_user_data *, but we encode the current enabled-state in bit 0. */ -static unsigned long port_user[NR_EVENT_CHANNELS]; +static unsigned long *port_user; static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */ static inline struct per_user_data *get_port_user(unsigned port) @@ -522,8 +522,11 @@ static int __init evtchn_init(void) if (!xen_domain()) return -ENODEV; + port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL); + if (port_user == NULL) + return -ENOMEM; + spin_lock_init(&port_user_lock); - memset(port_user, 0, sizeof(port_user)); /* Create '/dev/misc/evtchn'. */ err = misc_register(&evtchn_miscdev); @@ -539,6 +542,9 @@ static int __init evtchn_init(void) static void __exit evtchn_cleanup(void) { + kfree(port_user); + port_user = NULL; + misc_deregister(&evtchn_miscdev); } -- cgit v1.2.3-70-g09d2 From 0edce91dcd83160019867a00746c679344dc0bbd Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 18 Sep 2009 16:55:29 -0700 Subject: xen/evtchn: ports start enabled Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 709c32d949b..72dc7f20c5e 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -108,10 +108,9 @@ irqreturn_t evtchn_interrupt(int irq, void *data) u = get_port_user(port); - if (WARN(!get_port_enabled(port), - "Interrupt for port %d, but apparently not enabled; per-user %p\n", - port, u)) - goto out; + WARN(!get_port_enabled(port), + "Interrupt for port %d, but apparently not enabled; per-user %p\n", + port, u); disable_irq_nosync(irq); set_port_enabled(port, false); @@ -127,7 +126,6 @@ irqreturn_t evtchn_interrupt(int irq, void *data) } else u->ring_overflow = 1; -out: spin_unlock(&port_user_lock); return IRQ_HANDLED; @@ -265,6 +263,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port) */ BUG_ON(get_port_user(port) != NULL); set_port_user(port, u); + set_port_enabled(port, true); /* start enabled */ rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED, u->name, (void *)(unsigned long)port); -- cgit v1.2.3-70-g09d2 From 1a1a17cddbfb1f81222b3f18ee8530c41fbc3b82 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 18 Sep 2009 17:13:41 -0700 Subject: xen/evtchn: remove spurious barrier evtchn_unbind_from_user() is called under a lock, so there's no need to worry about the ordering of unbind_from_irqhandler vs clearing the port per-user data. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 72dc7f20c5e..f79ac5ca379 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -279,9 +279,6 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port) unbind_from_irqhandler(irq, (void *)(unsigned long)port); - /* make sure we unbind the irq handler before clearing the port */ - barrier(); - set_port_user(port, NULL); } -- cgit v1.2.3-70-g09d2 From 3f5e554f669098c84c82ce75e7577f7e0f3fccde Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 28 May 2010 15:28:27 -0700 Subject: xen/evtchn: don't do unbind_from_irqhandler under spinlock unbind_from_irqhandler can end up doing /proc operations, which can't happen under a spinlock. So before removing the IRQ handler, disable the irq under the port_user lock (masking the underlying event channel and making sure the irq handler isn't running concurrently and won't start running), then remove the handler without the lock. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index f79ac5ca379..6a3a12945d0 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -375,10 +375,12 @@ static long evtchn_ioctl(struct file *file, break; } - evtchn_unbind_from_user(u, unbind.port); + disable_irq(irq_from_evtchn(unbind.port)); spin_unlock_irq(&port_user_lock); + evtchn_unbind_from_user(u, unbind.port); + rc = 0; break; } @@ -484,11 +486,18 @@ static int evtchn_release(struct inode *inode, struct file *filp) if (get_port_user(i) != u) continue; - evtchn_unbind_from_user(get_port_user(i), i); + disable_irq(irq_from_evtchn(i)); } spin_unlock_irq(&port_user_lock); + for (i = 0; i < NR_EVENT_CHANNELS; i++) { + if (get_port_user(i) != u) + continue; + + evtchn_unbind_from_user(get_port_user(i), i); + } + kfree(u->name); kfree(u); -- cgit v1.2.3-70-g09d2 From 376d908f52427591cef4acd172db9c3ef28676ec Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 May 2010 15:43:49 -0700 Subject: xen/evtchn: Fix name of Xen event-channel device The Xen event-channel device is named evtchn in the kernel but always used as /dev/xen/evtchn in userspace. This patch fixes the name. Signed-off-by: Bastian Blank Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 6a3a12945d0..68119f6324d 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -517,7 +517,7 @@ static const struct file_operations evtchn_fops = { static struct miscdevice evtchn_miscdev = { .minor = MISC_DYNAMIC_MINOR, - .name = "evtchn", + .name = "xen/evtchn", .fops = &evtchn_fops, }; static int __init evtchn_init(void) -- cgit v1.2.3-70-g09d2 From 70697d540c0598ad023a391d4c895044db9a6624 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 5 Oct 2010 11:13:44 -0700 Subject: xen/evtchn: add missing static Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 68119f6324d..f3594ec2ee3 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -99,7 +99,7 @@ static inline void set_port_enabled(unsigned port, bool enabled) port_user[port] &= ~1; } -irqreturn_t evtchn_interrupt(int irq, void *data) +static irqreturn_t evtchn_interrupt(int irq, void *data) { unsigned int port = (unsigned long)data; struct per_user_data *u; -- cgit v1.2.3-70-g09d2 From 313e74412105c670ff8900ec8099a3a5df1fa83c Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Thu, 28 Oct 2010 15:39:02 +0400 Subject: xen: xenfs: privcmd: check put_user() return code put_user() may fail. In this case propagate error code from privcmd_ioctl_mmap_batch(). Signed-off-by: Vasiliy Kulikov Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/privcmd.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xenfs/privcmd.c b/drivers/xen/xenfs/privcmd.c index f80be7f6eb9..2eb04c84251 100644 --- a/drivers/xen/xenfs/privcmd.c +++ b/drivers/xen/xenfs/privcmd.c @@ -266,9 +266,7 @@ static int mmap_return_errors(void *data, void *state) xen_pfn_t *mfnp = data; struct mmap_batch_state *st = state; - put_user(*mfnp, st->user++); - - return 0; + return put_user(*mfnp, st->user++); } static struct vm_operations_struct privcmd_vm_ops; @@ -323,10 +321,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata) up_write(&mm->mmap_sem); if (state.err > 0) { - ret = 0; - state.user = m.arr; - traverse_pages(m.num, sizeof(xen_pfn_t), + ret = traverse_pages(m.num, sizeof(xen_pfn_t), &pagelist, mmap_return_errors, &state); } -- cgit v1.2.3-70-g09d2 From c64e38ea17a81721da0393584fd807f8434050fa Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 1 Nov 2010 14:32:27 -0400 Subject: xen/blkfront: map REQ_FLUSH into a full barrier Implement a flush as a full barrier, since we have nothing weaker. Signed-off-by: Jeremy Fitzhardinge Acked-by: Christoph Hellwig --- drivers/block/xen-blkfront.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 06e2812ba12..3a318d8576c 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -245,14 +245,11 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode, } /* - * blkif_queue_request + * Generate a Xen blkfront IO request from a blk layer request. Reads + * and writes are handled as expected. Since we lack a loose flush + * request, we map flushes into a full ordered barrier. * - * request block io - * - * id: for guest use only. - * operation: BLKIF_OP_{READ,WRITE,PROBE} - * buffer: buffer to read/write into. this should be a - * virtual address in the guest os. + * @req: a request struct */ static int blkif_queue_request(struct request *req) { @@ -289,7 +286,7 @@ static int blkif_queue_request(struct request *req) ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; - if (req->cmd_flags & REQ_HARDBARRIER) + if (req->cmd_flags & REQ_FLUSH) ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); @@ -1069,14 +1066,8 @@ static void blkfront_connect(struct blkfront_info *info) */ info->feature_flush = 0; - /* - * The driver doesn't properly handled empty flushes, so - * lets disable barrier support for now. - */ -#if 0 if (!err && barrier) info->feature_flush = REQ_FLUSH; -#endif err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); if (err) { -- cgit v1.2.3-70-g09d2 From a945b9801a9bfd4a98bcfd9f6656b5027b254e3f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 1 Nov 2010 17:03:14 -0400 Subject: xen/blkfront: change blk_shadow.request to proper pointer Signed-off-by: Jeremy Fitzhardinge --- drivers/block/xen-blkfront.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 3a318d8576c..31c8a643d10 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -65,7 +65,7 @@ enum blkif_state { struct blk_shadow { struct blkif_request req; - unsigned long request; + struct request *request; unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; }; @@ -136,7 +136,7 @@ static void add_id_to_freelist(struct blkfront_info *info, unsigned long id) { info->shadow[id].req.id = info->shadow_free; - info->shadow[id].request = 0; + info->shadow[id].request = NULL; info->shadow_free = id; } @@ -278,7 +278,7 @@ static int blkif_queue_request(struct request *req) /* Fill out a communications ring structure. */ ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt); id = get_id_from_freelist(info); - info->shadow[id].request = (unsigned long)req; + info->shadow[id].request = req; ring_req->id = id; ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req); @@ -633,7 +633,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; - req = (struct request *)info->shadow[id].request; + req = info->shadow[id].request; blkif_completion(&info->shadow[id]); @@ -898,7 +898,7 @@ static int blkif_recover(struct blkfront_info *info) /* Stage 3: Find pending requests and requeue them. */ for (i = 0; i < BLK_RING_SIZE; i++) { /* Not in use? */ - if (copy[i].request == 0) + if (!copy[i].request) continue; /* Grab a request slot and copy shadow state into it. */ @@ -915,9 +915,7 @@ static int blkif_recover(struct blkfront_info *info) req->seg[j].gref, info->xbdev->otherend_id, pfn_to_mfn(info->shadow[req->id].frame[j]), - rq_data_dir( - (struct request *) - info->shadow[req->id].request)); + rq_data_dir(info->shadow[req->id].request)); info->shadow[req->id].req = *req; info->ring.req_prod_pvt++; -- cgit v1.2.3-70-g09d2 From be2f8373c188ed1f5d36003c9928e4d695213080 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 2 Nov 2010 10:38:33 -0400 Subject: xen/blkfront: Implement FUA with BLKIF_OP_WRITE_BARRIER The BLKIF_OP_WRITE_BARRIER is a full ordered barrier, so we can use it to implement FUA as well as a plain FLUSH. Signed-off-by: Jeremy Fitzhardinge Acked-by: Christoph Hellwig --- drivers/block/xen-blkfront.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 31c8a643d10..76b874a7917 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -286,8 +286,18 @@ static int blkif_queue_request(struct request *req) ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; - if (req->cmd_flags & REQ_FLUSH) + + if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) { + /* + * Ideally we could just do an unordered + * flush-to-disk, but all we have is a full write + * barrier at the moment. However, a barrier write is + * a superset of FUA, so we can implement it the same + * way. (It's also a FLUSH+FUA, since it is + * guaranteed ordered WRT previous writes.) + */ ring_req->operation = BLKIF_OP_WRITE_BARRIER; + } ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); @@ -1065,7 +1075,7 @@ static void blkfront_connect(struct blkfront_info *info) info->feature_flush = 0; if (!err && barrier) - info->feature_flush = REQ_FLUSH; + info->feature_flush = REQ_FLUSH | REQ_FUA; err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); if (err) { -- cgit v1.2.3-70-g09d2 From dcb8baeceaa1c629bbd06f472cea023ad08a0c33 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 2 Nov 2010 11:55:58 -0400 Subject: xen/blkfront: cope with backend that fail empty BLKIF_OP_WRITE_BARRIER requests Some(?) Xen block backends fail BLKIF_OP_WRITE_BARRIER requests, which Linux uses as a cache flush operation. In that case, disable use of FLUSH. Signed-off-by: Jeremy Fitzhardinge Cc: Daniel Stodden --- drivers/block/xen-blkfront.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 76b874a7917..4f9e22f2913 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -656,6 +656,16 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", info->gd->disk_name); error = -EOPNOTSUPP; + } + if (unlikely(bret->status == BLKIF_RSP_ERROR && + info->shadow[id].req.nr_segments == 0)) { + printk(KERN_WARNING "blkfront: %s: empty write barrier op failed\n", + info->gd->disk_name); + error = -EOPNOTSUPP; + } + if (unlikely(error)) { + if (error == -EOPNOTSUPP) + error = 0; info->feature_flush = 0; xlvbd_flush(info); } -- cgit v1.2.3-70-g09d2 From 587d145200f26758940099fbbc301fdd43d3f391 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 25 Oct 2010 19:44:21 -0700 Subject: HID: Remove KERN_DEBUG from dbg_hid use Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 834ef47b76d..76e1f64e976 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -136,7 +136,8 @@ static int hidinput_setkeycode(struct input_dev *dev, clear_bit(old_keycode, dev->keybit); set_bit(usage->code, dev->keybit); - dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); + dbg_hid("Assigned keycode %d to HID usage code %x\n", + keycode, scancode); /* Set the keybit for the old keycode if the old keycode is used * by another key */ if (hidinput_find_key (hid, 0, old_keycode)) -- cgit v1.2.3-70-g09d2 From 5a39ce5b491a10f4a15bd30b26e55d3533b5f587 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 13 Oct 2010 15:58:17 +0200 Subject: HID: egalax: Use kzalloc To avoid unnecessary explicit initialization, allocate zeroed memory. Signed-off-by: Henrik Rydberg Acked-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-egalax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index 54b017ad258..5a1b52e0eb8 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c @@ -221,7 +221,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id) struct egalax_data *td; struct hid_report *report; - td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL); + td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL); if (!td) { dev_err(&hdev->dev, "cannot allocate eGalax data\n"); return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 25d5c699f983a2da51f5165eb9a8fc6338124b6c Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Sun, 7 Nov 2010 16:22:28 -0500 Subject: mmc: Fix printing of card DDR type We should not call mmc_card_set_ddr_mode() if we are in single data mode. This sets DDR and causes the kernel log to say the card is DDR when it is not. Explicitly set ddr to 0 rather then rely on MMC_SDR_MODE being 0 when doing the checks. Signed-off-by: Philip Rakity Acked-by: Linus Walleij Acked-by: Kyungmin Park Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 995261f7fd7..77f93c3b880 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; - int err, ddr = MMC_SDR_MODE; + int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; @@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, 1 << bus_width, ddr); err = 0; } else { - mmc_card_set_ddr_mode(card); + if (ddr) + mmc_card_set_ddr_mode(card); + else + ddr = MMC_SDR_MODE; + mmc_set_bus_width_ddr(card->host, bus_width, ddr); } } -- cgit v1.2.3-70-g09d2 From 14d4031d21d8a63ad84e5ab9198d0503efabc780 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 4 Nov 2010 13:59:11 +0800 Subject: mmc: ushc: Return proper error code for ushc_probe() Improves error handling in the ushc driver. Signed-off-by: Axel Lin Acked-by: David Vrabel Signed-off-by: Chris Ball --- drivers/mmc/host/ushc.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index b4ead4a13c9..f8f65df9b01 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c @@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id struct usb_device *usb_dev = interface_to_usbdev(intf); struct mmc_host *mmc; struct ushc_data *ushc; - int ret = -ENOMEM; + int ret; mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); if (mmc == NULL) @@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id mmc->max_blk_count = 511; ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (ushc->int_urb == NULL) + if (ushc->int_urb == NULL) { + ret = -ENOMEM; goto err; + } ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); - if (ushc->int_data == NULL) + if (ushc->int_data == NULL) { + ret = -ENOMEM; goto err; + } usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, usb_rcvintpipe(usb_dev, intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), @@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id intf->cur_altsetting->endpoint[0].desc.bInterval); ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); - if (ushc->cbw_urb == NULL) + if (ushc->cbw_urb == NULL) { + ret = -ENOMEM; goto err; + } ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); - if (ushc->cbw == NULL) + if (ushc->cbw == NULL) { + ret = -ENOMEM; goto err; + } ushc->cbw->signature = USHC_CBW_SIGNATURE; usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), @@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id cbw_callback, ushc); ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); - if (ushc->data_urb == NULL) + if (ushc->data_urb == NULL) { + ret = -ENOMEM; goto err; + } ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); - if (ushc->csw_urb == NULL) + if (ushc->csw_urb == NULL) { + ret = -ENOMEM; goto err; + } ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); - if (ushc->csw == NULL) + if (ushc->csw == NULL) { + ret = -ENOMEM; goto err; + } usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), ushc->csw, sizeof(struct ushc_csw), csw_callback, ushc); -- cgit v1.2.3-70-g09d2 From 5f619704d18b93869d045abc49e09cdba109b04b Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 4 Nov 2010 22:20:39 +0000 Subject: mmc: sdhci: Properly enable SDIO IRQ wakeups A little more work was needed for SDIO IRQ wakeups to be functional. Wake-on-WLAN on the SD WiFi adapter in the XO-1.5 laptop is now working. Signed-off-by: Daniel Drake Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pci.c | 11 +++++++++-- drivers/mmc/host/sdhci.c | 10 ++++++++++ drivers/mmc/host/sdhci.h | 4 ++++ 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 55746bac2f4..d196e77a93d 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -637,6 +637,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) { struct sdhci_pci_chip *chip; struct sdhci_pci_slot *slot; + mmc_pm_flag_t slot_pm_flags; mmc_pm_flag_t pm_flags = 0; int i, ret; @@ -657,7 +658,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) return ret; } - pm_flags |= slot->host->mmc->pm_flags; + slot_pm_flags = slot->host->mmc->pm_flags; + if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) + sdhci_enable_irq_wakeups(slot->host); + + pm_flags |= slot_pm_flags; } if (chip->fixes && chip->fixes->suspend) { @@ -671,8 +676,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); if (pm_flags & MMC_PM_KEEP_POWER) { - if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) + if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) { + pci_pme_active(pdev, true); pci_enable_wake(pdev, PCI_D3hot, 1); + } pci_set_power_state(pdev, PCI_D3hot); } else { pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 782c0ee3c92..154cbf83c1a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1681,6 +1681,16 @@ int sdhci_resume_host(struct sdhci_host *host) EXPORT_SYMBOL_GPL(sdhci_resume_host); +void sdhci_enable_irq_wakeups(struct sdhci_host *host) +{ + u8 val; + val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); + val |= SDHCI_WAKE_ON_INT; + sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); +} + +EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); + #endif /* CONFIG_PM */ /*****************************************************************************\ diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b7b8a3b28b0..d52a7163b97 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -87,6 +87,9 @@ #define SDHCI_BLOCK_GAP_CONTROL 0x2A #define SDHCI_WAKE_UP_CONTROL 0x2B +#define SDHCI_WAKE_ON_INT 0x01 +#define SDHCI_WAKE_ON_INSERT 0x02 +#define SDHCI_WAKE_ON_REMOVE 0x04 #define SDHCI_CLOCK_CONTROL 0x2C #define SDHCI_DIVIDER_SHIFT 8 @@ -317,6 +320,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); #ifdef CONFIG_PM extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); extern int sdhci_resume_host(struct sdhci_host *host); +extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); #endif #endif /* __SDHCI_HW_H */ -- cgit v1.2.3-70-g09d2 From 37865fe91582582a6f6c00652f6a2b1ff71f8a78 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Sat, 23 Oct 2010 01:57:21 +0200 Subject: mmc: sdhci-esdhc-imx: fix timeout on i.MX's sdhci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes timeout problems on i.MX's sdhci as suggested by Richard Zhu. Tested on: - i.MX257: not needed - i.MX357: needed - i.MX515: needed More details can be found here: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/029748.html Signed-off-by: Eric Bénard Tested-by: Shawn Guo Acked-by: Wolfram Sang Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-esdhc-imx.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2e9cca19c90..28e63ef58d0 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -112,6 +113,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd clk_enable(clk); pltfm_host->clk = clk; + if (cpu_is_mx35() || cpu_is_mx51()) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + return 0; } -- cgit v1.2.3-70-g09d2 From 16a790bcce87740d219b7227eaa4df72804097ea Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Sat, 23 Oct 2010 01:57:22 +0200 Subject: mmc: sdhci-esdhc-imx: enable QUIRK_NO_MULTIBLOCK only for i.MX25 and i.MX35 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only these CPUs list the bug in their errata. Signed-off-by: Eric Bénard Acked-by: Wolfram Sang Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-esdhc-imx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 28e63ef58d0..9b82910b9db 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -116,6 +116,10 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd if (cpu_is_mx35() || cpu_is_mx51()) host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */ + if (cpu_is_mx25() || cpu_is_mx35()) + host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; + return 0; } @@ -137,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = { }; struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { - .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK - | SDHCI_QUIRK_BROKEN_ADMA, + .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA, /* ADMA has issues. Might be fixable */ - /* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */ .ops = &sdhci_esdhc_ops, .init = esdhc_pltfm_init, .exit = esdhc_pltfm_exit, -- cgit v1.2.3-70-g09d2 From 35ac6f081f26e1b6b3482b9c8dfccebe7817c691 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Tue, 9 Nov 2010 13:57:29 +0000 Subject: mmc: sdhci: Fix crash on boot with C0 stepping Moorestown platforms SDHC2 is newly added in C0 stepping of Langwell. Without the Moorestown specific quirk, the default pci_probe will be called and crash the kernel. This patch unblocks the crash problem on C0 by using the same probing function as HC1, which limits the number of slots to one. Signed-off-by: Jacob Pan Signed-off-by: Alan Cox Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pci.c | 20 ++++++++++++++------ include/linux/pci_ids.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d196e77a93d..3d9c2460d43 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = { * ADMA operation is disabled for Moorestown platform due to * hardware bugs. */ -static int mrst_hc1_probe(struct sdhci_pci_chip *chip) +static int mrst_hc_probe(struct sdhci_pci_chip *chip) { /* - * slots number is fixed here for MRST as SDIO3 is never used and has - * hardware bugs. + * slots number is fixed here for MRST as SDIO3/5 are never used and + * have hardware bugs. */ chip->num_slots = 1; return 0; @@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, }; -static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = { +static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = { .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, - .probe = mrst_hc1_probe, + .probe = mrst_hc_probe, }; static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { @@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_INTEL_MRST_SD1, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1, + .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2, + }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_MRST_SD2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2, }, { diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c6bcfe93b9c..d369b533dc2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2441,6 +2441,7 @@ #define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x0822 #define PCI_DEVICE_ID_INTEL_MFD_EMMC0 0x0823 #define PCI_DEVICE_ID_INTEL_MFD_EMMC1 0x0824 +#define PCI_DEVICE_ID_INTEL_MRST_SD2 0x084F #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 #define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 -- cgit v1.2.3-70-g09d2 From 69669455b049c0f1f04bb306625c5d4db6838b11 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Nov 2010 18:51:34 +0100 Subject: drm/i915: Fix I2C adapter registration Fix many small bugs in I2C adapter registration: * Properly reject unsupported GPIO pin. * Fix improper use of I2C_NAME_SIZE (which is the size of i2c_client.name, not i2c_adapter.name.) * Prefix adapter names with "i915" so that the user knows what the I2C channel is connected to. * Fix swapped characters in the string used to name the GPIO-based adapter. * Add missing comma in gmbus name table. Signed-off-by: Jean Delvare Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_i2c.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 2be4f728ed0..3dba086e7ee 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -160,7 +160,7 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) }; struct intel_gpio *gpio; - if (pin < 1 || pin > 7) + if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) return NULL; gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); @@ -172,7 +172,8 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) gpio->reg += PCH_GPIOA - GPIOA; gpio->dev_priv = dev_priv; - snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO%c", "?BACDEF?"[pin]); + snprintf(gpio->adapter.name, sizeof(gpio->adapter.name), + "i915 GPIO%c", "?BACDE?F"[pin]); gpio->adapter.owner = THIS_MODULE; gpio->adapter.algo_data = &gpio->algo; gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; @@ -349,7 +350,7 @@ int intel_setup_gmbus(struct drm_device *dev) "panel", "dpc", "dpb", - "reserved" + "reserved", "dpd", }; struct drm_i915_private *dev_priv = dev->dev_private; @@ -366,8 +367,8 @@ int intel_setup_gmbus(struct drm_device *dev) bus->adapter.owner = THIS_MODULE; bus->adapter.class = I2C_CLASS_DDC; snprintf(bus->adapter.name, - I2C_NAME_SIZE, - "gmbus %s", + sizeof(bus->adapter.name), + "i915 gmbus %s", names[i]); bus->adapter.dev.parent = &dev->pdev->dev; -- cgit v1.2.3-70-g09d2 From 318af55ddd38bdaaa2b57f5c3bd394f3ce3a2610 Mon Sep 17 00:00:00 2001 From: "Hans J. Koch" Date: Sat, 30 Oct 2010 00:36:47 +0200 Subject: uio: Change mail address of Hans J. Koch My old mail address doesn't exist anymore. This changes all occurrences to my new address. Signed-off-by: Hans J. Koch Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio.c | 2 +- drivers/uio/uio_cif.c | 2 +- drivers/uio/uio_netx.c | 2 +- include/linux/uio_driver.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index a858d2b87b9..51fe1795d5a 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -3,7 +3,7 @@ * * Copyright(C) 2005, Benedikt Spranger * Copyright(C) 2005, Thomas Gleixner - * Copyright(C) 2006, Hans J. Koch + * Copyright(C) 2006, Hans J. Koch * Copyright(C) 2006, Greg Kroah-Hartman * * Userspace IO diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index a8ea2f19a0c..a84a451159e 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c @@ -1,7 +1,7 @@ /* * UIO Hilscher CIF card driver * - * (C) 2007 Hans J. Koch + * (C) 2007 Hans J. Koch * Original code (C) 2005 Benedikt Spranger * * Licensed under GPL version 2 only. diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c index 5a18e9f7b83..5ffdb483b01 100644 --- a/drivers/uio/uio_netx.c +++ b/drivers/uio/uio_netx.c @@ -2,7 +2,7 @@ * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX). * See http://www.hilscher.com for details. * - * (C) 2007 Hans J. Koch + * (C) 2007 Hans J. Koch * (C) 2008 Manuel Traut * * Licensed under GPL version 2 only. diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index d6188e5a52d..665517c05ea 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -3,7 +3,7 @@ * * Copyright(C) 2005, Benedikt Spranger * Copyright(C) 2005, Thomas Gleixner - * Copyright(C) 2006, Hans J. Koch + * Copyright(C) 2006, Hans J. Koch * Copyright(C) 2006, Greg Kroah-Hartman * * Userspace IO driver. -- cgit v1.2.3-70-g09d2 From 241b652f1995de138106afd2f2e4eda9f8a3c240 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 5 Nov 2010 09:59:01 -0400 Subject: xhci: Remove excessive printks with shared IRQs. If the xHCI host controller shares an interrupt line with another device, the xHCI driver needs to check if the interrupt was generated by its hardware. Unfortunately, the user will see a ton of "Spurious interrupt." lines if the other hardware interrupts often. Lawrence found his dmesg output cluttered with this output when the xHCI host shared an interrupt with his i915 hardware. Remove the warning, as sharing an interrupt is a normal thing. This should be applied to the 2.6.36 stable tree. Signed-off-by: Sarah Sharp Reported-by: Lawrence Rust Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9f3115e729b..df558f6f84e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) if (!(status & STS_EINT)) { spin_unlock(&xhci->lock); - xhci_warn(xhci, "Spurious interrupt.\n"); return IRQ_NONE; } xhci_dbg(xhci, "op reg status = %08x\n", status); -- cgit v1.2.3-70-g09d2 From 74bb844af8ec6a4c360b1fc7feb139801c0cacfd Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Wed, 27 Oct 2010 16:44:52 +0800 Subject: xHCI: release spinlock when setup interrupt Jiri Slaby reports spinlock is held while calling kmalloc(GFP_KERNEL) and request_irq() in xhci_resume(). Release the spinlock when setup interrupt. Reported-by: Jiri Slaby Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 5d7d4e951ea..7c8d70fbe11 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -714,6 +714,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) return retval; } + spin_unlock_irq(&xhci->lock); /* Re-setup MSI-X */ if (hcd->irq) free_irq(hcd->irq, hcd); @@ -736,6 +737,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) hcd->irq = pdev->irq; } + spin_lock_irq(&xhci->lock); /* step 4: set Run/Stop bit */ command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_RUN; -- cgit v1.2.3-70-g09d2 From dc07c91b9b4067022210e68d914a6890a4d70622 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Thu, 11 Nov 2010 17:43:57 +0800 Subject: xHCI: fix wMaxPacketSize mask USB2.0 spec 9.6.6 says: For all endpoints, bit 10..0 specify the maximum packet size(in bytes). So the wMaxPacketSize mask should be 0x7ff rather than 0x3ff. This patch should be queued for the stable tree. The bug in xhci_endpoint_init() was present as far back as 2.6.31, and the bug in xhci_get_max_esit_payload() was present when the function was introduced in 2.6.34. Reported-by: Sander Eikelenboom Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 202770676da..d178761c398 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, if (udev->speed == USB_SPEED_SUPER) return ep->ss_ep_comp.wBytesPerInterval; - max_packet = ep->desc.wMaxPacketSize & 0x3ff; + max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; /* A 0 in max burst means 1 transfer per ESIT */ return max_packet * (max_burst + 1); @@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Fall through */ case USB_SPEED_FULL: case USB_SPEED_LOW: - max_packet = ep->desc.wMaxPacketSize & 0x3ff; + max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); ep_ctx->ep_info2 |= MAX_PACKET(max_packet); break; default: diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 93d3bf4d213..85e65647d44 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -621,6 +621,11 @@ struct xhci_ep_ctx { #define MAX_PACKET_MASK (0xffff << 16) #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) +/* Get max packet size from ep desc. Bit 10..0 specify the max packet size. + * USB2.0 spec 9.6.6. + */ +#define GET_MAX_PACKET(p) ((p) & 0x7ff) + /* tx_info bitmasks */ #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) -- cgit v1.2.3-70-g09d2 From e060e7af98182494b764d002eba7fa022fe91bdf Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 11 Nov 2010 12:37:43 -0800 Subject: xen: set vma flag VM_PFNMAP in the privcmd mmap file_op Set VM_PFNMAP in the privcmd mmap file_op, rather than later in xen_remap_domain_mfn_range when it is too late because vma_wants_writenotify has already been called and vm_page_prot has already been modified. Signed-off-by: Stefano Stabellini Signed-off-by: Jeremy Fitzhardinge --- arch/x86/xen/mmu.c | 3 ++- drivers/xen/xenfs/privcmd.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index f08ea045620..792de4349c7 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -2299,7 +2299,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP); - vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) == + (VM_PFNMAP | VM_RESERVED | VM_IO))); rmd.mfn = mfn; rmd.prot = prot; diff --git a/drivers/xen/xenfs/privcmd.c b/drivers/xen/xenfs/privcmd.c index 2eb04c84251..88474d460d8 100644 --- a/drivers/xen/xenfs/privcmd.c +++ b/drivers/xen/xenfs/privcmd.c @@ -380,8 +380,9 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma) if (xen_feature(XENFEAT_auto_translated_physmap)) return -ENOSYS; - /* DONTCOPY is essential for Xen as copy_page_range is broken. */ - vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; + /* DONTCOPY is essential for Xen because copy_page_range doesn't know + * how to recreate these mappings */ + vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP; vma->vm_ops = &privcmd_vm_ops; vma->vm_private_data = NULL; -- cgit v1.2.3-70-g09d2 From d9bcbf343ec63e1104b5276195888ee06b4d086f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 11 Nov 2010 17:32:25 +0100 Subject: mmc: fix rmmod race for hosts using card-detection polling MMC hosts that poll for card detection by defining the MMC_CAP_NEEDS_POLL flag have a race on rmmod, where the delayed work is cancelled without waiting for completed polling. To prevent this a _sync version of the work cancellation has to be used. Signed-off-by: Guennadi Liakhovetski Cc: Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8f86d702e46..31ae07a3657 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host) if (host->caps & MMC_CAP_DISABLE) cancel_delayed_work(&host->disable); - cancel_delayed_work(&host->detect); + cancel_delayed_work_sync(&host->detect); mmc_flush_scheduled_work(); /* clear pm flags now and let card drivers set them as needed */ -- cgit v1.2.3-70-g09d2 From 85345517fe6d4de27b0d6ca19fef9d28ac947c4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 13 Nov 2010 09:49:11 +0000 Subject: drm/i915: Retire any pending operations on the old scanout when switching An old and oft reported bug, is that of the GPU hanging on a MI_WAIT_FOR_EVENT following a mode switch. The cause is that the GPU is waiting on a scanline counter on an inactive pipe, and so waits for a very long time until eventually the user reboots his machine. We can prevent this either by moving the WAIT into the kernel and thereby incurring considerable cost on every swapbuffers, or by waiting for the GPU to retire the last batch that accesses the framebuffer before installing a new one. As mode switches are much rarer than swap buffers, this looks like an easy choice. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=28964 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29252 Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++ 3 files changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 90414ae86af..409826da309 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1045,6 +1045,8 @@ void i915_gem_clflush_object(struct drm_gem_object *obj); int i915_gem_object_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain); +int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, + bool interruptible); int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eba9b161522..951e3d46311 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2907,6 +2907,20 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, return 0; } +int +i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, + bool interruptible) +{ + if (!obj->active) + return 0; + + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) + i915_gem_flush_ring(obj->base.dev, NULL, obj->ring, + 0, obj->base.write_domain); + + return i915_gem_object_wait_rendering(&obj->base, interruptible); +} + /** * Moves a single object to the CPU read, and possibly write domain. * diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 48d8fd686ea..bee24b1a58e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1611,6 +1611,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, wait_event(dev_priv->pending_flip_queue, atomic_read(&obj_priv->pending_flip) == 0); + + /* Big Hammer, we also need to ensure that any pending + * MI_WAIT_FOR_EVENT inside a user batch buffer on the + * current scanout is retired before unpinning the old + * framebuffer. + */ + ret = i915_gem_object_flush_gpu(obj_priv, false); + if (ret) { + i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); + mutex_unlock(&dev->struct_mutex); + return ret; + } } ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, -- cgit v1.2.3-70-g09d2 From fba4312e223f1187efc8c083daed70e57fa9c9d3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 14 Nov 2010 20:24:35 -0500 Subject: drm/radeon/kms: fix and unify tiled buffer alignment checking for r6xx/7xx Tiled buffers have the same alignment requirements regardless of whether the surface is for db, cb, or textures. Previously, the calculations where inconsistent for each buffer type. - Unify the alignment calculations in a common function - Standardize the alignment units (pixels for pitch/height/depth, bytes for base) - properly check the buffer base alignments Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 309 ++++++++++++++++++++++++--------------- drivers/gpu/drm/radeon/r600d.h | 6 + 2 files changed, 199 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 37cc2aa9f92..0f90fc3482c 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -50,6 +50,7 @@ struct r600_cs_track { u32 nsamples; u32 cb_color_base_last[8]; struct radeon_bo *cb_color_bo[8]; + u64 cb_color_bo_mc[8]; u32 cb_color_bo_offset[8]; struct radeon_bo *cb_color_frag_bo[8]; struct radeon_bo *cb_color_tile_bo[8]; @@ -67,6 +68,7 @@ struct r600_cs_track { u32 db_depth_size; u32 db_offset; struct radeon_bo *db_bo; + u64 db_bo_mc; }; static inline int r600_bpe_from_format(u32 *bpe, u32 format) @@ -140,6 +142,68 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format) return 0; } +struct array_mode_checker { + int array_mode; + u32 group_size; + u32 nbanks; + u32 npipes; + u32 nsamples; + u32 bpe; +}; + +/* returns alignment in pixels for pitch/height/depth and bytes for base */ +static inline int r600_get_array_mode_alignment(struct array_mode_checker *values, + u32 *pitch_align, + u32 *height_align, + u32 *depth_align, + u64 *base_align) +{ + u32 tile_width = 8; + u32 tile_height = 8; + u32 macro_tile_width = values->nbanks; + u32 macro_tile_height = values->npipes; + u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples; + u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; + + switch (values->array_mode) { + case ARRAY_LINEAR_GENERAL: + /* technically tile_width/_height for pitch/height */ + *pitch_align = 1; /* tile_width */ + *height_align = 1; /* tile_height */ + *depth_align = 1; + *base_align = 1; + break; + case ARRAY_LINEAR_ALIGNED: + *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe)); + *height_align = tile_height; + *depth_align = 1; + *base_align = values->group_size; + break; + case ARRAY_1D_TILED_THIN1: + *pitch_align = max((u32)tile_width, + (u32)(values->group_size / + (tile_height * values->bpe * values->nsamples))); + *height_align = tile_height; + *depth_align = 1; + *base_align = values->group_size; + break; + case ARRAY_2D_TILED_THIN1: + *pitch_align = max((u32)macro_tile_width, + (u32)(((values->group_size / tile_height) / + (values->bpe * values->nsamples)) * + values->nbanks)) * tile_width; + *height_align = macro_tile_height * tile_height; + *depth_align = 1; + *base_align = max(macro_tile_bytes, + (*pitch_align) * values->bpe * (*height_align) * values->nsamples); + break; + default: + return -EINVAL; + } + + return 0; +} + static void r600_cs_track_init(struct r600_cs_track *track) { int i; @@ -153,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track) track->cb_color_info[i] = 0; track->cb_color_bo[i] = NULL; track->cb_color_bo_offset[i] = 0xFFFFFFFF; + track->cb_color_bo_mc[i] = 0xFFFFFFFF; } track->cb_target_mask = 0xFFFFFFFF; track->cb_shader_mask = 0xFFFFFFFF; track->db_bo = NULL; + track->db_bo_mc = 0xFFFFFFFF; /* assume the biggest format and that htile is enabled */ track->db_depth_info = 7 | (1 << 25); track->db_depth_view = 0xFFFFC000; @@ -168,7 +234,10 @@ static void r600_cs_track_init(struct r600_cs_track *track) static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) { struct r600_cs_track *track = p->track; - u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; + u32 bpe = 0, slice_tile_max, size, tmp; + u32 height, height_align, pitch, pitch_align, depth_align; + u64 base_offset, base_align; + struct array_mode_checker array_check; volatile u32 *ib = p->ib->ptr; unsigned array_mode; @@ -183,60 +252,40 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) i, track->cb_color_info[i]); return -EINVAL; } - /* pitch is the number of 8x8 tiles per row */ - pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; + /* pitch in pixels */ + pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; slice_tile_max *= 64; - height = slice_tile_max / (pitch * 8); + height = slice_tile_max / pitch; if (height > 8192) height = 8192; array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); + + base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; + array_check.array_mode = array_mode; + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = track->nsamples; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, + G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, + track->cb_color_info[i]); + return -EINVAL; + } switch (array_mode) { case V_0280A0_ARRAY_LINEAR_GENERAL: - /* technically height & 0x7 */ break; case V_0280A0_ARRAY_LINEAR_ALIGNED: - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_0280A0_ARRAY_1D_TILED_THIN1: - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } /* avoid breaking userspace */ if (height > 7) height &= ~0x7; - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_0280A0_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED((height / 8), track->npipes)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; default: dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, @@ -244,8 +293,24 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) track->cb_color_info[i]); return -EINVAL; } + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, height_align)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; + } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + return -EINVAL; + } + /* check offset */ - tmp = height * pitch * 8 * bpe; + tmp = height * pitch * bpe; if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { /* the initial DDX does bad things with the CB size occasionally */ @@ -260,15 +325,11 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) return -EINVAL; } } - if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); - return -EINVAL; - } /* limit max tile */ - tmp = (height * pitch * 8) >> 6; + tmp = (height * pitch) >> 6; if (tmp < slice_tile_max) slice_tile_max = tmp; - tmp = S_028060_PITCH_TILE_MAX(pitch - 1) | + tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); ib[track->cb_color_size_idx[i]] = tmp; return 0; @@ -310,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) /* Check depth buffer */ if (G_028800_STENCIL_ENABLE(track->db_depth_control) || G_028800_Z_ENABLE(track->db_depth_control)) { - u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max; + u32 nviews, bpe, ntiles, size, slice_tile_max; + u32 height, height_align, pitch, pitch_align, depth_align; + u64 base_offset, base_align; + struct array_mode_checker array_check; + int array_mode; + if (track->db_bo == NULL) { dev_warn(p->dev, "z/stencil with no depth buffer\n"); return -EINVAL; @@ -353,41 +419,34 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); } else { size = radeon_bo_size(track->db_bo); - pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1; + /* pitch in pixels */ + pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; slice_tile_max *= 64; - height = slice_tile_max / (pitch * 8); + height = slice_tile_max / pitch; if (height > 8192) height = 8192; - switch (G_028010_ARRAY_MODE(track->db_depth_info)) { + base_offset = track->db_bo_mc + track->db_offset; + array_mode = G_028010_ARRAY_MODE(track->db_depth_info); + array_check.array_mode = array_mode; + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = track->nsamples; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, + G_028010_ARRAY_MODE(track->db_depth_info), + track->db_depth_info); + return -EINVAL; + } + switch (array_mode) { case V_028010_ARRAY_1D_TILED_THIN1: - pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8); - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } /* don't break userspace */ height &= ~0x7; - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_028010_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED((height / 8), track->npipes)) { - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; default: dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, @@ -395,15 +454,27 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) track->db_depth_info); return -EINVAL; } - if (!IS_ALIGNED(track->db_offset, track->group_size)) { - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset); + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, height_align)) { + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + return -EINVAL; + } + ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; tmp = ntiles * bpe * 64 * nviews; if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { - dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n", + dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, radeon_bo_size(track->db_bo)); return -EINVAL; @@ -954,6 +1025,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); track->cb_color_base_last[tmp] = ib[idx]; track->cb_color_bo[tmp] = reloc->robj; + track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset; break; case DB_DEPTH_BASE: r = r600_cs_packet_next_reloc(p, &reloc); @@ -965,6 +1037,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx track->db_offset = radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); track->db_bo = reloc->robj; + track->db_bo_mc = reloc->lobj.gpu_offset; break; case DB_HTILE_DATA_BASE: case SQ_PGM_START_FS: @@ -1086,16 +1159,25 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, struct radeon_bo *texture, struct radeon_bo *mipmap, + u64 base_offset, + u64 mip_offset, u32 tiling_flags) { struct r600_cs_track *track = p->track; u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; - u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align; + u32 word0, word1, l0_size, mipmap_size; + u32 height_align, pitch, pitch_align, depth_align; + u64 base_align; + struct array_mode_checker array_check; /* on legacy kernel we don't perform advanced check */ if (p->rdev == NULL) return 0; + /* convert to bytes */ + base_offset <<= 8; + mip_offset <<= 8; + word0 = radeon_get_ib_value(p, idx + 0); if (tiling_flags & RADEON_TILING_MACRO) word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); @@ -1128,46 +1210,38 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i return -EINVAL; } - pitch = G_038000_PITCH(word0) + 1; - switch (G_038000_TILE_MODE(word0)) { - case V_038000_ARRAY_LINEAR_GENERAL: - pitch_align = 1; - /* XXX check height align */ - break; - case V_038000_ARRAY_LINEAR_ALIGNED: - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - case V_038000_ARRAY_1D_TILED_THIN1: - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - case V_038000_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - default: - dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, - G_038000_TILE_MODE(word0), word0); + /* pitch in texels */ + pitch = (G_038000_PITCH(word0) + 1) * 8; + array_check.array_mode = G_038000_TILE_MODE(word0); + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = 1; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", + __func__, __LINE__, G_038000_TILE_MODE(word0)); + return -EINVAL; + } + + /* XXX check height as well... */ + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", + __func__, __LINE__, base_offset); + return -EINVAL; + } + if (!IS_ALIGNED(mip_offset, base_align)) { + dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", + __func__, __LINE__, mip_offset); return -EINVAL; } - /* XXX check offset align */ word0 = radeon_get_ib_value(p, idx + 4); word1 = radeon_get_ib_value(p, idx + 5); @@ -1402,7 +1476,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); mipmap = reloc->robj; r = r600_check_texture_resource(p, idx+(i*7)+1, - texture, mipmap, reloc->lobj.tiling_flags); + texture, mipmap, + base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), + mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), + reloc->lobj.tiling_flags); if (r) return r; ib[idx+1+(i*7)+2] += base_offset; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 966a793e225..bff4dc4f410 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -51,6 +51,12 @@ #define PTE_READABLE (1 << 5) #define PTE_WRITEABLE (1 << 6) +/* tiling bits */ +#define ARRAY_LINEAR_GENERAL 0x00000000 +#define ARRAY_LINEAR_ALIGNED 0x00000001 +#define ARRAY_1D_TILED_THIN1 0x00000002 +#define ARRAY_2D_TILED_THIN1 0x00000004 + /* Registers */ #define ARB_POP 0x2418 #define ENABLE_TC128 (1 << 30) -- cgit v1.2.3-70-g09d2 From a41c73e04673b47730df682446f0d52f95e32a5b Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 14 Nov 2010 23:08:27 +0300 Subject: drm: radeon: fix error value sign enable_vblank implementations should use negative result to indicate error. radeon_enable_vblank() returns EINVAL in this case. Change this to -EINVAL. Signed-off-by: Vasiliy Kulikov Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index 2f349a30019..465746bd51b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c @@ -76,7 +76,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return EINVAL; + return -EINVAL; } } else { switch (crtc) { @@ -89,7 +89,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return EINVAL; + return -EINVAL; } } -- cgit v1.2.3-70-g09d2 From 1b346af2f88a0e19e718a843d39d34e41e5527e1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Aug 2010 08:03:04 +0200 Subject: ARM mx3fb: check for DMA engine type We have two dma engines in MX3 systems: The IPU and the SDMA engine. We have to check if we got a channel from the correct engine before proceeding with a channel. Signed-off-by: Sascha Hauer Cc: Guennadi Liakhovetski Reviewed-by: Guennadi Liakhovetski --- drivers/video/mx3fb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 7cfc170bce1..ca0f6be9d12 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -1420,6 +1421,9 @@ static bool chan_filter(struct dma_chan *chan, void *arg) struct device *dev; struct mx3fb_platform_data *mx3fb_pdata; + if (!imx_dma_is_ipu(chan)) + return false; + if (!rq) return false; -- cgit v1.2.3-70-g09d2 From 9a1683d1dd14d6ed35d2884c6b79ff12fc6bef39 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 15 Nov 2010 18:14:43 +0900 Subject: sh: clkfwk: Kill off unused clk_set_rate_ex(). With the refactoring of the SH7722 clock framework some time ago this abstraction has become unecessary. Kill it off before anyone else gets the bright idea to start using it. Signed-off-by: Paul Mundt --- Documentation/DocBook/sh.tmpl | 4 ---- Documentation/sh/clk.txt | 32 -------------------------------- drivers/sh/clk/core.c | 12 +++--------- include/linux/sh_clk.h | 30 ------------------------------ 4 files changed, 3 insertions(+), 75 deletions(-) delete mode 100644 Documentation/sh/clk.txt (limited to 'drivers') diff --git a/Documentation/DocBook/sh.tmpl b/Documentation/DocBook/sh.tmpl index d858d92cf6d..4a38f604fa6 100644 --- a/Documentation/DocBook/sh.tmpl +++ b/Documentation/DocBook/sh.tmpl @@ -79,10 +79,6 @@ - - Clock Framework Extensions -!Iinclude/linux/sh_clk.h - Machine Specific Interfaces diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt deleted file mode 100644 index 114b595cfa9..00000000000 --- a/Documentation/sh/clk.txt +++ /dev/null @@ -1,32 +0,0 @@ -Clock framework on SuperH architecture - -The framework on SH extends existing API by the function clk_set_rate_ex, -which prototype is as follows: - - clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id) - -The algo_id parameter is used to specify algorithm used to recalculate clocks, -adjanced to clock, specified as first argument. It is assumed that algo_id==0 -means no changes to adjanced clock - -Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, -if it is present in ops structure. The method should set the clock rate and adjust -all needed clocks according to the passed algo_id. -Exact values for algo_id are machine-dependent. For the sh7722, the following -values are defined: - - NO_CHANGE = 0, - IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */ - IUS_322, /* I:U:Sh = 3:2:2 */ - IUS_522, /* I:U:Sh = 5:2:2 */ - IUS_N11, /* I:U:Sh = N:1:1 */ - SB_N1, /* Sh:B = N:1 */ - SB3_N1, /* Sh:B3 = N:1 */ - SB3_32, /* Sh:B3 = 3:2 */ - SB3_43, /* Sh:B3 = 4:3 */ - SB3_54, /* Sh:B3 = 5:4 */ - BP_N1, /* B:P = N:1 */ - IP_N1 /* I:P = N:1 */ - -Each of these constants means relation between clocks that can be set via the FRQCR -register diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index cb12a8e1466..69be6bb9232 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -454,12 +454,6 @@ unsigned long clk_get_rate(struct clk *clk) EXPORT_SYMBOL_GPL(clk_get_rate); int clk_set_rate(struct clk *clk, unsigned long rate) -{ - return clk_set_rate_ex(clk, rate, 0); -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) { int ret = -EOPNOTSUPP; unsigned long flags; @@ -467,7 +461,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) spin_lock_irqsave(&clock_lock, flags); if (likely(clk->ops && clk->ops->set_rate)) { - ret = clk->ops->set_rate(clk, rate, algo_id); + ret = clk->ops->set_rate(clk, rate, 0); if (ret != 0) goto out_unlock; } else { @@ -485,7 +479,7 @@ out_unlock: return ret; } -EXPORT_SYMBOL_GPL(clk_set_rate_ex); +EXPORT_SYMBOL_GPL(clk_set_rate); int clk_set_parent(struct clk *clk, struct clk *parent) { @@ -654,7 +648,7 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) clkp->parent); if (likely(clkp->ops->set_rate)) clkp->ops->set_rate(clkp, - rate, NO_CHANGE); + rate, 0); else if (likely(clkp->ops->recalc)) clkp->rate = clkp->ops->recalc(clkp); } diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index cea0c38e7a6..30885d92880 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -67,36 +67,6 @@ int clk_register(struct clk *); void clk_unregister(struct clk *); void clk_enable_init_clocks(void); -/** - * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter - * @clk: clock source - * @rate: desired clock rate in Hz - * @algo_id: algorithm id to be passed down to ops->set_rate - * - * Returns success (0) or negative errno. - */ -int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); - -enum clk_sh_algo_id { - NO_CHANGE = 0, - - IUS_N1_N1, - IUS_322, - IUS_522, - IUS_N11, - - SB_N1, - - SB3_N1, - SB3_32, - SB3_43, - SB3_54, - - BP_N1, - - IP_N1, -}; - struct clk_div_mult_table { unsigned int *divisors; unsigned int nr_divisors; -- cgit v1.2.3-70-g09d2 From 35a96c739fd7624b8edff990a74b86b5a85342da Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 15 Nov 2010 18:18:32 +0900 Subject: sh: clkfwk: Kill off now unused algo_id in set_rate op. Now that clk_set_rate_ex() is gone, there is also no way to get at rate setting algo id, which is now also completely unused. Kill it off before new clock ops start using it. Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/clock-sh7372.c | 6 ++---- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 2 +- drivers/sh/clk/core.c | 5 ++--- drivers/sh/clk/cpg.c | 5 ++--- include/linux/sh_clk.h | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 7db31e6c6bf..b25ce90a346 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -220,8 +220,7 @@ static void pllc2_disable(struct clk *clk) __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR); } -static int pllc2_set_rate(struct clk *clk, - unsigned long rate, int algo_id) +static int pllc2_set_rate(struct clk *clk, unsigned long rate) { unsigned long value; int idx; @@ -463,8 +462,7 @@ static int fsidiv_enable(struct clk *clk) return 0; } -static int fsidiv_set_rate(struct clk *clk, - unsigned long rate, int algo_id) +static int fsidiv_set_rate(struct clk *clk, unsigned long rate) { int idx; diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 4eabc68cd75..b601fa3978d 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -110,7 +110,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) return 0; } -static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) +static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) { unsigned long frqcr3; unsigned int tmp; diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 69be6bb9232..87743e7d4d4 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -461,7 +461,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) spin_lock_irqsave(&clock_lock, flags); if (likely(clk->ops && clk->ops->set_rate)) { - ret = clk->ops->set_rate(clk, rate, 0); + ret = clk->ops->set_rate(clk, rate); if (ret != 0) goto out_unlock; } else { @@ -647,8 +647,7 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) clkp->ops->set_parent(clkp, clkp->parent); if (likely(clkp->ops->set_rate)) - clkp->ops->set_rate(clkp, - rate, 0); + clkp->ops->set_rate(clkp, rate); else if (likely(clkp->ops->recalc)) clkp->rate = clkp->ops->recalc(clkp); } diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 3aea5f0ceb0..359e9a322c7 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -110,8 +110,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div6_set_rate(struct clk *clk, - unsigned long rate, int algo_id) +static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) { unsigned long value; int idx; @@ -253,7 +252,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) +static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) { struct clk_div4_table *d4t = clk->priv; unsigned long value; diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 30885d92880..038475a2092 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -23,7 +23,7 @@ struct clk_ops { int (*enable)(struct clk *clk); void (*disable)(struct clk *clk); unsigned long (*recalc)(struct clk *clk); - int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); + int (*set_rate)(struct clk *clk, unsigned long rate); int (*set_parent)(struct clk *clk, struct clk *parent); long (*round_rate)(struct clk *clk, unsigned long rate); }; -- cgit v1.2.3-70-g09d2 From fcb7193096969ca9e5b9219b9a99ddf299d4054f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 15 Nov 2010 00:23:42 -0800 Subject: Input: sysrq - pass along lone Alt + SysRq When user presses and releases Alt + SysRq without pressing any of the hot keys re-inject the combination and pass it on to userspace instead of suppressing it - maybe he or she wanted to take print screen instead of invoking SysRq handler. Also pass along release events for keys that have been pressed before SysRq mode has been invoked so that keys do not appear to be "stuck". Acked-by: Jason Wessel Tested-by: Jason Wessel Signed-off-by: Dmitry Torokhov --- drivers/char/sysrq.c | 169 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index eaa5d3efa79..c556ed9db13 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq); #ifdef CONFIG_INPUT /* Simple translation table for the SysRq keys */ -static const unsigned char sysrq_xlate[KEY_MAX + 1] = +static const unsigned char sysrq_xlate[KEY_CNT] = "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ @@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] = "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ "\r\000/"; /* 0x60 - 0x6f */ -static bool sysrq_down; -static int sysrq_alt_use; -static int sysrq_alt; -static DEFINE_SPINLOCK(sysrq_event_lock); +struct sysrq_state { + struct input_handle handle; + struct work_struct reinject_work; + unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; + unsigned int alt; + unsigned int alt_use; + bool active; + bool need_reinject; +}; + +static void sysrq_reinject_alt_sysrq(struct work_struct *work) +{ + struct sysrq_state *sysrq = + container_of(work, struct sysrq_state, reinject_work); + struct input_handle *handle = &sysrq->handle; + unsigned int alt_code = sysrq->alt_use; + + if (sysrq->need_reinject) { + /* Simulate press and release of Alt + SysRq */ + input_inject_event(handle, EV_KEY, alt_code, 1); + input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); + input_inject_event(handle, EV_SYN, SYN_REPORT, 1); + + input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); + input_inject_event(handle, EV_KEY, alt_code, 0); + input_inject_event(handle, EV_SYN, SYN_REPORT, 1); + } +} -static bool sysrq_filter(struct input_handle *handle, unsigned int type, - unsigned int code, int value) +static bool sysrq_filter(struct input_handle *handle, + unsigned int type, unsigned int code, int value) { + struct sysrq_state *sysrq = handle->private; + bool was_active = sysrq->active; bool suppress; - /* We are called with interrupts disabled, just take the lock */ - spin_lock(&sysrq_event_lock); + switch (type) { - if (type != EV_KEY) - goto out; + case EV_SYN: + suppress = false; + break; - switch (code) { + case EV_KEY: + switch (code) { - case KEY_LEFTALT: - case KEY_RIGHTALT: - if (value) - sysrq_alt = code; - else { - if (sysrq_down && code == sysrq_alt_use) - sysrq_down = false; + case KEY_LEFTALT: + case KEY_RIGHTALT: + if (!value) { + /* One of ALTs is being released */ + if (sysrq->active && code == sysrq->alt_use) + sysrq->active = false; - sysrq_alt = 0; + sysrq->alt = KEY_RESERVED; + + } else if (value != 2) { + sysrq->alt = code; + sysrq->need_reinject = false; + } + break; + + case KEY_SYSRQ: + if (value == 1 && sysrq->alt != KEY_RESERVED) { + sysrq->active = true; + sysrq->alt_use = sysrq->alt; + /* + * If nothing else will be pressed we'll need + * to * re-inject Alt-SysRq keysroke. + */ + sysrq->need_reinject = true; + } + + /* + * Pretend that sysrq was never pressed at all. This + * is needed to properly handle KGDB which will try + * to release all keys after exiting debugger. If we + * do not clear key bit it KGDB will end up sending + * release events for Alt and SysRq, potentially + * triggering print screen function. + */ + if (sysrq->active) + clear_bit(KEY_SYSRQ, handle->dev->key); + + break; + + default: + if (sysrq->active && value && value != 2) { + sysrq->need_reinject = false; + __handle_sysrq(sysrq_xlate[code], true); + } + break; } - break; - case KEY_SYSRQ: - if (value == 1 && sysrq_alt) { - sysrq_down = true; - sysrq_alt_use = sysrq_alt; + suppress = sysrq->active; + + if (!sysrq->active) { + /* + * If we are not suppressing key presses keep track of + * keyboard state so we can release keys that have been + * pressed before entering SysRq mode. + */ + if (value) + set_bit(code, sysrq->key_down); + else + clear_bit(code, sysrq->key_down); + + if (was_active) + schedule_work(&sysrq->reinject_work); + + } else if (value == 0 && + test_and_clear_bit(code, sysrq->key_down)) { + /* + * Pass on release events for keys that was pressed before + * entering SysRq mode. + */ + suppress = false; } break; default: - if (sysrq_down && value && value != 2) - __handle_sysrq(sysrq_xlate[code], true); + suppress = sysrq->active; break; } -out: - suppress = sysrq_down; - spin_unlock(&sysrq_event_lock); - return suppress; } @@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { - struct input_handle *handle; + struct sysrq_state *sysrq; int error; - sysrq_down = false; - sysrq_alt = 0; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) + sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL); + if (!sysrq) return -ENOMEM; - handle->dev = dev; - handle->handler = handler; - handle->name = "sysrq"; + INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq); + + sysrq->handle.dev = dev; + sysrq->handle.handler = handler; + sysrq->handle.name = "sysrq"; + sysrq->handle.private = sysrq; - error = input_register_handle(handle); + error = input_register_handle(&sysrq->handle); if (error) { pr_err("Failed to register input sysrq handler, error %d\n", error); goto err_free; } - error = input_open_device(handle); + error = input_open_device(&sysrq->handle); if (error) { pr_err("Failed to open input device, error %d\n", error); goto err_unregister; @@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler, return 0; err_unregister: - input_unregister_handle(handle); + input_unregister_handle(&sysrq->handle); err_free: - kfree(handle); + kfree(sysrq); return error; } static void sysrq_disconnect(struct input_handle *handle) { + struct sysrq_state *sysrq = handle->private; + input_close_device(handle); + cancel_work_sync(&sysrq->reinject_work); input_unregister_handle(handle); - kfree(handle); + kfree(sysrq); } /* -- cgit v1.2.3-70-g09d2 From 3e9bb2a071614f1d185740f31ac503ecba11d783 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Mon, 15 Nov 2010 19:32:43 +0100 Subject: block: fix amiga and atari floppy driver compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Geert, my crosstool don't produce warning below. I guess this has to do something with compiler version. - Geert noticed following warning during compilation. drivers/block/amiflop.c:1344: warning: ‘rq’ may be used uninitialized in this function drivers/block/ataflop.c:1402: warning: ‘rq’ may be used uninitialized in this function - Initialize rq to NULL to fix the warning. If we can't find a suitable request to dispatch, this function should return NULL instead of a possibly garbage pointer. - Cross compile tested only. Don't have hardware to test it. Reported-by: Geert Uytterhoeven Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe --- drivers/block/amiflop.c | 2 +- drivers/block/ataflop.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index a1725e6488d..7888501ad9e 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1341,7 +1341,7 @@ static struct request *set_next_request(void) { struct request_queue *q; int cnt = FD_MAX_UNITS; - struct request *rq; + struct request *rq = NULL; /* Find next queue we can dispatch from */ fdc_queue = fdc_queue + 1; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 4e4cc6c828c..605a67e40bb 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1399,7 +1399,7 @@ static struct request *set_next_request(void) { struct request_queue *q; int old_pos = fdc_queue; - struct request *rq; + struct request *rq = NULL; do { q = unit[fdc_queue].disk->queue; -- cgit v1.2.3-70-g09d2 From dfa31fef5dd3d204c4cdae7369f3542bd1f7e84a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 15 Nov 2010 15:11:26 +0100 Subject: carl9170: fix usb anchor wait timeout usb_wait_anchor_empty_timeout's @timeout wants milliseconds and not jiffies. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 3317039cd28..7504ed14c72 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -553,12 +553,12 @@ static int carl9170_usb_flush(struct ar9170 *ar) usb_free_urb(urb); } - ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ); + ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000); if (ret == 0) err = -ETIMEDOUT; /* lets wait a while until the tx - queues are dried out */ - ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ); + ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000); if (ret == 0) err = -ETIMEDOUT; -- cgit v1.2.3-70-g09d2 From 898213200cbadc570ef4248a6d90430c4a9c2908 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 12 Nov 2010 11:59:31 -0800 Subject: xhci: Fix command ring replay after resume. Andiry's xHCI bus suspend patch introduced the possibly of a host controller replaying old commands on the command ring, if the host successfully restores the registers after a resume. After a resume from suspend, the xHCI driver must restore the registers, including the command ring pointer. I had suggested that Andiry set the command ring pointer to the current command ring dequeue pointer, so that the driver wouldn't have to zero the command ring. Unfortunately, setting the command ring pointer to the current dequeue pointer won't work because the register assumes the pointer is 64-byte aligned, and TRBs on the command ring are 16-byte aligned. The lower seven bits will always be masked off, leading to the written pointer being up to 3 TRBs behind the intended pointer. Here's a log excerpt. On init, the xHCI driver places a vendor-specific command on the command ring: [ 215.750958] xhci_hcd 0000:01:00.0: Vendor specific event TRB type = 48 [ 215.750960] xhci_hcd 0000:01:00.0: NEC firmware version 30.25 [ 215.750962] xhci_hcd 0000:01:00.0: Command ring deq = 0x3781e010 (DMA) When we resume, the command ring dequeue pointer to be written should have been 0x3781e010. Instead, it's 0x3781e000: [ 235.557846] xhci_hcd 0000:01:00.0: // Setting command ring address to 0x3781e001 [ 235.557848] xhci_hcd 0000:01:00.0: `MEM_WRITE_DWORD(3'b000, 64'hffffc900100bc038, 64'h3781e001, 4'hf); [ 235.557850] xhci_hcd 0000:01:00.0: `MEM_WRITE_DWORD(3'b000, 32'hffffc900100bc020, 32'h204, 4'hf); [ 235.557866] usb usb9: root hub lost power or was reset (I can't see the results of this bug because the xHCI restore always fails on this box, and the xHCI driver re-allocates everything.) The fix is to zero the command ring and put the software and hardware enqueue and dequeue pointer back to the beginning of the ring. We do this before the system suspends, to be paranoid and prevent the BIOS from starting the host without clearing the command ring pointer, which might cause the host to muck with stale memory. (The pointer isn't required to be in the suspend power well, but it could be.) The command ring pointer is set again after the host resumes. Signed-off-by: Sarah Sharp Tested-by: Andiry Xu --- drivers/usb/host/xhci.c | 71 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7c8d70fbe11..06fca0835b5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); } +static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) +{ + u64 val_64; + + /* step 2: initialize command ring buffer */ + val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | + (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, + xhci->cmd_ring->dequeue) & + (u64) ~CMD_RING_RSVD_BITS) | + xhci->cmd_ring->cycle_state; + xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n", + (long unsigned long) val_64); + xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); +} + +/* + * The whole command ring must be cleared to zero when we suspend the host. + * + * The host doesn't save the command ring pointer in the suspend well, so we + * need to re-program it on resume. Unfortunately, the pointer must be 64-byte + * aligned, because of the reserved bits in the command ring dequeue pointer + * register. Therefore, we can't just set the dequeue pointer back in the + * middle of the ring (TRBs are 16-byte aligned). + */ +static void xhci_clear_command_ring(struct xhci_hcd *xhci) +{ + struct xhci_ring *ring; + struct xhci_segment *seg; + + ring = xhci->cmd_ring; + seg = ring->deq_seg; + do { + memset(seg->trbs, 0, SEGMENT_SIZE); + seg = seg->next; + } while (seg != ring->deq_seg); + + /* Reset the software enqueue and dequeue pointers */ + ring->deq_seg = ring->first_seg; + ring->dequeue = ring->first_seg->trbs; + ring->enq_seg = ring->deq_seg; + ring->enqueue = ring->dequeue; + + /* + * Ring is now zeroed, so the HW should look for change of ownership + * when the cycle bit is set to 1. + */ + ring->cycle_state = 1; + + /* + * Reset the hardware dequeue pointer. + * Yes, this will need to be re-written after resume, but we're paranoid + * and want to make sure the hardware doesn't access bogus memory + * because, say, the BIOS or an SMI started the host without changing + * the command ring pointers. + */ + xhci_set_cmd_ring_deq(xhci); +} + /* * Stop HC (not bus-specific) * @@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci) spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } + xhci_clear_command_ring(xhci); /* step 3: save registers */ xhci_save_registers(xhci); @@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - u64 val_64; int old_state, retval; old_state = hcd->state; @@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* step 1: restore register */ xhci_restore_registers(xhci); /* step 2: initialize command ring buffer */ - val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); - val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | - (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, - xhci->cmd_ring->dequeue) & - (u64) ~CMD_RING_RSVD_BITS) | - xhci->cmd_ring->cycle_state; - xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n", - (long unsigned long) val_64); - xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); + xhci_set_cmd_ring_deq(xhci); /* step 3: restore state and start state*/ /* step 3: set CRS flag */ command = xhci_readl(xhci, &xhci->op_regs->command); -- cgit v1.2.3-70-g09d2 From e502ac5e1eca99d7dc3f12b2a6780ccbca674858 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:11:45 -0800 Subject: USB: atm: ueagle-atm: fix up some permissions on the sysfs files Some of the sysfs files had the incorrect permissions. Some didn't make sense at all (writable for a file that you could not write to?) Reported-by: Linus Torvalds Cc: Matthieu Castet Cc: Stanislaw Gruszka Cc: Damien Bergamini Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index ea071a5b6ee..44447f54942 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2301,7 +2301,7 @@ out: return ret; } -static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); +static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot); static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, char *buf) @@ -2364,8 +2364,7 @@ out: return ret; } -static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, - read_human_status, NULL); +static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL); static ssize_t read_delin(struct device *dev, struct device_attribute *attr, char *buf) @@ -2397,7 +2396,7 @@ out: return ret; } -static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); +static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL); #define UEA_ATTR(name, reset) \ \ -- cgit v1.2.3-70-g09d2 From 723b991a62d94f74c9f19abd3da6e937288eb969 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:15:11 -0800 Subject: USB: ehci: fix debugfs 'lpm' permissions The permissions for the lpm debugfs file is incorrect, this fixes it. Reported-by: Linus Torvalds Cc: Alek Du Cc: Jacob Pan Cc: David Brownell Cc: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 86afdc73322..6e2599661b5 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -1067,7 +1067,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci) &debug_registers_fops)) goto file_error; - if (!debugfs_create_file("lpm", S_IRUGO|S_IWUGO, ehci->debug_dir, bus, + if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus, &debug_lpm_fops)) goto file_error; -- cgit v1.2.3-70-g09d2 From d9624e75f6ad94d8a0718c1fafa89186d271a78c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:17:52 -0800 Subject: USB: storage: sierra_ms: fix sysfs file attribute A non-writable sysfs file shouldn't have writable attributes. Reported-by: Linus Torvalds Cc: Kevin Lloyd Cc: Matthew Dharm Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/sierra_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 57fc2f532ca..ceba512f84d 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr, } return result; } -static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL); +static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL); int sierra_ms_init(struct us_data *us) { -- cgit v1.2.3-70-g09d2 From c990600d340641150f7270470a64bd99a5c0b225 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:32:38 -0800 Subject: USB: misc: cypress_cy7c63: fix up some sysfs attribute permissions They should not be writable by any user. Reported-by: Linus Torvalds Cc: Oliver Bock Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/cypress_cy7c63.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 2f43c57743c..9251773ecef 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -196,11 +196,9 @@ static ssize_t get_port1_handler(struct device *dev, return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1); } -static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO, - get_port0_handler, set_port0_handler); +static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler); -static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO, - get_port1_handler, set_port1_handler); +static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler); static int cypress_probe(struct usb_interface *interface, -- cgit v1.2.3-70-g09d2 From d489a4b3926bad571d404ca6508f6744b9602776 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:34:26 -0800 Subject: USB: misc: trancevibrator: fix up a sysfs attribute permission It should not be writable by any user. Reported-by: Linus Torvalds Cc: Sam Hocevar Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/trancevibrator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index d77aba46ae8..f63776a48e2 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed); +static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed); static int tv_probe(struct usb_interface *interface, const struct usb_device_id *id) -- cgit v1.2.3-70-g09d2 From 48f115470e68d443436b76b22dad63ffbffd6b97 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:35:49 -0800 Subject: USB: misc: usbled: fix up some sysfs attribute permissions They should not be writable by any user. Reported-by: Linus Torvalds Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 63da2c3c838..c96f51de169 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c @@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co change_color(led); \ return count; \ } \ -static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); +static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value); show_set(blue); show_set(red); show_set(green); -- cgit v1.2.3-70-g09d2 From e24d7ace4e822debcb78386bf279c9aba4d7fbd1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:36:44 -0800 Subject: USB: misc: usbsevseg: fix up some sysfs attribute permissions They should not be writable by any user. Reported-by: Linus Torvalds Cc: Harrison Metzger Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbsevseg.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index de8ef945b53..417b8f207e8 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev, \ \ return count; \ } \ -static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name); +static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name); static ssize_t show_attr_text(struct device *dev, struct device_attribute *attr, char *buf) @@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev, return count; } -static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text); +static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text); static ssize_t show_attr_decimals(struct device *dev, struct device_attribute *attr, char *buf) @@ -272,8 +272,7 @@ static ssize_t set_attr_decimals(struct device *dev, return count; } -static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO, - show_attr_decimals, set_attr_decimals); +static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals); static ssize_t show_attr_textmode(struct device *dev, struct device_attribute *attr, char *buf) @@ -319,8 +318,7 @@ static ssize_t set_attr_textmode(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO, - show_attr_textmode, set_attr_textmode); +static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode); MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); -- cgit v1.2.3-70-g09d2 From 3d965875144b905d71dfb4d291c665c0794222c4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Nov 2010 11:37:55 -0800 Subject: USB: OTG: langwell_otg: fix up some sysfs attribute permissions They should not be writable by any user. Reported-by: Linus Torvalds Cc: Hao Wu Cc: Alan Cox Cc: Alek Du Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/langwell_otg.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index bdc3ea66be6..9fea48264fa 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -1896,7 +1896,7 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr, } return count; } -static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req); +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); static ssize_t get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) @@ -1942,8 +1942,7 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr, } return count; } -static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO, - get_a_bus_drop, set_a_bus_drop); +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop); static ssize_t get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) @@ -1988,7 +1987,7 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr, } return count; } -static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req); +static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); static ssize_t set_a_clr_err(struct device *dev, struct device_attribute *attr, @@ -2012,7 +2011,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr, } return count; } -static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err); +static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); static struct attribute *inputs_attrs[] = { &dev_attr_a_bus_req.attr, -- cgit v1.2.3-70-g09d2 From cc267ec5dfa29eba34cbf4eae3e5db9ca499c179 Mon Sep 17 00:00:00 2001 From: Arnd Hannemann Date: Mon, 15 Nov 2010 21:43:22 +0000 Subject: fbdev: sh_mobile_lcdcfb: fix bug in reconfig() The function sh_mobile_fb_reconfig() contained a bug, which caused the line_length to be set wrongly, if a mode with a different X-resolution than the default one was chosen. This caused 1080p24 mode to not work on AP4EVB. Additionally the notifier chain was also called with the wrong mode. This patch fixes this, by using the X-resolution of the new mode instead of the old one to calculate line length and hands over the correct mode to the notifier chain. Signed-off-by: Arnd Hannemann Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 9b1364723c6..b02d97a879d 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -860,7 +860,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) /* Couldn't reconfigure, hopefully, can continue as before */ return; - info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8); + info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); /* * fb_set_var() calls the notifier change internally, only if @@ -868,7 +868,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) * user event, we have to call the chain ourselves. */ event.info = info; - event.data = &mode2; + event.data = &mode1; fb_notifier_call_chain(evnt, &event); } -- cgit v1.2.3-70-g09d2 From 6f07d31e46639e4b1b23de6ee88c9e079a7bf32d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 15 Nov 2010 13:33:25 -0800 Subject: Input: aiptek - tighten up permissions on sysfs attributes Sysfs attributes affecting device behavior should not be, by default, world-writeable. If distributions want to allow console users access these attributes they need to employ udev and friends to adjust permissions as needed. Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 57b25b84d1f..0a619c558bf 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(pointer_mode, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletPointerMode, store_tabletPointerMode); /*********************************************************************** @@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co } static DEVICE_ATTR(coordinate_mode, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletCoordinateMode, store_tabletCoordinateMode); /*********************************************************************** @@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch } static DEVICE_ATTR(tool_mode, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletToolMode, store_tabletToolMode); /*********************************************************************** @@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char } static DEVICE_ATTR(xtilt, - S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt); + S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt); /*********************************************************************** * support routines for the 'ytilt' file. Note that this file @@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char } static DEVICE_ATTR(ytilt, - S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt); + S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt); /*********************************************************************** * support routines for the 'jitter' file. Note that this file @@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(jitter, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletJitterDelay, store_tabletJitterDelay); /*********************************************************************** @@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(delay, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletProgrammableDelay, store_tabletProgrammableDelay); /*********************************************************************** @@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(stylus_upper, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletStylusUpper, store_tabletStylusUpper); /*********************************************************************** @@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(stylus_lower, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletStylusLower, store_tabletStylusLower); /*********************************************************************** @@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c } static DEVICE_ATTR(mouse_left, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletMouseLeft, store_tabletMouseLeft); /*********************************************************************** @@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(mouse_middle, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletMouseMiddle, store_tabletMouseMiddle); /*********************************************************************** @@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const } static DEVICE_ATTR(mouse_right, - S_IRUGO | S_IWUGO, + S_IRUGO | S_IWUSR, show_tabletMouseRight, store_tabletMouseRight); /*********************************************************************** @@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char } static DEVICE_ATTR(wheel, - S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel); + S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel); /*********************************************************************** * support routines for the 'execute' file. Note that this file @@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha } static DEVICE_ATTR(execute, - S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute); + S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute); /*********************************************************************** * support routines for the 'odm_code' file. Note that this file -- cgit v1.2.3-70-g09d2 From fe61f1d737f7804e0bd440ace9724e669e2c2906 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 16 Nov 2010 11:06:46 -0800 Subject: xen/xenfs: update xenfs_mount for new prototype .mount now returns a struct dentry *. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index f6339d11d59..990ee42167a 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c @@ -121,9 +121,9 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent) return rc; } -static int xenfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *data) +static struct dentry *xenfs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) { return mount_single(fs_type, flags, data, xenfs_fill_super); } -- cgit v1.2.3-70-g09d2 From 590b0b9754bd8928926bae7194b6da7ead9bda3b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:17:01 -0800 Subject: Staging: asus_oled: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: Jakub Schmidtke Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/asus_oled/asus_oled.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 8c95d8c2a4f..555157ff9a4 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device, #define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file -static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(asus_oled_enabled, S_IRUSR | S_IRUGO, get_enabled, set_enabled); -static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture); +static DEVICE_ATTR(asus_oled_picture, S_IRUSR , NULL, set_picture); -static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(enabled, S_IRUSR | S_IRUGO, class_get_enabled, class_set_enabled); -static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture); +static DEVICE_ATTR(picture, S_IRUSR, NULL, class_set_picture); static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) -- cgit v1.2.3-70-g09d2 From 3bad28ec006ad6ab2bca4e5103860b75391e3c9d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:18:33 -0800 Subject: Staging: frontier: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: David Taht Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/tranzport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index a145a15cfdb..1611a27e9b7 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev) t->value = temp; \ return count; \ } \ - static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); + static DEVICE_ATTR(value, S_IRUSR | S_IRUGO, show_##value, set_##value); show_int(enable); show_int(offline); -- cgit v1.2.3-70-g09d2 From 1d904e8950c86e670ace237eaea1d48cd81e94df Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:19:53 -0800 Subject: Staging: iio: adis16220: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: Jonathan Cameron Cc: Barry Song Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16220_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c86d1498737..c2b20913937 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); #define IIO_DEV_ATTR_CAPTURE(_store) \ - IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0) + IIO_DEVICE_ATTR(capture, S_IRUSR, NULL, _store, 0) static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); -- cgit v1.2.3-70-g09d2 From 90c05b97fdec8d2196e420d98f774bab731af7aa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:21:03 -0800 Subject: Staging: samsung-laptop: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index eb44b60e1eb..28700b49827 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev, } return count; } -static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(silent, S_IRUSR | S_IRUGO, get_silent_state, set_silent_state); -- cgit v1.2.3-70-g09d2 From cc9ca9dfddda46b1802d325891a69d7efdbe1f1e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:21:36 -0800 Subject: Staging: udlfb: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: Bernie Thompson Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/udlfb/udlfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index fed25105970..0e0bc0b23d4 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = { __ATTR_RO(metrics_bytes_identical), __ATTR_RO(metrics_bytes_sent), __ATTR_RO(metrics_cpu_kcycles_used), - __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store), + __ATTR(metrics_reset, S_IRUSR, NULL, metrics_reset_store), }; /* -- cgit v1.2.3-70-g09d2 From 0281b490dd7b96990724f4a15842c55657699aed Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:22:43 -0800 Subject: Staging: zram: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: Nitin Gupta Cc: Pekka Enberg Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index 6c574a994d1..c9b52b941d6 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev, return sprintf(buf, "%llu\n", val); } -static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO, +static DEVICE_ATTR(disksize, S_IRUGO | S_IRUSR, disksize_show, disksize_store); static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); -static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store); +static DEVICE_ATTR(reset, S_IRUSR, NULL, reset_store); static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL); static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL); static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL); -- cgit v1.2.3-70-g09d2 From 2018845b6a169f75341f8e68ad1089cb6697cf24 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Nov 2010 11:23:33 -0800 Subject: Staging: line6: fix up some sysfs attribute permissions They should not be writable by any user Reported-by: Linus Torvalds Cc: Markus Grabner Cc: Mariusz Kozlowski Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/control.c | 204 +++++++++++++++++++-------------------- drivers/staging/line6/midi.c | 4 +- drivers/staging/line6/pcm.c | 4 +- drivers/staging/line6/pod.c | 32 +++--- drivers/staging/line6/toneport.c | 4 +- drivers/staging/line6/variax.c | 12 +-- 6 files changed, 130 insertions(+), 130 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c index 040e25ca6d3..95910ff4505 100644 --- a/drivers/staging/line6/control.c +++ b/drivers/staging/line6/control.c @@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2); VARIAX_PARAM_R(float, mix1); VARIAX_PARAM_R(int, pickup_wiring); -static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak); -static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, +static DEVICE_ATTR(tweak, S_IRUSR | S_IRUGO, pod_get_tweak, pod_set_tweak); +static DEVICE_ATTR(wah_position, S_IRUSR | S_IRUGO, pod_get_wah_position, pod_set_wah_position); -static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(compression_gain, S_IRUSR | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain); -static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(vol_pedal_position, S_IRUSR | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position); -static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(compression_threshold, S_IRUSR | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold); -static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan); -static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, +static DEVICE_ATTR(pan, S_IRUSR | S_IRUGO, pod_get_pan, pod_set_pan); +static DEVICE_ATTR(amp_model_setup, S_IRUSR | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup); -static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, +static DEVICE_ATTR(amp_model, S_IRUSR | S_IRUGO, pod_get_amp_model, pod_set_amp_model); -static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive); -static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass); -static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid); -static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid); -static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble); -static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, +static DEVICE_ATTR(drive, S_IRUSR | S_IRUGO, pod_get_drive, pod_set_drive); +static DEVICE_ATTR(bass, S_IRUSR | S_IRUGO, pod_get_bass, pod_set_bass); +static DEVICE_ATTR(mid, S_IRUSR | S_IRUGO, pod_get_mid, pod_set_mid); +static DEVICE_ATTR(lowmid, S_IRUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid); +static DEVICE_ATTR(treble, S_IRUSR | S_IRUGO, pod_get_treble, pod_set_treble); +static DEVICE_ATTR(highmid, S_IRUSR | S_IRUGO, pod_get_highmid, pod_set_highmid); -static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, +static DEVICE_ATTR(chan_vol, S_IRUSR | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol); -static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, +static DEVICE_ATTR(reverb_mix, S_IRUSR | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix); -static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, +static DEVICE_ATTR(effect_setup, S_IRUSR | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup); -static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_1_frequency, S_IRUSR | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency); -static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, +static DEVICE_ATTR(presence, S_IRUSR | S_IRUGO, pod_get_presence, pod_set_presence); -static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(treble__bass, treble, S_IRUSR | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass); -static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(noise_gate_enable, S_IRUSR | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable); -static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, +static DEVICE_ATTR(gate_threshold, S_IRUSR | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold); -static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, +static DEVICE_ATTR(gate_decay_time, S_IRUSR | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time); -static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, +static DEVICE_ATTR(stomp_enable, S_IRUSR | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable); -static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, +static DEVICE_ATTR(comp_enable, S_IRUSR | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable); -static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, +static DEVICE_ATTR(stomp_time, S_IRUSR | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time); -static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, +static DEVICE_ATTR(delay_enable, S_IRUSR | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable); -static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, +static DEVICE_ATTR(mod_param_1, S_IRUSR | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1); -static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, +static DEVICE_ATTR(delay_param_1, S_IRUSR | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1); -static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(delay_param_1_note_value, S_IRUSR | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value); -static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IRUSR | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass); -static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, +static DEVICE_ATTR(delay_param_2, S_IRUSR | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2); -static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(delay_volume_mix, S_IRUSR | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix); -static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, +static DEVICE_ATTR(delay_param_3, S_IRUSR | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3); -static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, +static DEVICE_ATTR(reverb_enable, S_IRUSR | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable); -static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, +static DEVICE_ATTR(reverb_type, S_IRUSR | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type); -static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, +static DEVICE_ATTR(reverb_decay, S_IRUSR | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay); -static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, +static DEVICE_ATTR(reverb_tone, S_IRUSR | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone); -static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(reverb_pre_delay, S_IRUSR | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); -static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, +static DEVICE_ATTR(reverb_pre_post, S_IRUSR | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post); -static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_2_frequency, S_IRUSR | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency); -static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IRUSR | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass); -static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, +static DEVICE_ATTR(wah_enable, S_IRUSR | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable); -static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(modulation_lo_cut, S_IRUSR | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); -static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(delay_reverb_lo_cut, S_IRUSR | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); -static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(volume_pedal_minimum, S_IRUSR | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); -static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, +static DEVICE_ATTR(eq_pre_post, S_IRUSR | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post); -static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, +static DEVICE_ATTR(volume_pre_post, S_IRUSR | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post); -static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, +static DEVICE_ATTR(di_model, S_IRUSR | S_IRUGO, pod_get_di_model, pod_set_di_model); -static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, +static DEVICE_ATTR(di_delay, S_IRUSR | S_IRUGO, pod_get_di_delay, pod_set_di_delay); -static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, +static DEVICE_ATTR(mod_enable, S_IRUSR | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable); -static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(mod_param_1_note_value, S_IRUSR | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value); -static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, +static DEVICE_ATTR(mod_param_2, S_IRUSR | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2); -static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, +static DEVICE_ATTR(mod_param_3, S_IRUSR | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3); -static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, +static DEVICE_ATTR(mod_param_4, S_IRUSR | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4); -static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, +static DEVICE_ATTR(mod_param_5, S_IRUSR | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5); -static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, +static DEVICE_ATTR(mod_volume_mix, S_IRUSR | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix); -static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, +static DEVICE_ATTR(mod_pre_post, S_IRUSR | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post); -static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(modulation_model, S_IRUSR | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model); -static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_3_frequency, S_IRUSR | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency); -static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IRUSR | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass); -static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(mod_param_1_double_precision, S_IRUSR | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision); -static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(delay_param_1_double_precision, S_IRUSR | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision); -static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, +static DEVICE_ATTR(eq_enable, S_IRUSR | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable); -static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap); -static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(tap, S_IRUSR | S_IRUGO, pod_get_tap, pod_set_tap); +static DEVICE_ATTR(volume_tweak_pedal_assign, S_IRUSR | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign); -static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_5_frequency, S_IRUSR | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency); -static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner); -static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, +static DEVICE_ATTR(tuner, S_IRUSR | S_IRUGO, pod_get_tuner, pod_set_tuner); +static DEVICE_ATTR(mic_selection, S_IRUSR | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection); -static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, +static DEVICE_ATTR(cabinet_model, S_IRUSR | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model); -static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, +static DEVICE_ATTR(stomp_model, S_IRUSR | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model); -static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, +static DEVICE_ATTR(roomlevel, S_IRUSR | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel); -static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_4_frequency, S_IRUSR | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency); -static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(band_6_frequency, S_IRUSR | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency); -static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(stomp_param_1_note_value, S_IRUSR | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value); -static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, +static DEVICE_ATTR(stomp_param_2, S_IRUSR | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2); -static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, +static DEVICE_ATTR(stomp_param_3, S_IRUSR | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3); -static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, +static DEVICE_ATTR(stomp_param_4, S_IRUSR | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4); -static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, +static DEVICE_ATTR(stomp_param_5, S_IRUSR | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5); -static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, +static DEVICE_ATTR(stomp_param_6, S_IRUSR | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6); -static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(amp_switch_select, S_IRUSR | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select); -static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, +static DEVICE_ATTR(delay_param_4, S_IRUSR | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4); -static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, +static DEVICE_ATTR(delay_param_5, S_IRUSR | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5); -static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, +static DEVICE_ATTR(delay_pre_post, S_IRUSR | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post); -static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, +static DEVICE_ATTR(delay_model, S_IRUSR | S_IRUGO, pod_get_delay_model, pod_set_delay_model); -static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(delay_verb_model, S_IRUSR | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model); -static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, +static DEVICE_ATTR(tempo_msb, S_IRUSR | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb); -static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, +static DEVICE_ATTR(tempo_lsb, S_IRUSR | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb); -static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, +static DEVICE_ATTR(wah_model, S_IRUSR | S_IRUGO, pod_get_wah_model, pod_set_wah_model); -static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, +static DEVICE_ATTR(bypass_volume, S_IRUSR | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume); -static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, +static DEVICE_ATTR(fx_loop_on_off, S_IRUSR | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off); -static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(tweak_param_select, S_IRUSR | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select); -static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, +static DEVICE_ATTR(amp1_engage, S_IRUSR | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage); -static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, +static DEVICE_ATTR(band_1_gain, S_IRUSR | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain); -static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IRUSR | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); -static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, +static DEVICE_ATTR(band_2_gain, S_IRUSR | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain); -static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IRUSR | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); -static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, +static DEVICE_ATTR(band_3_gain, S_IRUSR | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain); -static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IRUSR | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass); -static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IRUSR | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); -static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, +static DEVICE_ATTR(band_4_gain, S_IRUSR | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain); -static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, +static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IRUSR | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass); static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write); static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 4304dfe6c16..5388bd7226c 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev, return count; } -static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(midi_mask_transmit, S_IRUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); -static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(midi_mask_receive, S_IRUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); /* MIDI device destructor */ diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index e54770e34d2..9b34338178d 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev, return count; } -static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume, +static DEVICE_ATTR(impulse_volume, S_IRUSR | S_IRUGO, pcm_get_impulse_volume, pcm_set_impulse_volume); -static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period, +static DEVICE_ATTR(impulse_period, S_IRUSR | S_IRUGO, pcm_get_impulse_period, pcm_set_impulse_period); #endif diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 22e2cedcacf..ed27ac19501 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1); #undef GET_SYSTEM_PARAM /* POD special files: */ -static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, +static DEVICE_ATTR(channel, S_IRUSR | S_IRUGO, pod_get_channel, pod_set_channel); static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write); static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write); static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write); -static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump); -static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, +static DEVICE_ATTR(dump, S_IRUSR | S_IRUGO, pod_get_dump, pod_set_dump); +static DEVICE_ATTR(dump_buf, S_IRUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf); -static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish); +static DEVICE_ATTR(finish, S_IRUSR, line6_nop_read, pod_set_finish); static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write); -static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(midi_postprocess, S_IRUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); -static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, +static DEVICE_ATTR(monitor_level, S_IRUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level); static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write); static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write); -static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(retrieve_amp_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_amp_setup); -static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(retrieve_channel, S_IRUSR, line6_nop_read, pod_set_retrieve_channel); -static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(retrieve_effects_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_effects_setup); -static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, +static DEVICE_ATTR(routing, S_IRUSR | S_IRUGO, pod_get_routing, pod_set_routing); static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write); -static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(store_amp_setup, S_IRUSR, line6_nop_read, pod_set_store_amp_setup); -static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(store_channel, S_IRUSR, line6_nop_read, pod_set_store_channel); -static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, +static DEVICE_ATTR(store_effects_setup, S_IRUSR, line6_nop_read, pod_set_store_effects_setup); -static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, +static DEVICE_ATTR(tuner_freq, S_IRUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); -static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, +static DEVICE_ATTR(tuner_mute, S_IRUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute); static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write); static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write); #ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw); #endif /* control info callback */ diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 6a10b0f9749..6bcf0366e89 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev, return count; } -static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_red, S_IRUSR | S_IRUGO, line6_nop_read, toneport_set_led_red); -static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_green, S_IRUSR | S_IRUGO, line6_nop_read, toneport_set_led_green); static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 894eee7f231..803bc752ab8 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev, #endif /* Variax workbench special files: */ -static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, +static DEVICE_ATTR(model, S_IRUSR | S_IRUGO, variax_get_model, variax_set_model); -static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, +static DEVICE_ATTR(volume, S_IRUSR | S_IRUGO, variax_get_volume, variax_set_volume); -static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone); +static DEVICE_ATTR(tone, S_IRUSR | S_IRUGO, variax_get_tone, variax_set_tone); static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write); static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write); static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write); -static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, +static DEVICE_ATTR(active, S_IRUSR | S_IRUGO, variax_get_active, variax_set_active); static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write); #ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); -static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2); +static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw2, S_IRUSR, line6_nop_read, variax_set_raw2); #endif /* -- cgit v1.2.3-70-g09d2 From 5fb5d38fc268b8285125b213b9b2ded9322a371c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 12 Nov 2010 08:08:35 +0300 Subject: Staging: speakup: free after input_unregister_device() input_unregister_device() frees the device so the call to input_free_device() is a double free. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/fakekey.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c index adb93f21c0d..65b231178f0 100644 --- a/drivers/staging/speakup/fakekey.c +++ b/drivers/staging/speakup/fakekey.c @@ -62,7 +62,6 @@ void speakup_remove_virtual_keyboard(void) { if (virt_keyboard != NULL) { input_unregister_device(virt_keyboard); - input_free_device(virt_keyboard); virt_keyboard = NULL; } } -- cgit v1.2.3-70-g09d2 From ebba26f4a8d0c137a2d365b6bded2a0d7fcd1d06 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 12 Nov 2010 08:04:43 +0300 Subject: Staging: quickstart: free after input_unregister_device() input_unregister_device() releases "quickstart_input" so the input_free_device() is a double free. Also I noticed that there is a memory leak if the call to input_register_device() fails. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index d746715d3d8..d83bec876d2 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -355,7 +355,6 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type) static void quickstart_exit(void) { input_unregister_device(quickstart_input); - input_free_device(quickstart_input); device_remove_file(&pf_device->dev, &dev_attr_pressed_button); device_remove_file(&pf_device->dev, &dev_attr_buttons); @@ -375,6 +374,7 @@ static int __init quickstart_init_input(void) { struct quickstart_btn **ptr = &quickstart_data.btn_lst; int count; + int ret; quickstart_input = input_allocate_device(); @@ -391,7 +391,13 @@ static int __init quickstart_init_input(void) ptr = &((*ptr)->next); } - return input_register_device(quickstart_input); + ret = input_register_device(quickstart_input); + if (ret) { + input_free_device(quickstart_input); + return ret; + } + + return 0; } static int __init quickstart_init(void) -- cgit v1.2.3-70-g09d2 From 61838261edaf621d1e8ee4ea9d7c052f7d783ca4 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sat, 13 Nov 2010 19:46:50 +0100 Subject: staging: comedi: fix memory leak Instead of freeing outBuffer, inBuffer gets freed twice. Signed-off-by: Nicolas Kaiser Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1f177a67ff1..de784ff08ca 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2295,8 +2295,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->inBuffer = NULL; kfree(usbduxsub_tmp->insnBuffer); usbduxsub_tmp->insnBuffer = NULL; - kfree(usbduxsub_tmp->inBuffer); - usbduxsub_tmp->inBuffer = NULL; + kfree(usbduxsub_tmp->outBuffer); + usbduxsub_tmp->outBuffer = NULL; kfree(usbduxsub_tmp->dac_commands); usbduxsub_tmp->dac_commands = NULL; kfree(usbduxsub_tmp->dux_commands); -- cgit v1.2.3-70-g09d2 From f36d83a8cb7224f45fdfa1129a616dff56479a09 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 13 Nov 2010 13:01:56 -0600 Subject: staging: rtl8187se: Change panic to warn when RF switch turned off This driver issues a kernel panic over conditions that do not justify such drastic action. Change these to log entries with a stack dump. This patch fixes the system crash reported in https://bugs.launchpad.net/ubuntu/+source/linux/+bug/674285. Signed-off-by: Larry Finger Reported-and-Tested-by: Robie Basik Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8185b_init.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 46000d72f4c..3bdf9b31cc4 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -264,8 +264,12 @@ HwHSSIThreeWire( udelay(10); } - if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) - panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp); + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { + printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" + " %#X RE|WE bits are not clear!!\n", u1bTmp); + dump_stack(); + return 0; + } /* RTL8187S HSSI Read/Write Function */ u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); @@ -298,13 +302,23 @@ HwHSSIThreeWire( int idx; int ByteCnt = nDataBufBitCnt / 8; /* printk("%d\n",nDataBufBitCnt); */ - if ((nDataBufBitCnt % 8) != 0) - panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n", - nDataBufBitCnt); + if ((nDataBufBitCnt % 8) != 0) { + printk(KERN_ERR "rtl8187se: " + "HwThreeWire(): nDataBufBitCnt(%d)" + " should be multiple of 8!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt += 8; + nDataBufBitCnt &= ~7; + } - if (nDataBufBitCnt > 64) - panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); + if (nDataBufBitCnt > 64) { + printk(KERN_ERR "rtl8187se: HwThreeWire():" + " nDataBufBitCnt(%d) should <= 64!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt = 64; + } for (idx = 0; idx < ByteCnt; idx++) write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); -- cgit v1.2.3-70-g09d2 From 832855354b5863d141ecfc563e78063978c6f29f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 12 Nov 2010 08:11:13 +0300 Subject: Staging: rtl8712: signedness bug in init PollingCnt is 20 and that means we loop 20 times and then run the timeout code. After the end of the loop PollingCnt should be -1 but because it's an unsigned char, it's actually 255 and the timeout code never runs. Signed-off-by: Dan Carpenter Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/usb_halinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c index f6569dce301..0e9483bbabe 100644 --- a/drivers/staging/rtl8712/usb_halinit.c +++ b/drivers/staging/rtl8712/usb_halinit.c @@ -37,7 +37,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) { u8 val8 = 0; u8 ret = _SUCCESS; - u8 PollingCnt = 20; + int PollingCnt = 20; struct registry_priv *pregistrypriv = &padapter->registrypriv; if (pregistrypriv->chip_version == RTL8712_FPGA) { -- cgit v1.2.3-70-g09d2 From 3251627c943f1cfc5bfad7c38d4e8d85cf44c6d8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 11:58:26 +0300 Subject: Staging: intel_sst: fix memory leak The original code set "str_info->decode_ibuf" to NULL so the kfree() is no-op. Signed-off-by: Dan Carpenter Acked-by: Harsha Priya Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst_stream_encoded.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c index fbae39fda5c..5c455608b02 100644 --- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c +++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c @@ -1269,7 +1269,7 @@ finish: dbufs->output_bytes_produced = total_output; str_info->status = str_info->prev; str_info->prev = STREAM_DECODE; - str_info->decode_ibuf = NULL; kfree(str_info->decode_ibuf); + str_info->decode_ibuf = NULL; return retval; } -- cgit v1.2.3-70-g09d2 From e8364bb8d041c0fd92d69a17ff19f535e1d1c187 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 10 Nov 2010 15:11:07 +0530 Subject: ath9k: Remove pm_qos request after hw unregister. Update pm_qos before removing it in deinit_device to prevent this warning: pm_qos_update_request() called for unknown object. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 6a0d99eff40..92bc5c5f487 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -817,8 +817,6 @@ void ath9k_deinit_device(struct ath_softc *sc) ath9k_ps_wakeup(sc); - pm_qos_remove_request(&ath9k_pm_qos_req); - wiphy_rfkill_stop_polling(sc->hw->wiphy); ath_deinit_leds(sc); @@ -832,6 +830,7 @@ void ath9k_deinit_device(struct ath_softc *sc) } ieee80211_unregister_hw(hw); + pm_qos_remove_request(&ath9k_pm_qos_req); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); -- cgit v1.2.3-70-g09d2 From 32b089558c54792028f14ae830ca7c0a8d9ac9a3 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 10 Nov 2010 17:51:24 +0530 Subject: ath9k_htc: Update usb device ID list Added new VID/PIDs into supported devices list Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f7ec31b4ddd..0e1227769e9 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -36,8 +36,13 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */ + { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ + { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ + { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */ { }, }; -- cgit v1.2.3-70-g09d2 From 7cbf2611dac8d5f76fe64795a9426b8c97e6c3f8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 10 Nov 2010 17:51:25 +0530 Subject: ath9k_htc: Add new devices into AR7010 Treat new PIDs (0xA704, 0x1200) as AR7010 devices. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++ drivers/net/wireless/ath/ath9k/reg.h | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 0e1227769e9..dfb6560dab9 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -811,6 +811,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) case 0x7010: case 0x7015: case 0x9018: + case 0xA704: + case 0x1200: firm_offset = AR7010_FIRMWARE_TEXT; break; default: @@ -933,6 +935,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, case 0x7010: case 0x7015: case 0x9018: + case 0xA704: + case 0x1200: if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) hif_dev->fw_name = FIRMWARE_AR7010_1_1; else diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 3d7b97f1b3a..7c8a38d0456 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -249,6 +249,8 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) case 0x7010: case 0x7015: case 0x9018: + case 0xA704: + case 0x1200: priv->htc->credits = 45; break; default: diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index fa05b711e5c..52ee82d6796 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -866,7 +866,9 @@ #define AR_DEVID_7010(_ah) \ (((_ah)->hw_version.devid == 0x7010) || \ ((_ah)->hw_version.devid == 0x7015) || \ - ((_ah)->hw_version.devid == 0x9018)) + ((_ah)->hw_version.devid == 0x9018) || \ + ((_ah)->hw_version.devid == 0xA704) || \ + ((_ah)->hw_version.devid == 0x1200)) #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 -- cgit v1.2.3-70-g09d2 From b5261cf4f3860bd772346a3e692683b6144dd44c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 10 Nov 2010 17:51:26 +0530 Subject: ath9k_hw: Set proper eeprom offset for AR9287 HTC devices AR9287 based PCI & USB devices are differed in eeprom start offset. So set proper the offset for HTC devices to read nvram correctly. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- drivers/net/wireless/ath/ath9k/reg.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 966b9496a9d..195406db3bd 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) int addr, eep_start_loc; eep_data = (u16 *)eep; - if (ah->hw_version.devid == 0x7015) + if (AR9287_HTC_DEVID(ah)) eep_start_loc = AR9287_HTC_EEP_START_LOC; else eep_start_loc = AR9287_EEP_START_LOC; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 52ee82d6796..dddf579aacf 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -870,6 +870,10 @@ ((_ah)->hw_version.devid == 0xA704) || \ ((_ah)->hw_version.devid == 0x1200)) +#define AR9287_HTC_DEVID(_ah) \ + (((_ah)->hw_version.devid == 0x7015) || \ + ((_ah)->hw_version.devid == 0x1200)) + #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 #define AR_RAD2133_SREV_MAJOR 0xd0 -- cgit v1.2.3-70-g09d2 From a80c49dbb6cd389fd5b0d79f850b56322475d00b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 15 Nov 2010 21:11:12 +0100 Subject: serial8250: Mark console as CON_ANYTIME While trying to debug a cpu-hotplug issue I noticed printk() stopped working once the cpu got marked offline, since the 8250 serial console doesn't have any per-cpu resources the CON_ANYTIME bit is the safe and documented way to make it work again. Signed-off-by: Peter Zijlstra Signed-off-by: Greg Kroah-Hartman --- drivers/serial/8250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 4d8e14b7aa9..09a550860dc 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2872,7 +2872,7 @@ static struct console serial8250_console = { .device = uart_console_device, .setup = serial8250_console_setup, .early_setup = serial8250_console_early_setup, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_ANYTIME, .index = -1, .data = &serial8250_reg, }; -- cgit v1.2.3-70-g09d2 From 3d091a6f703906c5680855ff29bd94d051c8c6d8 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Mon, 8 Nov 2010 17:58:35 +0800 Subject: USB: EHCI: AMD periodic frame list table quirk On AMD SB700/SB800/Hudson-2/3 platforms, USB EHCI controller may read/write to memory space not allocated to USB controller if there is longer than normal latency on DMA read encountered. In this condition the exposure will be encountered only if the driver has following format of Periodic Frame List link pointer structure: For any idle periodic schedule, the Frame List link pointers that have the T-bit set to 1 intending to terminate the use of frame list link pointer as a physical memory pointer. Idle periodic schedule Frame List Link pointer shoule be in the following format to avoid the issue: Frame list link pointer should be always contains a valid pointer to a inactive QHead with T-bit set to 0. Signed-off-by: Andiry Xu Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mem.c | 26 ++++++++++++++++++++++++-- drivers/usb/host/ehci-pci.c | 13 +++++++++++++ drivers/usb/host/ehci-sched.c | 21 ++++++++++++++++++--- drivers/usb/host/ehci.h | 2 ++ 4 files changed, 57 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index d36e4e75e08..12f70c302b0 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -141,6 +141,10 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci) qh_put (ehci->async); ehci->async = NULL; + if (ehci->dummy) + qh_put(ehci->dummy); + ehci->dummy = NULL; + /* DMA consistent memory and pools */ if (ehci->qtd_pool) dma_pool_destroy (ehci->qtd_pool); @@ -227,8 +231,26 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) if (ehci->periodic == NULL) { goto fail; } - for (i = 0; i < ehci->periodic_size; i++) - ehci->periodic [i] = EHCI_LIST_END(ehci); + + if (ehci->use_dummy_qh) { + struct ehci_qh_hw *hw; + ehci->dummy = ehci_qh_alloc(ehci, flags); + if (!ehci->dummy) + goto fail; + + hw = ehci->dummy->hw; + hw->hw_next = EHCI_LIST_END(ehci); + hw->hw_qtd_next = EHCI_LIST_END(ehci); + hw->hw_alt_next = EHCI_LIST_END(ehci); + hw->hw_token &= ~QTD_STS_ACTIVE; + ehci->dummy->hw = hw; + + for (i = 0; i < ehci->periodic_size; i++) + ehci->periodic[i] = ehci->dummy->qh_dma; + } else { + for (i = 0; i < ehci->periodic_size; i++) + ehci->periodic[i] = EHCI_LIST_END(ehci); + } /* software shadow of hardware table */ ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index a1e8d273103..01bb72b7183 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -103,6 +103,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd) if (retval) return retval; + if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) || + (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) { + /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may + * read/write memory space which does not belong to it when + * there is NULL pointer with T-bit set to 1 in the frame list + * table. To avoid the issue, the frame list link pointer + * should always contain a valid pointer to a inactive qh. + */ + ehci->use_dummy_qh = 1; + ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI " + "dummy qh workaround\n"); + } + /* data structure init */ retval = ehci_init(hcd); if (retval) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a92526d6e5a..d9f78eb2657 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -98,7 +98,14 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) */ *prev_p = *periodic_next_shadow(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); - *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); + + if (!ehci->use_dummy_qh || + *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)) + != EHCI_LIST_END(ehci)) + *hw_p = *shadow_next_periodic(ehci, &here, + Q_NEXT_TYPE(ehci, *hw_p)); + else + *hw_p = ehci->dummy->qh_dma; } /* how many of the uframe's 125 usecs are allocated? */ @@ -2335,7 +2342,11 @@ restart: * pointer for much longer, if at all. */ *q_p = q.itd->itd_next; - *hw_p = q.itd->hw_next; + if (!ehci->use_dummy_qh || + q.itd->hw_next != EHCI_LIST_END(ehci)) + *hw_p = q.itd->hw_next; + else + *hw_p = ehci->dummy->qh_dma; type = Q_NEXT_TYPE(ehci, q.itd->hw_next); wmb(); modified = itd_complete (ehci, q.itd); @@ -2368,7 +2379,11 @@ restart: * URB completion. */ *q_p = q.sitd->sitd_next; - *hw_p = q.sitd->hw_next; + if (!ehci->use_dummy_qh || + q.sitd->hw_next != EHCI_LIST_END(ehci)) + *hw_p = q.sitd->hw_next; + else + *hw_p = ehci->dummy->qh_dma; type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); wmb(); modified = sitd_complete (ehci, q.sitd); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index bde823f704e..ba8eab366b8 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -73,6 +73,7 @@ struct ehci_hcd { /* one per controller */ /* async schedule support */ struct ehci_qh *async; + struct ehci_qh *dummy; /* For AMD quirk use */ struct ehci_qh *reclaim; unsigned scanning : 1; @@ -131,6 +132,7 @@ struct ehci_hcd { /* one per controller */ unsigned need_io_watchdog:1; unsigned broken_periodic:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ + unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) -- cgit v1.2.3-70-g09d2 From f52022b53bac3228620e490abbe2ccb1e87ab060 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 9 Nov 2010 09:16:39 +0800 Subject: USB: isp1362-hcd - fix section mismatch warning Fix section mismatch warning by using "__devinit" annotation for isp1362_probe. WARNING: drivers/usb/host/isp1362-hcd.o(.data+0x0): Section mismatch in reference from the variable isp1362_driver to the function .init.text:isp1362_probe() The variable isp1362_driver references the function __init isp1362_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Signed-off-by: Axel Lin Acked-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1362-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 8196fa11fec..97cce59ff76 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2684,7 +2684,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev) return 0; } -static int __init isp1362_probe(struct platform_device *pdev) +static int __devinit isp1362_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct isp1362_hcd *isp1362_hcd; -- cgit v1.2.3-70-g09d2 From b48809518631880207796b4aab0fc39c2f036754 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 16 Nov 2010 11:51:32 +0100 Subject: USB: gadget: AT91: fix typo in atmel_usba_udc driver compile fix for bug introduced by 969affff547027) Signed-off-by: Josh Wu Cc: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/atmel_usba_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index b5e20e873cb..717ff653fa2 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -2017,7 +2017,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) } } else { /* gpio_request fail so use -EINVAL for gpio_is_valid */ - ubc->vbus_pin = -EINVAL; + udc->vbus_pin = -EINVAL; } } -- cgit v1.2.3-70-g09d2 From 02e2c51ba3e80acde600721ea784c3ef84da5ea1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 16 Nov 2010 10:57:37 -0500 Subject: USB: EHCI: fix obscure race in ehci_endpoint_disable This patch (as1435) fixes an obscure and unlikely race in ehci-hcd. When an async URB is unlinked, the corresponding QH is removed from the async list. If the QH's endpoint is then disabled while the URB is being given back, ehci_endpoint_disable() won't find the QH on the async list, causing it to believe that the QH has been lost. This will lead to a memory leak at best and quite possibly to an oops. The solution is to trust usbcore not to lose track of endpoints. If the QH isn't on the async list then it doesn't need to be taken off the list, but the driver should still wait for the QH to become IDLE before disabling it. In theory this fixes Bugzilla #20182. In fact the race is so rare that it's not possible to tell whether the bug is still present. However, adding delays and making other changes to force the race seems to show that the patch works. Signed-off-by: Alan Stern Reported-by: Stefan Richter CC: David Brownell CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 502a7e6fef4..e9062806d4a 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1063,10 +1063,11 @@ rescan: tmp && tmp != qh; tmp = tmp->qh_next.qh) continue; - /* periodic qh self-unlinks on empty */ - if (!tmp) - goto nogood; - unlink_async (ehci, qh); + /* periodic qh self-unlinks on empty, and a COMPLETING qh + * may already be unlinked. + */ + if (tmp) + unlink_async(ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: @@ -1083,7 +1084,6 @@ idle_timeout: } /* else FALL THROUGH */ default: -nogood: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. */ -- cgit v1.2.3-70-g09d2 From 1c6969ec8e6328e8d288fc585310e9e52fc9db04 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Nov 2010 14:55:33 -0800 Subject: xen/evtchn: clear secondary CPUs' cpu_evtchn_mask[] after restore To bind all event channels to CPU#0, it is not sufficient to set all of its cpu_evtchn_mask[] bits; all other CPUs also need to get their bits cleared. Otherwise, evtchn_do_upcall() will start handling interrupts on CPUs they're not intended to run on, which can be particularly bad for per-CPU ones. [ linux-2.6.18-xen.hg 7de7453dee36 ] Signed-off-by: Jan Beulich Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/events.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 321a0c8346e..d770b8c8885 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -286,9 +286,9 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) static void init_evtchn_cpu_bindings(void) { + int i; #ifdef CONFIG_SMP struct irq_desc *desc; - int i; /* By default all event channels notify CPU#0. */ for_each_irq_desc(i, desc) { @@ -296,7 +296,10 @@ static void init_evtchn_cpu_bindings(void) } #endif - memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s)); + for_each_possible_cpu(i) + memset(cpu_evtchn_mask(i), + (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s)); + } static inline void clear_evtchn(int port) -- cgit v1.2.3-70-g09d2 From e04195644eea7c6c14007922257704ec67156cd1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 16 Nov 2010 14:56:47 -0800 Subject: xen/events: use locked set|clear_bit() for cpu_evtchn_mask The per-cpu event channel masks can be updated unlocked from multiple CPUs, so use the locked variant. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index d770b8c8885..d6d4f76ed50 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -278,8 +278,8 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu)); #endif - __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); - __set_bit(chn, cpu_evtchn_mask(cpu)); + clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); + set_bit(chn, cpu_evtchn_mask(cpu)); irq_info[irq].cpu = cpu; } -- cgit v1.2.3-70-g09d2 From 902bca00dc6e3b3ff5fbb1e32e5dbb45d5f30579 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 6 Nov 2010 12:36:13 +0100 Subject: firewire: net: count stats.tx_packets and stats.tx_bytes Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 18fdd9703b4..e2e968e732b 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -906,6 +906,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask); static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) { struct fwnet_device *dev = ptask->dev; + struct sk_buff *skb = ptask->skb; unsigned long flags; bool free; @@ -916,8 +917,11 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) /* Check whether we or the networking TX soft-IRQ is last user. */ free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); - if (ptask->outstanding_pkts == 0) + if (ptask->outstanding_pkts == 0) { list_del(&ptask->pt_link); + dev->netdev->stats.tx_packets++; + dev->netdev->stats.tx_bytes += skb->len; + } spin_unlock_irqrestore(&dev->lock, flags); @@ -926,7 +930,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) u16 fg_off; u16 datagram_label; u16 lf; - struct sk_buff *skb; /* Update the ptask to point to the next fragment and send it */ lf = fwnet_get_hdr_lf(&ptask->hdr); @@ -953,7 +956,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) datagram_label = fwnet_get_hdr_dgl(&ptask->hdr); break; } - skb = ptask->skb; + skb_pull(skb, ptask->max_payload); if (ptask->outstanding_pkts > 1) { fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, -- cgit v1.2.3-70-g09d2 From 7ee11fa8d0a84b05cefe12b0bebc05ab0ea89cd6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 6 Nov 2010 16:57:28 +0100 Subject: firewire: net: fix memory leaks a) fwnet_transmit_packet_done used to poison ptask->pt_link by list_del. If fwnet_send_packet checked later whether it was responsible to clean up (in the border case that the TX soft IRQ was outpaced by the AT-req tasklet on another CPU), it missed this because ptask->pt_link was no longer shown as empty. b) If fwnet_write_complete got an rcode other than RCODE_COMPLETE, we missed to free the skb and ptask entirely. Also, count stats.tx_dropped and stats.tx_errors when rcode != 0. Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index e2e968e732b..3a27cee5bf2 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -916,9 +916,10 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) /* Check whether we or the networking TX soft-IRQ is last user. */ free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); + if (free) + list_del(&ptask->pt_link); if (ptask->outstanding_pkts == 0) { - list_del(&ptask->pt_link); dev->netdev->stats.tx_packets++; dev->netdev->stats.tx_bytes += skb->len; } @@ -973,6 +974,31 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) fwnet_free_ptask(ptask); } +static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) +{ + struct fwnet_device *dev = ptask->dev; + unsigned long flags; + bool free; + + spin_lock_irqsave(&dev->lock, flags); + + /* One fragment failed; don't try to send remaining fragments. */ + ptask->outstanding_pkts = 0; + + /* Check whether we or the networking TX soft-IRQ is last user. */ + free = !list_empty(&ptask->pt_link); + if (free) + list_del(&ptask->pt_link); + + dev->netdev->stats.tx_dropped++; + dev->netdev->stats.tx_errors++; + + spin_unlock_irqrestore(&dev->lock, flags); + + if (free) + fwnet_free_ptask(ptask); +} + static void fwnet_write_complete(struct fw_card *card, int rcode, void *payload, size_t length, void *data) { @@ -980,11 +1006,12 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, ptask = data; - if (rcode == RCODE_COMPLETE) + if (rcode == RCODE_COMPLETE) { fwnet_transmit_packet_done(ptask); - else + } else { fw_error("fwnet_write_complete: failed: %x\n", rcode); - /* ??? error recovery */ + fwnet_transmit_packet_failed(ptask); + } } static int fwnet_send_packet(struct fwnet_packet_task *ptask) -- cgit v1.2.3-70-g09d2 From 48553011cea504796e513350740781ac6745f556 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 6 Nov 2010 23:18:23 +0100 Subject: firewire: net: replace lists by counters The current transmit code does not at all make use of - fwnet_device.packet_list and only very limited use of - fwnet_device.broadcasted_list, - fwnet_device.queued_packets. Their current function is to track whether the TX soft-IRQ finished dealing with an skb when the AT-req tasklet takes over, and to discard pending tx datagrams (if there are any) when the local node is removed. The latter does actually contain a race condition bug with TX soft-IRQ and AT-req tasklet. Instead of these lists and the corresponding link in fwnet_packet_task, - a flag in fwnet_packet_task to track whether fwnet_tx is done, - a counter of queued datagrams in fwnet_device do the job as well. The above mentioned theoretic race condition is resolved by letting fwnet_remove sleep until all datagrams were flushed. It may sleep almost arbitrarily long since fwnet_remove is executed in the context of a multithreaded (concurrency managed) workqueue. The type of max_payload is changed to u16 here to avoid waste in struct fwnet_packet_task. This value cannot exceed 4096 per IEEE 1394:2008 table 16-18 (or 32678 per specification of packet headers, if there is ever going to be something else than beta mode). Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 73 ++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 3a27cee5bf2..d2d488b9cd9 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -169,15 +170,8 @@ struct fwnet_device { struct fw_address_handler handler; u64 local_fifo; - /* List of packets to be sent */ - struct list_head packet_list; - /* - * List of packets that were broadcasted. When we get an ISO interrupt - * one of them has been sent - */ - struct list_head broadcasted_list; - /* List of packets that have been sent but not yet acked */ - struct list_head sent_list; + /* Number of tx datagrams that have been queued but not yet acked */ + int queued_datagrams; struct list_head peer_list; struct fw_card *card; @@ -195,7 +189,7 @@ struct fwnet_peer { unsigned pdg_size; /* pd_list size */ u16 datagram_label; /* outgoing datagram label */ - unsigned max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ + u16 max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ int node_id; int generation; unsigned speed; @@ -203,22 +197,18 @@ struct fwnet_peer { /* This is our task struct. It's used for the packet complete callback. */ struct fwnet_packet_task { - /* - * ptask can actually be on dev->packet_list, dev->broadcasted_list, - * or dev->sent_list depending on its current state. - */ - struct list_head pt_link; struct fw_transaction transaction; struct rfc2734_header hdr; struct sk_buff *skb; struct fwnet_device *dev; int outstanding_pkts; - unsigned max_payload; u64 fifo_addr; u16 dest_node; + u16 max_payload; u8 generation; u8 speed; + u8 enqueued; }; /* @@ -915,9 +905,9 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) ptask->outstanding_pkts--; /* Check whether we or the networking TX soft-IRQ is last user. */ - free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); + free = (ptask->outstanding_pkts == 0 && ptask->enqueued); if (free) - list_del(&ptask->pt_link); + dev->queued_datagrams--; if (ptask->outstanding_pkts == 0) { dev->netdev->stats.tx_packets++; @@ -986,9 +976,9 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) ptask->outstanding_pkts = 0; /* Check whether we or the networking TX soft-IRQ is last user. */ - free = !list_empty(&ptask->pt_link); + free = ptask->enqueued; if (free) - list_del(&ptask->pt_link); + dev->queued_datagrams--; dev->netdev->stats.tx_dropped++; dev->netdev->stats.tx_errors++; @@ -1069,9 +1059,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) spin_lock_irqsave(&dev->lock, flags); /* If the AT tasklet already ran, we may be last user. */ - free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); + free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); if (!free) - list_add_tail(&ptask->pt_link, &dev->broadcasted_list); + ptask->enqueued = true; + else + dev->queued_datagrams--; spin_unlock_irqrestore(&dev->lock, flags); @@ -1086,9 +1078,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) spin_lock_irqsave(&dev->lock, flags); /* If the AT tasklet already ran, we may be last user. */ - free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); + free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); if (!free) - list_add_tail(&ptask->pt_link, &dev->sent_list); + ptask->enqueued = true; + else + dev->queued_datagrams--; spin_unlock_irqrestore(&dev->lock, flags); @@ -1350,10 +1344,12 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) max_payload += RFC2374_FRAG_HDR_SIZE; } + dev->queued_datagrams++; + spin_unlock_irqrestore(&dev->lock, flags); ptask->max_payload = max_payload; - INIT_LIST_HEAD(&ptask->pt_link); + ptask->enqueued = 0; fwnet_send_packet(ptask); @@ -1487,14 +1483,9 @@ static int fwnet_probe(struct device *_dev) dev->broadcast_rcv_context = NULL; dev->broadcast_xmt_max_payload = 0; dev->broadcast_xmt_datagramlabel = 0; - dev->local_fifo = FWNET_NO_FIFO_ADDR; - - INIT_LIST_HEAD(&dev->packet_list); - INIT_LIST_HEAD(&dev->broadcasted_list); - INIT_LIST_HEAD(&dev->sent_list); + dev->queued_datagrams = 0; INIT_LIST_HEAD(&dev->peer_list); - dev->card = card; dev->netdev = net; @@ -1552,7 +1543,7 @@ static int fwnet_remove(struct device *_dev) struct fwnet_peer *peer = dev_get_drvdata(_dev); struct fwnet_device *dev = peer->dev; struct net_device *net; - struct fwnet_packet_task *ptask, *pt_next; + int i; mutex_lock(&fwnet_device_mutex); @@ -1570,21 +1561,9 @@ static int fwnet_remove(struct device *_dev) dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); } - list_for_each_entry_safe(ptask, pt_next, - &dev->packet_list, pt_link) { - dev_kfree_skb_any(ptask->skb); - kmem_cache_free(fwnet_packet_task_cache, ptask); - } - list_for_each_entry_safe(ptask, pt_next, - &dev->broadcasted_list, pt_link) { - dev_kfree_skb_any(ptask->skb); - kmem_cache_free(fwnet_packet_task_cache, ptask); - } - list_for_each_entry_safe(ptask, pt_next, - &dev->sent_list, pt_link) { - dev_kfree_skb_any(ptask->skb); - kmem_cache_free(fwnet_packet_task_cache, ptask); - } + for (i = 0; dev->queued_datagrams && i < 5; i++) + ssleep(1); + WARN_ON(dev->queued_datagrams); list_del(&dev->dev_link); free_netdev(net); -- cgit v1.2.3-70-g09d2 From b2268830f5cf29d94b3e4a2af0b795a8f28776fe Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 14 Nov 2010 14:35:40 +0100 Subject: firewire: net: throttle TX queue before running out of tlabels This prevents firewire-net from submitting write requests in fast succession until failure due to all 64 transaction labels were used up for unfinished split transactions. The netif_stop/wake_queue API is used for this purpose. Without this stop/wake mechanism, datagrams were simply lost whenever the tlabel pool was exhausted. Plus, tlabel exhaustion by firewire-net also prevented other unrelated outbound transactions to be initiated. The chosen queue depth was checked by me to hit the maximum possible throughput with an OS X peer whose receive DMA is good enough to never reject requests due to busy inbound request FIFO. Current Linux peers show a mixed picture of -5%...+15% change in bandwidth; their current bottleneck are RCODE_BUSY situations (fewer or more, depending on TX queue depth) due to too small AR buffer in firewire-ohci. Maxim Levitsky tested this change with similar watermarks with a Linux peer and some pending firewire-ohci improvements that address the RCODE_BUSY problem and confirmed that these TX queue limits are good. Note: This removes some netif_wake_queue from reception code paths. They were apparently copy&paste artefacts from a nonsensical netif_wake_queue use in the older eth1394 driver. This belongs only into the transmit path. Signed-off-by: Stefan Richter Tested-by: Maxim Levitsky --- drivers/firewire/net.c | 59 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index d2d488b9cd9..1a467a91fb0 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -27,8 +27,14 @@ #include #include -#define FWNET_MAX_FRAGMENTS 25 /* arbitrary limit */ -#define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16 * 1024 ? 4 : 2) +/* rx limits */ +#define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */ +#define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16*1024 ? 4 : 2) + +/* tx limits */ +#define FWNET_MAX_QUEUED_DATAGRAMS 20 /* < 64 = number of tlabels */ +#define FWNET_MIN_QUEUED_DATAGRAMS 10 /* should keep AT DMA busy enough */ +#define FWNET_TX_QUEUE_LEN FWNET_MAX_QUEUED_DATAGRAMS /* ? */ #define IEEE1394_BROADCAST_CHANNEL 31 #define IEEE1394_ALL_NODES (0xffc0 | 0x003f) @@ -640,8 +646,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, net->stats.rx_packets++; net->stats.rx_bytes += skb->len; } - if (netif_queue_stopped(net)) - netif_wake_queue(net); return 0; @@ -650,8 +654,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, net->stats.rx_dropped++; dev_kfree_skb_any(skb); - if (netif_queue_stopped(net)) - netif_wake_queue(net); return -ENOENT; } @@ -783,15 +785,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, * Datagram is not complete, we're done for the * moment. */ - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; + retval = 0; fail: spin_unlock_irqrestore(&dev->lock, flags); - if (netif_queue_stopped(net)) - netif_wake_queue(net); - return retval; } @@ -891,6 +888,13 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask) kmem_cache_free(fwnet_packet_task_cache, ptask); } +/* Caller must hold dev->lock. */ +static void dec_queued_datagrams(struct fwnet_device *dev) +{ + if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS) + netif_wake_queue(dev->netdev); +} + static int fwnet_send_packet(struct fwnet_packet_task *ptask); static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) @@ -907,7 +911,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) /* Check whether we or the networking TX soft-IRQ is last user. */ free = (ptask->outstanding_pkts == 0 && ptask->enqueued); if (free) - dev->queued_datagrams--; + dec_queued_datagrams(dev); if (ptask->outstanding_pkts == 0) { dev->netdev->stats.tx_packets++; @@ -978,7 +982,7 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) /* Check whether we or the networking TX soft-IRQ is last user. */ free = ptask->enqueued; if (free) - dev->queued_datagrams--; + dec_queued_datagrams(dev); dev->netdev->stats.tx_dropped++; dev->netdev->stats.tx_errors++; @@ -1063,7 +1067,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) if (!free) ptask->enqueued = true; else - dev->queued_datagrams--; + dec_queued_datagrams(dev); spin_unlock_irqrestore(&dev->lock, flags); @@ -1082,7 +1086,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) if (!free) ptask->enqueued = true; else - dev->queued_datagrams--; + dec_queued_datagrams(dev); spin_unlock_irqrestore(&dev->lock, flags); @@ -1248,6 +1252,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) struct fwnet_peer *peer; unsigned long flags; + spin_lock_irqsave(&dev->lock, flags); + + /* Can this happen? */ + if (netif_queue_stopped(dev->netdev)) { + spin_unlock_irqrestore(&dev->lock, flags); + + return NETDEV_TX_BUSY; + } + ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC); if (ptask == NULL) goto fail; @@ -1266,9 +1279,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) proto = hdr_buf.h_proto; dg_size = skb->len; - /* serialize access to peer, including peer->datagram_label */ - spin_lock_irqsave(&dev->lock, flags); - /* * Set the transmission type for the packet. ARP packets and IP * broadcast packets are sent via GASP. @@ -1290,7 +1300,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid)); if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR) - goto fail_unlock; + goto fail; generation = peer->generation; dest_node = peer->node_id; @@ -1344,7 +1354,8 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) max_payload += RFC2374_FRAG_HDR_SIZE; } - dev->queued_datagrams++; + if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS) + netif_stop_queue(dev->netdev); spin_unlock_irqrestore(&dev->lock, flags); @@ -1355,9 +1366,9 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) return NETDEV_TX_OK; - fail_unlock: - spin_unlock_irqrestore(&dev->lock, flags); fail: + spin_unlock_irqrestore(&dev->lock, flags); + if (ptask) kmem_cache_free(fwnet_packet_task_cache, ptask); @@ -1403,7 +1414,7 @@ static void fwnet_init_dev(struct net_device *net) net->addr_len = FWNET_ALEN; net->hard_header_len = FWNET_HLEN; net->type = ARPHRD_IEEE1394; - net->tx_queue_len = 10; + net->tx_queue_len = FWNET_TX_QUEUE_LEN; } /* caller must hold fwnet_device_mutex */ -- cgit v1.2.3-70-g09d2 From c353103de8795358af1584088aa471571decb307 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 13:06:38 +0300 Subject: fbcmap: cleanup white space in fb_alloc_cmap() checkpatch.pl and Andrew Morton both complained about the indenting in fb_alloc_cmap() Signed-off-by: Dan Carpenter Signed-off-by: Paul Mundt --- drivers/video/fbcmap.c | 54 ++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index f53b9f1d6ab..a79b9762901 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -90,32 +90,38 @@ static const struct fb_cmap default_16_colors = { int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) { - int size = len*sizeof(u16); - - if (cmap->len != len) { - fb_dealloc_cmap(cmap); - if (!len) - return 0; - if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) - goto fail; - if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) - goto fail; - if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) - goto fail; - if (transp) { - if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) - goto fail; - } else - cmap->transp = NULL; - } - cmap->start = 0; - cmap->len = len; - fb_copy_cmap(fb_default_cmap(len), cmap); - return 0; + int size = len * sizeof(u16); + + if (cmap->len != len) { + fb_dealloc_cmap(cmap); + if (!len) + return 0; + + cmap->red = kmalloc(size, GFP_ATOMIC); + if (!cmap->red) + goto fail; + cmap->green = kmalloc(size, GFP_ATOMIC); + if (!cmap->green) + goto fail; + cmap->blue = kmalloc(size, GFP_ATOMIC); + if (!cmap->blue) + goto fail; + if (transp) { + cmap->transp = kmalloc(size, GFP_ATOMIC); + if (!cmap->transp) + goto fail; + } else { + cmap->transp = NULL; + } + } + cmap->start = 0; + cmap->len = len; + fb_copy_cmap(fb_default_cmap(len), cmap); + return 0; fail: - fb_dealloc_cmap(cmap); - return -ENOMEM; + fb_dealloc_cmap(cmap); + return -ENOMEM; } /** -- cgit v1.2.3-70-g09d2 From 1e7c7804884fc5751e3872f13498fd533325f8b2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 16 Nov 2010 12:11:02 +0300 Subject: fbcmap: integer overflow bug There is an integer overflow in fb_set_user_cmap() because cmap->len * 2 can wrap. It's basically harmless. Your terminal will be messed up until you type reset. This patch does three things to fix the bug. First, it checks the return value of fb_copy_cmap() in fb_alloc_cmap(). That is enough to fix address the overflow. Second it checks for the integer overflow in fb_set_user_cmap(). Lastly I wanted to cap "cmap->len" in fb_set_user_cmap() much lower because it gets used to determine the size of allocation. Unfortunately no one knows what the limit should be. Instead what this patch does is makes the allocation happen with GFP_KERNEL instead of GFP_ATOMIC and lets the kmalloc() decide what values of cmap->len are reasonable. To do this, the patch introduces a function called fb_alloc_cmap_gfp() which is like fb_alloc_cmap() except that it takes a GFP flag. Signed-off-by: Dan Carpenter Signed-off-by: Paul Mundt --- drivers/video/fbcmap.c | 28 ++++++++++++++++++++-------- include/linux/fb.h | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index a79b9762901..affdf3e32cf 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -88,26 +88,27 @@ static const struct fb_cmap default_16_colors = { * */ -int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) +int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags) { int size = len * sizeof(u16); + int ret = -ENOMEM; if (cmap->len != len) { fb_dealloc_cmap(cmap); if (!len) return 0; - cmap->red = kmalloc(size, GFP_ATOMIC); + cmap->red = kmalloc(size, flags); if (!cmap->red) goto fail; - cmap->green = kmalloc(size, GFP_ATOMIC); + cmap->green = kmalloc(size, flags); if (!cmap->green) goto fail; - cmap->blue = kmalloc(size, GFP_ATOMIC); + cmap->blue = kmalloc(size, flags); if (!cmap->blue) goto fail; if (transp) { - cmap->transp = kmalloc(size, GFP_ATOMIC); + cmap->transp = kmalloc(size, flags); if (!cmap->transp) goto fail; } else { @@ -116,12 +117,19 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) } cmap->start = 0; cmap->len = len; - fb_copy_cmap(fb_default_cmap(len), cmap); + ret = fb_copy_cmap(fb_default_cmap(len), cmap); + if (ret) + goto fail; return 0; fail: fb_dealloc_cmap(cmap); - return -ENOMEM; + return ret; +} + +int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) +{ + return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC); } /** @@ -256,8 +264,12 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; + if (size < 0 || size < cmap->len) + return -E2BIG; + memset(&umap, 0, sizeof(struct fb_cmap)); - rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); + rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL, + GFP_KERNEL); if (rc) return rc; if (copy_from_user(umap.red, cmap->red, size) || diff --git a/include/linux/fb.h b/include/linux/fb.h index 7fca3dc4e47..d1631d37e9e 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -1122,6 +1122,7 @@ extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs /* drivers/video/fbcmap.c */ extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); +extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags); extern void fb_dealloc_cmap(struct fb_cmap *cmap); extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to); -- cgit v1.2.3-70-g09d2 From ad913da61aeb267ac99a649834a0cb1a963d7ec2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sun, 14 Nov 2010 14:12:31 +0000 Subject: lxfb: Program panel v/h sync output polarity correctly Commit b5c26f97ec4a17c65 introduced some breakage for the OLPC XO-1 laptop, differences in the output video signal after the patch caused some problems with the XO's display controller chip. Reviewing of that commit against the AMD Geode LX Data Book, it seems that these bits were being set inversely. In both cases, active high output is denoted by a value of 0. See section 6.8.3.44 of the databook from February 2009 (Publication ID: 33234H) Signed-off-by: Daniel Drake Signed-off-by: Paul Mundt --- drivers/video/geode/lxfb_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c index bc35a95e59d..85ec7f64c42 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/geode/lxfb_ops.c @@ -276,10 +276,10 @@ static void lx_graphics_enable(struct fb_info *info) write_fp(par, FP_PT1, 0); temp = FP_PT2_SCRC; - if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) + if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) temp |= FP_PT2_HSP; - if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) + if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) temp |= FP_PT2_VSP; write_fp(par, FP_PT2, temp); -- cgit v1.2.3-70-g09d2 From bbe425cd9ae83eacd0c9f09df2bf56dc911a54cd Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 17 Nov 2010 11:56:13 +0100 Subject: cciss: fix build for PROC_FS disabled The recent patch to fix the removal of a non-existing proc directory introduced this build problem for !CONFIG_PROC_FS: drivers/block/cciss.c:4929: error: 'proc_cciss' undeclared (first use in this function) Fix it by moving proc_cciss outside of the CONFIG_PROC_FS scope. Reported-by: Randy Dunlap Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a67d0a611a8..f291587d753 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -66,6 +66,7 @@ MODULE_VERSION("3.6.26"); MODULE_LICENSE("GPL"); static DEFINE_MUTEX(cciss_mutex); +static struct proc_dir_entry *proc_cciss; #include "cciss_cmd.h" #include "cciss.h" @@ -363,8 +364,6 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", #define ENG_GIG_FACTOR (ENG_GIG/512) #define ENGAGE_SCSI "engage scsi" -static struct proc_dir_entry *proc_cciss; - static void cciss_seq_show_header(struct seq_file *seq) { ctlr_info_t *h = seq->private; -- cgit v1.2.3-70-g09d2 From 23e701e6208191ad103517ae7a700f2dc59ab2ec Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 17 Nov 2010 12:03:58 -0500 Subject: [libata] remove SCSI host lock and serial number usage from ata_scsi_queuecmd cmd->serial_number is never tested in any path we reach; therefore we may remove the call to scsi_cmd_get_serial() inside DEF_SCSI_QCMD, the SCSI host_lock acquisition surrounding it, and our own SCSI host_lock unlock+relock cycle. Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 19835d39289..66aa4bee80a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3166,8 +3166,8 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, /** * ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device + * @shost: SCSI host of command to be sent * @cmd: SCSI command to be sent - * @done: Completion function, called when command is complete * * In some cases, this function translates SCSI commands into * ATA taskfiles, and queues the taskfiles to be sent to @@ -3177,42 +3177,39 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, * ATA and ATAPI devices appearing as SCSI devices. * * LOCKING: - * Releases scsi-layer-held lock, and obtains host lock. + * ATA host lock * * RETURNS: * Return value from __ata_scsi_queuecmd() if @cmd can be queued, * 0 otherwise. */ -static int ata_scsi_queuecmd_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) { struct ata_port *ap; struct ata_device *dev; struct scsi_device *scsidev = cmd->device; - struct Scsi_Host *shost = scsidev->host; int rc = 0; + unsigned long irq_flags; ap = ata_shost_to_port(shost); - spin_unlock(shost->host_lock); - spin_lock(ap->lock); + spin_lock_irqsave(ap->lock, irq_flags); ata_scsi_dump_cdb(ap, cmd); dev = ata_scsi_find_dev(ap, scsidev); if (likely(dev)) - rc = __ata_scsi_queuecmd(cmd, done, dev); + rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev); else { cmd->result = (DID_BAD_TARGET << 16); - done(cmd); + cmd->scsi_done(cmd); } - spin_unlock(ap->lock); - spin_lock(shost->host_lock); + spin_unlock_irqrestore(ap->lock, irq_flags); + return rc; } -DEF_SCSI_QCMD(ata_scsi_queuecmd) - /** * ata_scsi_simulate - simulate SCSI command on ATA device * @dev: the target device -- cgit v1.2.3-70-g09d2 From 73e1cc4a4a02cfd2d520355de56ce1dafa11dd59 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Wed, 17 Nov 2010 21:02:13 +0800 Subject: staging: spectra: fix build error blk_queue_ordered() has been deprecated and replaced with blk_queue_flush() by Tejun. However, use of blk_queue_ordered() in spectra nand driver has not been converted yet and thus results in the following build error. drivers/staging/spectra/ffsport.c: In function SBD_setup_device: drivers/staging/spectra/ffsport.c:659: error: implicit declaration of function blk_queue_ordered drivers/staging/spectra/ffsport.c:659: error: QUEUE_ORDERED_DRAIN_FLUSH undeclared (first use in this function) drivers/staging/spectra/ffsport.c:659: error: (Each undeclared identifier is reported only once drivers/staging/spectra/ffsport.c:659: error: for each function it appears in.) Signed-off-by: Yong Wang Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/ffsport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index c7932da03c5..63a9d0adf32 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c @@ -656,7 +656,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) /* Here we force report 512 byte hardware sector size to Kernel */ blk_queue_logical_block_size(dev->queue, 512); - blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH); + blk_queue_flush(dev->queue, REQ_FLUSH); dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); if (IS_ERR(dev->thread)) { -- cgit v1.2.3-70-g09d2 From d5d3ebe3be5c5123f2d444e186717f45284151e2 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Fri, 12 Nov 2010 00:15:25 +0000 Subject: r8169: fix checksum broken If r8196 received packets with invalid sctp/igmp(not tcp, udp) checksum, r8196 set skb->ip_summed wit CHECKSUM_UNNECESSARY. This cause that upper protocol don't check checksum field. I am not family with r8196 driver. I try to guess the meaning of RxProtoIP and IPFail. RxProtoIP stands for received IPv4 packet that upper protocol is not tcp and udp. !(opts1 & IPFail) is true means that driver correctly to check checksum in IPv4 header. If it's right, I think we should not set ip_summed wit CHECKSUM_UNNECESSARY for my sctp packets with invalid checksum. If it's not right, please tell me. Signed-off-by: Shan Wei Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/r8169.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4c4d16905ef..7d33ef4bcb4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4440,8 +4440,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) u32 status = opts1 & RxProtoMask; if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || - ((status == RxProtoUDP) && !(opts1 & UDPFail)) || - ((status == RxProtoIP) && !(opts1 & IPFail))) + ((status == RxProtoUDP) && !(opts1 & UDPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb); -- cgit v1.2.3-70-g09d2 From 24b7ea9f6c9787fad885442ed0cc010f1aa69cca Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 17 Nov 2010 11:55:08 -0800 Subject: 8139cp: fix checksum broken I am not family with RealTek RTL-8139C+ series 10/100 PCI Ethernet driver. I try to guess the meaning of RxProtoIP and IPFail. RxProtoIP stands for received IPv4 packet that upper protocol is not tcp and udp. !(status & IPFail) is true means that driver correctly to check checksum in IPv4 header. If these are right, driver will set ip_summed with CHECKSUM_UNNECESSARY for other upper protocol, e.g. sctp, igmp protocol. This will cause protocol stack ignores checksum check for packets with invalid checksum. This patch is only compile-test. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index ac422cd332e..dd16e83933a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -490,13 +490,11 @@ static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; - if (likely((protocol == RxProtoTCP) && (!(status & TCPFail)))) + if (((protocol == RxProtoTCP) && !(status & TCPFail)) || + ((protocol == RxProtoUDP) && !(status & UDPFail))) return 1; - else if ((protocol == RxProtoUDP) && (!(status & UDPFail))) - return 1; - else if ((protocol == RxProtoIP) && (!(status & IPFail))) - return 1; - return 0; + else + return 0; } static int cp_rx_poll(struct napi_struct *napi, int budget) -- cgit v1.2.3-70-g09d2 From 870634b0b641271acb2e22df06ddda0c794b89a3 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 14 Nov 2010 10:08:34 +0000 Subject: net: bnx2x: fix error value sign bnx2x_init_one() should return negative value on error. By mistake it returns ENODEV instead of -ENODEV. Signed-off-by: Vasiliy Kulikov Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index e9ad16f00b5..9709b856966 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9064,7 +9064,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, default: pr_err("Unknown board_type (%ld), aborting\n", ent->driver_data); - return ENODEV; + return -ENODEV; } cid_count += CNIC_CONTEXT_USE; -- cgit v1.2.3-70-g09d2 From 28cb6ccd2c7e86b3a4db94c7062cd27937bed424 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 15 Nov 2010 10:59:42 +0000 Subject: gianfar: fix signedness issue irq_of_parse_and_map() has an unsigned return type. Testing for a negative error value doesn't work here. Signed-off-by: Nicolas Kaiser Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 49e4ce1246a..d1bec626917 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -577,11 +577,10 @@ static int gfar_parse_group(struct device_node *np, irq_of_parse_and_map(np, 1); priv->gfargrp[priv->num_grps].interruptError = irq_of_parse_and_map(np,2); - if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 || - priv->gfargrp[priv->num_grps].interruptReceive < 0 || - priv->gfargrp[priv->num_grps].interruptError < 0) { + if (priv->gfargrp[priv->num_grps].interruptTransmit == NO_IRQ || + priv->gfargrp[priv->num_grps].interruptReceive == NO_IRQ || + priv->gfargrp[priv->num_grps].interruptError == NO_IRQ) return -EINVAL; - } } priv->gfargrp[priv->num_grps].grp_id = priv->num_grps; -- cgit v1.2.3-70-g09d2 From b432b4b3440a34c1430fcd66bab783640724bd28 Mon Sep 17 00:00:00 2001 From: kishore kadiyala Date: Wed, 17 Nov 2010 22:35:32 -0500 Subject: mmc: omap4: hsmmc: Fix improper card detection while booting While booting OMAP4 ES2.0 boards, cards on MMC1 and MMC2 controllers are not getting detected sometimes. During reset of command/data line, wrong pointer to base address was passed while read operation to SYSCTL register, thus impacting the updated reset logic. Passing the correct base address fixes the issue. Signed-off-by: Kishore Kadiyala Acked-by: Felipe Balbi Acked-by: Madhusudhan Chikkature Acked-by: Tony Lindgren Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 82a1079bbdc..5d46021cbb5 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, * Monitor a 0->1 transition first */ if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { - while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit)) + while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) && (i++ < limit)) cpu_relax(); } -- cgit v1.2.3-70-g09d2 From da3bd8203082794d26de3a0a6a7d1ee639d07eb1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 5 Oct 2010 15:07:33 +0200 Subject: drm/nouveau: ratelimit IRQ messages There are two messages in the ISR of nouveau which might be printed out hundred times in a second. Ratelimit them. (We need to move nouveau_ratelimit to the top of the file.) Signed-off-by: Jiri Slaby Reviewed-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_irq.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 6fd51a51c60..b9e1ffed855 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -42,6 +42,13 @@ #include "nouveau_connector.h" #include "nv50_display.h" +static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); + +static int nouveau_ratelimit(void) +{ + return __ratelimit(&nouveau_ratelimit_state); +} + void nouveau_irq_preinstall(struct drm_device *dev) { @@ -213,11 +220,12 @@ nouveau_fifo_irq_handler(struct drm_device *dev) u32 ib_get = nv_rd32(dev, 0x003334); u32 ib_put = nv_rd32(dev, 0x003330); - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " + if (nouveau_ratelimit()) + NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " "State 0x%08x Push 0x%08x\n", - chid, ho_get, get, ho_put, put, ib_get, ib_put, - state, push); + chid, ho_get, get, ho_put, put, + ib_get, ib_put, state, push); /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ nv_wr32(dev, 0x003364, 0x00000000); @@ -266,8 +274,9 @@ nouveau_fifo_irq_handler(struct drm_device *dev) } if (status) { - NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", - status, chid); + if (nouveau_ratelimit()) + NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", + status, chid); nv_wr32(dev, NV03_PFIFO_INTR_0, status); status = 0; } @@ -544,13 +553,6 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); } -static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); - -static int nouveau_ratelimit(void) -{ - return __ratelimit(&nouveau_ratelimit_state); -} - static inline void nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) -- cgit v1.2.3-70-g09d2 From 907af60b93045ae33b450553167aa8f684252de3 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 9 Oct 2010 04:02:09 +0200 Subject: drm/nouveau: Fix sleep while atomic in the semaphore code. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 441b12420bb..ab1bbfbf266 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -249,6 +249,7 @@ alloc_semaphore(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_semaphore *sema; + int ret; if (!USE_SEMA(dev)) return NULL; @@ -257,10 +258,14 @@ alloc_semaphore(struct drm_device *dev) if (!sema) goto fail; + ret = drm_mm_pre_get(&dev_priv->fence.heap); + if (ret) + goto fail; + spin_lock(&dev_priv->fence.lock); sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0); if (sema->mem) - sema->mem = drm_mm_get_block(sema->mem, 4, 0); + sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0); spin_unlock(&dev_priv->fence.lock); if (!sema->mem) -- cgit v1.2.3-70-g09d2 From 1f5bd44354c878cf8bb0e28a7cb27677e3640c45 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 2 Oct 2010 16:00:35 +0200 Subject: drm/nouveau: Reject modes exceeding the integrated TMDS maximum bandwidth. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Grzesiek Sójka Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 0871495096f..6208eedc097 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector) return ret; } +static unsigned +get_tmds_link_bandwidth(struct drm_connector *connector) +{ + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct drm_nouveau_private *dev_priv = connector->dev->dev_private; + struct dcb_entry *dcb = nv_connector->detected_encoder->dcb; + + if (dcb->location != DCB_LOC_ON_CHIP || + dev_priv->chipset >= 0x46) + return 165000; + else if (dev_priv->chipset >= 0x40) + return 155000; + else if (dev_priv->chipset >= 0x18) + return 135000; + else + return 112000; +} + static int nouveau_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; struct drm_encoder *encoder = to_drm_encoder(nv_encoder); @@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, max_clock = 400000; break; case OUTPUT_TMDS: - if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || - !nv_encoder->dcb->duallink_possible) - max_clock = 165000; - else - max_clock = 330000; + max_clock = get_tmds_link_bandwidth(connector); + if (nouveau_duallink && nv_encoder->dcb->duallink_possible) + max_clock *= 2; break; case OUTPUT_ANALOG: max_clock = nv_encoder->dcb->crtconf.maxfreq; -- cgit v1.2.3-70-g09d2 From 327ceae6643ddafb0c514183f00e7fc8ca6b6e99 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 10 Oct 2010 05:21:59 +0200 Subject: drm/nv04-nv40: Fall back to panel rescaling if we have no usable native mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the user to set a mode larger than the native one, useful if we had trouble finding the actual native mode (e.g. because it goes above the hardware bandwidth limits). Reported-by: Grzesiek Sójka Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_dfp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index c936403b26e..ef23550407b 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -185,14 +185,15 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); - /* For internal panels and gpu scaling on DVI we need the native mode */ - if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { - if (!nv_connector->native_mode) - return false; + if (!nv_connector->native_mode || + nv_connector->scaling_mode == DRM_MODE_SCALE_NONE || + mode->hdisplay > nv_connector->native_mode->hdisplay || + mode->vdisplay > nv_connector->native_mode->vdisplay) { + nv_encoder->mode = *adjusted_mode; + + } else { nv_encoder->mode = *nv_connector->native_mode; adjusted_mode->clock = nv_connector->native_mode->clock; - } else { - nv_encoder->mode = *adjusted_mode; } return true; -- cgit v1.2.3-70-g09d2 From 5eb94fbba39e71f04d629f8197343273b56e25eb Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 7 Oct 2010 03:33:15 +0200 Subject: drm/nv11: Fix bad PLL detection false positive. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index bed669a54a2..b9672a05c41 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c @@ -519,11 +519,11 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) struct pll_lims pll_lim; struct nouveau_pll_vals pv; - uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; + enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0; - if (get_pll_limits(dev, pllreg, &pll_lim)) + if (get_pll_limits(dev, pll, &pll_lim)) return; - nouveau_hw_get_pllvals(dev, pllreg, &pv); + nouveau_hw_get_pllvals(dev, pll, &pv); if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && @@ -536,7 +536,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) pv.M1 = pll_lim.vco1.max_m; pv.N1 = pll_lim.vco1.min_n; pv.log2P = pll_lim.max_usable_log2p; - nouveau_hw_setpll(dev, pllreg, &pv); + nouveau_hw_setpll(dev, pll_lim.reg, &pv); } /* -- cgit v1.2.3-70-g09d2 From cbab95db84f2a444d99bec77bac8b9b6ef20d11c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 11 Oct 2010 03:43:58 +0200 Subject: drm/nouveau: Some random cleanups. Remove some unused/duplicated definitions and make sparse happy again. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 41 +++-------------------------------- drivers/gpu/drm/nouveau/nouveau_irq.c | 19 ++++++++-------- drivers/gpu/drm/nouveau/nouveau_mem.c | 6 ++--- 3 files changed, 16 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3a07e580d27..135594c4416 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -485,13 +485,13 @@ enum nv04_fp_display_regs { }; struct nv04_crtc_reg { - unsigned char MiscOutReg; /* */ + unsigned char MiscOutReg; uint8_t CRTC[0xa0]; uint8_t CR58[0x10]; uint8_t Sequencer[5]; uint8_t Graphics[9]; uint8_t Attribute[21]; - unsigned char DAC[768]; /* Internal Colorlookuptable */ + unsigned char DAC[768]; /* PCRTC regs */ uint32_t fb_start; @@ -539,43 +539,9 @@ struct nv04_output_reg { }; struct nv04_mode_state { - uint32_t bpp; - uint32_t width; - uint32_t height; - uint32_t interlace; - uint32_t repaint0; - uint32_t repaint1; - uint32_t screen; - uint32_t scale; - uint32_t dither; - uint32_t extra; - uint32_t fifo; - uint32_t pixel; - uint32_t horiz; - int arbitration0; - int arbitration1; - uint32_t pll; - uint32_t pllB; - uint32_t vpll; - uint32_t vpll2; - uint32_t vpllB; - uint32_t vpll2B; + struct nv04_crtc_reg crtc_reg[2]; uint32_t pllsel; uint32_t sel_clk; - uint32_t general; - uint32_t crtcOwner; - uint32_t head; - uint32_t head2; - uint32_t cursorConfig; - uint32_t cursor0; - uint32_t cursor1; - uint32_t cursor2; - uint32_t timingH; - uint32_t timingV; - uint32_t displayV; - uint32_t crtcSync; - - struct nv04_crtc_reg crtc_reg[2]; }; enum nouveau_card_type { @@ -1239,7 +1205,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); -extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); /* nouveau_fence.c */ struct nouveau_fence; diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index b9e1ffed855..e2f2d59be3e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -209,8 +209,8 @@ nouveau_fifo_irq_handler(struct drm_device *dev) } if (status & NV_PFIFO_INTR_DMA_PUSHER) { - u32 get = nv_rd32(dev, 0x003244); - u32 put = nv_rd32(dev, 0x003240); + u32 dma_get = nv_rd32(dev, 0x003244); + u32 dma_put = nv_rd32(dev, 0x003240); u32 push = nv_rd32(dev, 0x003220); u32 state = nv_rd32(dev, 0x003228); @@ -224,13 +224,14 @@ nouveau_fifo_irq_handler(struct drm_device *dev) NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " "State 0x%08x Push 0x%08x\n", - chid, ho_get, get, ho_put, put, - ib_get, ib_put, state, push); + chid, ho_get, dma_get, ho_put, + dma_put, ib_get, ib_put, state, + push); /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ nv_wr32(dev, 0x003364, 0x00000000); - if (get != put || ho_get != ho_put) { - nv_wr32(dev, 0x003244, put); + if (dma_get != dma_put || ho_get != ho_put) { + nv_wr32(dev, 0x003244, dma_put); nv_wr32(dev, 0x003328, ho_put); } else if (ib_get != ib_put) { @@ -239,10 +240,10 @@ nouveau_fifo_irq_handler(struct drm_device *dev) } else { NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " "Put 0x%08x State 0x%08x Push 0x%08x\n", - chid, get, put, state, push); + chid, dma_get, dma_put, state, push); - if (get != put) - nv_wr32(dev, 0x003244, put); + if (dma_get != dma_put) + nv_wr32(dev, 0x003244, dma_put); } nv_wr32(dev, 0x003228, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index a163c7c612e..1165c3e6820 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -33,9 +33,9 @@ #include "drmP.h" #include "drm.h" #include "drm_sarea.h" -#include "nouveau_drv.h" -#define MIN(a,b) a < b ? a : b +#include "nouveau_drv.h" +#include "nouveau_pm.h" /* * NV10-NV40 tiling helpers @@ -719,7 +719,7 @@ nouveau_mem_timing_init(struct drm_device *dev) tUNK_19 = 1; tUNK_20 = 0; tUNK_21 = 0; - switch (MIN(recordlen,21)) { + switch (min(recordlen, 21)) { case 21: tUNK_21 = entry[21]; case 20: -- cgit v1.2.3-70-g09d2 From 7bb94d26ad62ca1d6b5e11db6e26425785cc46ac Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 11 Oct 2010 03:37:32 +0200 Subject: drm/nouveau: Avoid lock dependency between ramht and ramin spinlocks. The ramht code called some gpuobj functions with the HARDIRQ-safe RAMHT spinlock held, this could potentially lead to a dead lock because ramin_lock is HARDIRQ-unsafe. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_ramht.c | 71 ++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c index 7f16697cc96..2d8580927ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c @@ -153,26 +153,42 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, return -ENOMEM; } +static struct nouveau_ramht_entry * +nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle) +{ + struct nouveau_ramht *ramht = chan ? chan->ramht : NULL; + struct nouveau_ramht_entry *entry; + unsigned long flags; + + if (!ramht) + return NULL; + + spin_lock_irqsave(&ramht->lock, flags); + list_for_each_entry(entry, &ramht->entries, head) { + if (entry->channel == chan && + (!handle || entry->handle == handle)) { + list_del(&entry->head); + spin_unlock_irqrestore(&ramht->lock, flags); + + return entry; + } + } + spin_unlock_irqrestore(&ramht->lock, flags); + + return NULL; +} + static void -nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) +nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; - struct nouveau_ramht_entry *entry, *tmp; + unsigned long flags; u32 co, ho; - list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) { - if (entry->channel != chan || entry->handle != handle) - continue; - - nouveau_gpuobj_ref(NULL, &entry->gpuobj); - list_del(&entry->head); - kfree(entry); - break; - } - + spin_lock_irqsave(&chan->ramht->lock, flags); co = ho = nouveau_ramht_hash_handle(chan, handle); do { if (nouveau_ramht_entry_valid(dev, ramht, co) && @@ -184,7 +200,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) nv_wo32(ramht, co + 0, 0x00000000); nv_wo32(ramht, co + 4, 0x00000000); instmem->flush(dev); - return; + goto out; } co += 8; @@ -194,17 +210,22 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", chan->id, handle); +out: + spin_unlock_irqrestore(&chan->ramht->lock, flags); } void nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) { - struct nouveau_ramht *ramht = chan->ramht; - unsigned long flags; + struct nouveau_ramht_entry *entry; - spin_lock_irqsave(&ramht->lock, flags); - nouveau_ramht_remove_locked(chan, handle); - spin_unlock_irqrestore(&ramht->lock, flags); + entry = nouveau_ramht_remove_entry(chan, handle); + if (!entry) + return; + + nouveau_ramht_remove_hash(chan, entry->handle); + nouveau_gpuobj_ref(NULL, &entry->gpuobj); + kfree(entry); } struct nouveau_gpuobj * @@ -265,23 +286,19 @@ void nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr, struct nouveau_channel *chan) { - struct nouveau_ramht_entry *entry, *tmp; + struct nouveau_ramht_entry *entry; struct nouveau_ramht *ramht; - unsigned long flags; if (ref) kref_get(&ref->refcount); ramht = *ptr; if (ramht) { - spin_lock_irqsave(&ramht->lock, flags); - list_for_each_entry_safe(entry, tmp, &ramht->entries, head) { - if (entry->channel != chan) - continue; - - nouveau_ramht_remove_locked(chan, entry->handle); + while ((entry = nouveau_ramht_remove_entry(chan, 0))) { + nouveau_ramht_remove_hash(chan, entry->handle); + nouveau_gpuobj_ref(NULL, &entry->gpuobj); + kfree(entry); } - spin_unlock_irqrestore(&ramht->lock, flags); kref_put(&ramht->refcount, nouveau_ramht_del); } -- cgit v1.2.3-70-g09d2 From 1397b42b5a2e5b3b982078c89f3594c123e3c2b3 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 12 Oct 2010 03:17:43 +0200 Subject: drm/nouveau: Reduce severity of the unknown getparam error. Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index ed7757f1408..af2bec36d91 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1051,7 +1051,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, } /* FALLTHRU */ default: - NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); + NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param); return -EINVAL; } @@ -1066,7 +1066,7 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, switch (setparam->param) { default: - NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); + NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From f13b32630dda7e583a84a8c535880cff7e4a9bdd Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 10 Oct 2010 06:01:08 +0200 Subject: drm/nouveau: Expose some BO usage flags to userspace. This will be needed for Z compression and to take smarter placement decisions. Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 15 +++++++++----- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +++ drivers/gpu/drm/nouveau/nouveau_gem.c | 36 +++++++++++++++++++-------------- drivers/gpu/drm/nouveau/nouveau_state.c | 3 +++ drivers/gpu/drm/nouveau/nv50_crtc.c | 4 ++-- include/drm/nouveau_drm.h | 7 +++++++ 6 files changed, 46 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 80353e2b840..f55dd9145b7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -144,7 +144,8 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, nvbo->tile_mode = tile_mode; nvbo->tile_flags = tile_flags; - nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); + nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo), + &align, &size); align >>= PAGE_SHIFT; nouveau_bo_placement_set(nvbo, flags, 0); @@ -525,7 +526,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, stride = 16 * 4; height = amount / stride; - if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { + if (new_mem->mem_type == TTM_PL_VRAM && + nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) return ret; @@ -546,7 +548,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); OUT_RING (chan, 1); } - if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { + if (old_mem->mem_type == TTM_PL_VRAM && + nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) return ret; @@ -753,7 +756,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, if (dev_priv->card_type == NV_50) { ret = nv50_mem_vm_bind_linear(dev, offset + dev_priv->vm_vram_base, - new_mem->size, nvbo->tile_flags, + new_mem->size, + nouveau_bo_tile_layout(nvbo), offset); if (ret) return ret; @@ -894,7 +898,8 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) * nothing to do here. */ if (bo->mem.mem_type != TTM_PL_VRAM) { - if (dev_priv->card_type < NV_50 || !nvbo->tile_flags) + if (dev_priv->card_type < NV_50 || + !nouveau_bo_tile_layout(nvbo)) return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 135594c4416..60a54fae90c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -100,6 +100,9 @@ struct nouveau_bo { int pin_refcnt; }; +#define nouveau_bo_tile_layout(nvbo) \ + ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) + static inline struct nouveau_bo * nouveau_bo(struct ttm_buffer_object *bo) { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5c4c929d7f7..9a1fdcf400c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -107,23 +107,29 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep) } static bool -nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) { - switch (tile_flags) { - case 0x0000: - case 0x1800: - case 0x2800: - case 0x4800: - case 0x7000: - case 0x7400: - case 0x7a00: - case 0xe000: - break; - default: - NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); - return false; +nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->card_type >= NV_50) { + switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) { + case 0x0000: + case 0x1800: + case 0x2800: + case 0x4800: + case 0x7000: + case 0x7400: + case 0x7a00: + case 0xe000: + return true; + } + } else { + if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) + return true; } - return true; + NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); + return false; } int diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index af2bec36d91..ea3452194cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1041,6 +1041,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, case NOUVEAU_GETPARAM_PTIMER_TIME: getparam->value = dev_priv->engine.timer.read(dev); break; + case NOUVEAU_GETPARAM_HAS_BO_USAGE: + getparam->value = 1; + break; case NOUVEAU_GETPARAM_GRAPH_UNITS: /* NV40 and NV50 versions are quite different, but register * address is the same. User is supposed to know the card diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 16380d52cd8..56476d0c6de 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -546,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, } nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; - nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; + nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { ret = RING_SPACE(evo, 2); @@ -578,7 +578,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, fb->nvbo->tile_mode); } if (dev_priv->chipset == 0x50) - OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format); + OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); else OUT_RING(evo, format); diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index 01a71411950..bc5590b1a1a 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -80,6 +80,7 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 #define NOUVEAU_GETPARAM_PTIMER_TIME 14 +#define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 struct drm_nouveau_getparam { uint64_t param; uint64_t value; @@ -95,6 +96,12 @@ struct drm_nouveau_setparam { #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) +#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00 +#define NOUVEAU_GEM_TILE_16BPP 0x00000001 +#define NOUVEAU_GEM_TILE_32BPP 0x00000002 +#define NOUVEAU_GEM_TILE_ZETA 0x00000004 +#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008 + struct drm_nouveau_gem_info { uint32_t handle; uint32_t domain; -- cgit v1.2.3-70-g09d2 From 699ddfd98061b725c52fd34ff1c4346e5b4824d4 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 10 Oct 2010 06:07:32 +0200 Subject: drm/nv10: Balance RTs expected to be accessed simultaneously by the 3d engine. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f55dd9145b7..c41e1c200ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -143,6 +143,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, nvbo->no_vm = no_vm; nvbo->tile_mode = tile_mode; nvbo->tile_flags = tile_flags; + nvbo->bo.bdev = &dev_priv->ttm.bdev; nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo), &align, &size); @@ -177,6 +178,31 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; } +static void +set_placement_range(struct nouveau_bo *nvbo, uint32_t type) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); + + if (dev_priv->card_type == NV_10 && + nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) { + /* + * Make sure that the color and depth buffers are handled + * by independent memory controller units. Up to a 9x + * speed up when alpha-blending and depth-test are enabled + * at the same time. + */ + int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; + + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { + nvbo->placement.fpfn = vram_pages / 2; + nvbo->placement.lpfn = ~0; + } else { + nvbo->placement.fpfn = 0; + nvbo->placement.lpfn = vram_pages / 2; + } + } +} + void nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) { @@ -191,6 +217,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) pl->busy_placement = nvbo->busy_placements; set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, type | busy, flags); + + set_placement_range(nvbo, type); } int -- cgit v1.2.3-70-g09d2 From 2a56a0b913a8d7314c2c10fdd57d667b599232b4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 1 Oct 2010 14:39:37 +1000 Subject: drm/nva3: fix overflow in fixed point math used for pll calculation And a slight tweak which gets us closer to VBIOS-calculated numbers. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_calc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c index 2cdc2bfe717..de81151648f 100644 --- a/drivers/gpu/drm/nouveau/nv50_calc.c +++ b/drivers/gpu/drm/nouveau/nv50_calc.c @@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk, int *N, int *fN, int *M, int *P) { fixed20_12 fb_div, a, b; + u32 refclk = pll->refclk / 10; + u32 max_vco_freq = pll->vco1.maxfreq / 10; + u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10; + clk /= 10; - *P = pll->vco1.maxfreq / clk; + *P = max_vco_freq / clk; if (*P > pll->max_p) *P = pll->max_p; if (*P < pll->min_p) *P = pll->min_p; - /* *M = ceil(refclk / pll->vco.max_inputfreq); */ - a.full = dfixed_const(pll->refclk); - b.full = dfixed_const(pll->vco1.max_inputfreq); + /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */ + a.full = dfixed_const(refclk + max_vco_inputfreq); + b.full = dfixed_const(max_vco_inputfreq); a.full = dfixed_div(a, b); - a.full = dfixed_ceil(a); + a.full = dfixed_floor(a); *M = dfixed_trunc(a); /* fb_div = (vco * *M) / refclk; */ fb_div.full = dfixed_const(clk * *P); fb_div.full = dfixed_mul(fb_div, a); - a.full = dfixed_const(pll->refclk); + a.full = dfixed_const(refclk); fb_div.full = dfixed_div(fb_div, a); /* *N = floor(fb_div); */ -- cgit v1.2.3-70-g09d2 From 3c29f9e74591d2f365b159cf59193b19a2f65640 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 15 Oct 2010 22:22:59 +0200 Subject: drm/nouveau: fix nv40 pcie gart size Nouveau sets the PCIE GART size to 64MiB for all cards before nv50, but nv40 has enough RAMIN space to support 512MiB GART size. This patch fixes this value to make use of this hardware capability. Signed-off-by: Lucas Stach Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 288bacac7e5..15f35840464 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -224,7 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev) int i, ret; if (dev_priv->card_type < NV_50) { - aper_size = (64 * 1024 * 1024); + if(dev_priv->card_type < NV_40) { + aper_size = (64 * 1024 * 1024); + } else { + aper_size = (512 * 1024 * 1024); + } obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; obj_size += 8; /* ctxdma header */ } else { -- cgit v1.2.3-70-g09d2 From 5794b5fdb579abf7be2c27c6e0d6106f391a26e4 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 22 Oct 2010 04:39:14 +0200 Subject: drm/nv04: Fix scanout over the 16MB mark. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_hw.h | 19 +++++++++++++++++++ drivers/gpu/drm/nouveau/nv04_crtc.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h index 869130f8360..2989090b943 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.h +++ b/drivers/gpu/drm/nouveau/nouveau_hw.h @@ -415,6 +415,25 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head) NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); } +static inline void +nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + NVWriteCRTC(dev, head, NV_PCRTC_START, offset); + + if (dev_priv->card_type == NV_04) { + /* + * Hilarious, the 24th bit doesn't want to stick to + * PCRTC_START... + */ + int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX); + + NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX, + (cre_heb & ~0x40) | ((offset >> 18) & 0x40)); + } +} + static inline void nv_show_cursor(struct drm_device *dev, int head, bool show) { diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index c71abc2a34d..5b49cec528e 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -831,7 +831,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, /* Update the framebuffer location. */ regp->fb_start = nv_crtc->fb.offset & ~3; regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8); - NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start); + nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start); /* Update the arbitration parameters. */ nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel, -- cgit v1.2.3-70-g09d2 From 01db363979e96115a895f35c823303660f0f328d Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 21 Oct 2010 17:43:08 +0200 Subject: drm/nouveau: Use "force" to decide if analog load detection is ok or not. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 69 ++++++++++++----------------- drivers/gpu/drm/nouveau/nouveau_connector.h | 3 -- drivers/gpu/drm/nouveau/nv04_crtc.c | 5 --- 3 files changed, 28 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 6208eedc097..9ec2b8a8134 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -213,6 +213,24 @@ nouveau_connector_set_encoder(struct drm_connector *connector, } } +static bool +nouveau_connector_poll_allowed(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + bool spare_crtc = false; + + if (dev_priv->card_type >= NV_50) { + return true; + } else { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + spare_crtc |= !crtc->enabled; + + return spare_crtc; + } +} + static enum drm_connector_status nouveau_connector_detect(struct drm_connector *connector, bool force) { @@ -281,7 +299,8 @@ detect_analog: nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); if (!nv_encoder && !nouveau_tv_disable) nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); - if (nv_encoder) { + if (nv_encoder && + (force || nouveau_connector_poll_allowed(connector))) { struct drm_encoder *encoder = to_drm_encoder(nv_encoder); struct drm_encoder_helper_funcs *helper = encoder->helper_private; @@ -724,44 +743,6 @@ nouveau_connector_best_encoder(struct drm_connector *connector) return NULL; } -void -nouveau_connector_set_polling(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - bool spare_crtc = false; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - spare_crtc |= !crtc->enabled; - - connector->polled = 0; - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_VGA: - case DRM_MODE_CONNECTOR_TV: - if (dev_priv->card_type >= NV_50 || - (nv_gf4_disp_arch(dev) && spare_crtc)) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - break; - - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_DisplayPort: - case DRM_MODE_CONNECTOR_eDP: - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID || - spare_crtc) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - break; - - default: - break; - } -} - static const struct drm_connector_helper_funcs nouveau_connector_helper_funcs = { .get_modes = nouveau_connector_get_modes, @@ -892,6 +873,9 @@ nouveau_connector_create(struct drm_device *dev, int index) case DCB_CONNECTOR_TV_1: case DCB_CONNECTOR_TV_3: nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; + + if (nv_gf4_disp_arch(dev)) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; default: nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; @@ -903,11 +887,14 @@ nouveau_connector_create(struct drm_device *dev, int index) dev->mode_config.dithering_mode_property, nv_connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); + + if (dev_priv->card_type >= NV_50) + connector->polled = DRM_CONNECTOR_POLL_HPD; + else + connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; } - nouveau_connector_set_polling(connector); - drm_sysfs_connector_add(connector); dcb->drm = connector; return dcb->drm; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index c21ed6b16f8..711b1e9203a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -52,9 +52,6 @@ static inline struct nouveau_connector *nouveau_connector( struct drm_connector * nouveau_connector_create(struct drm_device *, int index); -void -nouveau_connector_set_polling(struct drm_connector *); - int nouveau_connector_bpp(struct drm_connector *); diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 5b49cec528e..40e18074162 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -158,7 +158,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_connector *connector; unsigned char seq1 = 0, crtc17 = 0; unsigned char crtc1A; @@ -213,10 +212,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) NVVgaSeqReset(dev, nv_crtc->index, false); NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); - - /* Update connector polling modes */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - nouveau_connector_set_polling(connector); } static bool -- cgit v1.2.3-70-g09d2 From 06ef3e61dd44f76fef89d8e7ad5d6c845f3f345e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 23 Oct 2010 23:12:37 +0200 Subject: drm/nouveau: Don't poll LVDS outputs. Reported-by: Xavier Chantry Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 9ec2b8a8134..1dd52dbfad4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -888,10 +888,12 @@ nouveau_connector_create(struct drm_device *dev, int index) nv_connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT; + if (dcb->type != DCB_CONNECTOR_LVDS) { + if (dev_priv->card_type >= NV_50) + connector->polled = DRM_CONNECTOR_POLL_HPD; + else + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + } break; } -- cgit v1.2.3-70-g09d2 From 56ac7475350ee646f5f7316abcdf65d3be94da1c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Oct 2010 10:26:24 +1000 Subject: drm/nv50: implement possible workaround for NV86 PGRAPH TLB flush hang Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 5 ++++ drivers/gpu/drm/nouveau/nouveau_mem.c | 14 ++++----- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 8 ++--- drivers/gpu/drm/nouveau/nouveau_state.c | 10 +++++++ drivers/gpu/drm/nouveau/nv50_fifo.c | 5 ++++ drivers/gpu/drm/nouveau/nv50_graph.c | 52 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv50_instmem.c | 1 - 7 files changed, 82 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 60a54fae90c..10a8d4e78e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -307,6 +307,7 @@ struct nouveau_fifo_engine { void (*destroy_context)(struct nouveau_channel *); int (*load_context)(struct nouveau_channel *); int (*unload_context)(struct drm_device *); + void (*tlb_flush)(struct drm_device *dev); }; struct nouveau_pgraph_object_method { @@ -339,6 +340,7 @@ struct nouveau_pgraph_engine { void (*destroy_context)(struct nouveau_channel *); int (*load_context)(struct nouveau_channel *); int (*unload_context)(struct drm_device *); + void (*tlb_flush)(struct drm_device *dev); void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, uint32_t size, uint32_t pitch); @@ -1014,6 +1016,7 @@ extern int nv50_fifo_create_context(struct nouveau_channel *); extern void nv50_fifo_destroy_context(struct nouveau_channel *); extern int nv50_fifo_load_context(struct nouveau_channel *); extern int nv50_fifo_unload_context(struct drm_device *); +extern void nv50_fifo_tlb_flush(struct drm_device *dev); /* nvc0_fifo.c */ extern int nvc0_fifo_init(struct drm_device *); @@ -1091,6 +1094,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *); extern int nv50_graph_unload_context(struct drm_device *); extern void nv50_graph_context_switch(struct drm_device *); extern int nv50_grctx_init(struct nouveau_grctx *); +extern void nv50_graph_tlb_flush(struct drm_device *dev); +extern void nv86_graph_tlb_flush(struct drm_device *dev); /* nvc0_graph.c */ extern int nvc0_graph_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 1165c3e6820..ac3bec024fd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -175,11 +175,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, } } } - dev_priv->engine.instmem.flush(dev); - nv50_vm_flush(dev, 5); - nv50_vm_flush(dev, 0); - nv50_vm_flush(dev, 4); + dev_priv->engine.instmem.flush(dev); + dev_priv->engine.fifo.tlb_flush(dev); + dev_priv->engine.graph.tlb_flush(dev); nv50_vm_flush(dev, 6); return 0; } @@ -209,11 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) pte++; } } - dev_priv->engine.instmem.flush(dev); - nv50_vm_flush(dev, 5); - nv50_vm_flush(dev, 0); - nv50_vm_flush(dev, 4); + dev_priv->engine.instmem.flush(dev); + dev_priv->engine.fifo.tlb_flush(dev); + dev_priv->engine.graph.tlb_flush(dev); nv50_vm_flush(dev, 6); } diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 15f35840464..0b309c1cc3d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { - nv50_vm_flush(dev, 5); /* PGRAPH */ - nv50_vm_flush(dev, 0); /* PFIFO */ + dev_priv->engine.fifo.tlb_flush(dev); + dev_priv->engine.graph.tlb_flush(dev); } nvbe->bound = true; @@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be) dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { - nv50_vm_flush(dev, 5); - nv50_vm_flush(dev, 0); + dev_priv->engine.fifo.tlb_flush(dev); + dev_priv->engine.graph.tlb_flush(dev); } nvbe->bound = false; diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index ea3452194cd..049f755567e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -354,6 +354,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv50_graph_destroy_context; engine->graph.load_context = nv50_graph_load_context; engine->graph.unload_context = nv50_graph_unload_context; + if (dev_priv->chipset != 0x86) + engine->graph.tlb_flush = nv50_graph_tlb_flush; + else { + /* from what i can see nvidia do this on every + * pre-NVA3 board except NVAC, but, we've only + * ever seen problems on NV86 + */ + engine->graph.tlb_flush = nv86_graph_tlb_flush; + } engine->fifo.channels = 128; engine->fifo.init = nv50_fifo_init; engine->fifo.takedown = nv50_fifo_takedown; @@ -365,6 +374,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv50_fifo_destroy_context; engine->fifo.load_context = nv50_fifo_load_context; engine->fifo.unload_context = nv50_fifo_unload_context; + engine->fifo.tlb_flush = nv50_fifo_tlb_flush; engine->display.early_init = nv50_display_early_init; engine->display.late_takedown = nv50_display_late_takedown; engine->display.create = nv50_display_create; diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index a46a961102f..1da65bd60c1 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev) return 0; } +void +nv50_fifo_tlb_flush(struct drm_device *dev) +{ + nv50_vm_flush(dev, 5); +} diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index cbf5ae2f67d..8b669d0af61 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = { { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ {} }; + +void +nv50_graph_tlb_flush(struct drm_device *dev) +{ + nv50_vm_flush(dev, 0); +} + +void +nv86_graph_tlb_flush(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; + bool idle, timeout = false; + unsigned long flags; + u64 start; + u32 tmp; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + nv_mask(dev, 0x400500, 0x00000001, 0x00000000); + + start = ptimer->read(dev); + do { + idle = true; + + for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + + for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + + for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000)); + + if (timeout) { + NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: " + "0x%08x 0x%08x 0x%08x 0x%08x\n", + nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380), + nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388)); + } + + nv50_vm_flush(dev, 0); + + nv_mask(dev, 0x400500, 0x00000001, 0x00000001); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); +} diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a53fc974332..b773229b764 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) } dev_priv->engine.instmem.flush(dev); - nv50_vm_flush(dev, 4); nv50_vm_flush(dev, 6); gpuobj->im_bound = 1; -- cgit v1.2.3-70-g09d2 From 63d6fd32889c46fa40cd1631fb2a0162187311ab Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 25 Oct 2010 02:13:21 +0200 Subject: drm/nv10-nv20: Fix instability after MPLL changes. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_pm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c index 6a6eb697d38..eb1c70dd82e 100644 --- a/drivers/gpu/drm/nouveau/nv04_pm.c +++ b/drivers/gpu/drm/nouveau/nv04_pm.c @@ -76,6 +76,15 @@ nv04_pm_clock_set(struct drm_device *dev, void *pre_state) reg += 4; nouveau_hw_setpll(dev, reg, &state->calc); + + if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) { + if (dev_priv->card_type == NV_20) + nv_mask(dev, 0x1002c4, 0, 1 << 20); + + /* Reset the DLLs */ + nv_mask(dev, 0x1002c0, 0, 1 << 8); + } + kfree(state); } -- cgit v1.2.3-70-g09d2 From 84b8081c2baf84b52ac9bf79f07edcea975ab0b5 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 26 Oct 2010 02:17:56 +0200 Subject: drm/nouveau: Don't use load detection for connector polling. Analog output polling makes GL programs jerky when pageflip is being used because it's carried out with the mode_config mutex held. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1dd52dbfad4..52c356e9a3d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -213,24 +213,6 @@ nouveau_connector_set_encoder(struct drm_connector *connector, } } -static bool -nouveau_connector_poll_allowed(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - bool spare_crtc = false; - - if (dev_priv->card_type >= NV_50) { - return true; - } else { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - spare_crtc |= !crtc->enabled; - - return spare_crtc; - } -} - static enum drm_connector_status nouveau_connector_detect(struct drm_connector *connector, bool force) { @@ -299,8 +281,7 @@ detect_analog: nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); if (!nv_encoder && !nouveau_tv_disable) nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); - if (nv_encoder && - (force || nouveau_connector_poll_allowed(connector))) { + if (nv_encoder && force) { struct drm_encoder *encoder = to_drm_encoder(nv_encoder); struct drm_encoder_helper_funcs *helper = encoder->helper_private; @@ -868,14 +849,12 @@ nouveau_connector_create(struct drm_device *dev, int index) dev->mode_config.scaling_mode_property, nv_connector->scaling_mode); } + connector->polled = DRM_CONNECTOR_POLL_CONNECT; /* fall-through */ case DCB_CONNECTOR_TV_0: case DCB_CONNECTOR_TV_1: case DCB_CONNECTOR_TV_3: nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; - - if (nv_gf4_disp_arch(dev)) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; default: nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; -- cgit v1.2.3-70-g09d2 From b54262f3c828ee17e27632d0d60255281c02e1a5 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 26 Oct 2010 12:48:28 +0200 Subject: drm/nouveau: Fix compilation issues in nouveau_pm when CONFIG_HWMON is not set Signed-off-by: Martin Peres Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_pm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 1c99c55d6d4..9f7b158f582 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -284,6 +284,7 @@ nouveau_sysfs_fini(struct drm_device *dev) } } +#ifdef CONFIG_HWMON static ssize_t nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) { @@ -395,10 +396,12 @@ static struct attribute *hwmon_attributes[] = { static const struct attribute_group hwmon_attrgroup = { .attrs = hwmon_attributes, }; +#endif static int nouveau_hwmon_init(struct drm_device *dev) { +#ifdef CONFIG_HWMON struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct device *hwmon_dev; @@ -425,13 +428,14 @@ nouveau_hwmon_init(struct drm_device *dev) } pm->hwmon = hwmon_dev; - +#endif return 0; } static void nouveau_hwmon_fini(struct drm_device *dev) { +#ifdef CONFIG_HWMON struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pm_engine *pm = &dev_priv->engine.pm; @@ -439,6 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev) sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); hwmon_device_unregister(pm->hwmon); } +#endif } int -- cgit v1.2.3-70-g09d2 From dd661e5f4e87609e7a9b4cbdff305dca7f494e7b Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 1 Nov 2010 18:06:28 +0100 Subject: drm/nouveau: Return error from nouveau_gpuobj_new if we're out of RAMIN. Reported-by: Tomas Miljenovic Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 896cf863414..dd572adca02 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -129,7 +129,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, if (ramin == NULL) { spin_unlock(&dev_priv->ramin_lock); nouveau_gpuobj_ref(NULL, &gpuobj); - return ret; + return -ENOMEM; } ramin = drm_mm_get_block_atomic(ramin, size, align); -- cgit v1.2.3-70-g09d2 From 9d5a6c4353eeac1e0095e731a0a746254f23af83 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 1 Nov 2010 18:08:26 +0100 Subject: drm/nouveau: Make PCIE GART size depend on the available RAMIN space. Reported-by: Tomas Miljenovic Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 0b309c1cc3d..d4ac9700703 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -224,11 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev) int i, ret; if (dev_priv->card_type < NV_50) { - if(dev_priv->card_type < NV_40) { - aper_size = (64 * 1024 * 1024); - } else { - aper_size = (512 * 1024 * 1024); - } + if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024) + aper_size = 64 * 1024 * 1024; + else + aper_size = 512 * 1024 * 1024; + obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; obj_size += 8; /* ctxdma header */ } else { -- cgit v1.2.3-70-g09d2 From cac8f05b4294d18cfa940511c286ca03aa6590ad Mon Sep 17 00:00:00 2001 From: Roy Spliet Date: Wed, 20 Oct 2010 01:09:56 +0200 Subject: drm/nouveau/pm: improve memtiming mappings Improvements: - Fix bug in switch statement - Add parts of 0x10022c, 0x10023c - Clean up 0x100234 - Comment out assumption in 0x100228 until verified Signed-off-by: Roy Spliet Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_mem.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index ac3bec024fd..fe4a30dc4b4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -651,6 +651,7 @@ nouveau_mem_gart_init(struct drm_device *dev) void nouveau_mem_timing_init(struct drm_device *dev) { + /* cards < NVC0 only */ struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_memtimings *memtimings = &pm->memtimings; @@ -717,14 +718,14 @@ nouveau_mem_timing_init(struct drm_device *dev) tUNK_19 = 1; tUNK_20 = 0; tUNK_21 = 0; - switch (min(recordlen, 21)) { - case 21: + switch (min(recordlen, 22)) { + case 22: tUNK_21 = entry[21]; - case 20: + case 21: tUNK_20 = entry[20]; - case 19: + case 20: tUNK_19 = entry[19]; - case 18: + case 19: tUNK_18 = entry[18]; default: tUNK_0 = entry[0]; @@ -754,24 +755,30 @@ nouveau_mem_timing_init(struct drm_device *dev) timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); if(recordlen > 19) { timing->reg_100228 += (tUNK_19 - 1) << 24; - } else { + }/* I cannot back-up this else-statement right now + else { timing->reg_100228 += tUNK_12 << 24; - } + }*/ /* XXX: reg_10022c */ + timing->reg_10022c = tUNK_2 - 1; timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | tUNK_13 << 8 | tUNK_13); /* XXX: +6? */ timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); - if(tUNK_10 > tUNK_11) { - timing->reg_100234 += tUNK_10 << 16; - } else { - timing->reg_100234 += tUNK_11 << 16; + timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; + + /* XXX; reg_100238, reg_10023c + * reg: 0x00?????? + * reg_10023c: + * 0 for pre-NV50 cards + * 0x????0202 for NV50+ cards (empirical evidence) */ + if(dev_priv->card_type >= NV_50) { + timing->reg_10023c = 0x202; } - /* XXX; reg_100238, reg_10023c */ NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, timing->reg_100220, timing->reg_100224, timing->reg_100228, timing->reg_10022c); -- cgit v1.2.3-70-g09d2 From 5bead799d3f8f1500c4b59301b8a2732a92f559f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 4 Nov 2010 09:56:12 +1000 Subject: drm/nouveau: don't expose backlight control when available through ACPI Avoid confusing userspace by not publishing backlight controls if ACPI equivalents are available. Reported-by: Aaron Sowry Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_backlight.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 406228f4a2a..b14c8111057 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -31,6 +31,7 @@ */ #include +#include #include "drmP.h" #include "nouveau_drv.h" @@ -136,6 +137,14 @@ int nouveau_backlight_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; +#ifdef CONFIG_ACPI + if (acpi_video_backlight_support()) { + NV_INFO(dev, "ACPI backlight interface available, " + "not registering our own\n"); + return 0; + } +#endif + switch (dev_priv->card_type) { case NV_40: return nouveau_nv40_backlight_init(dev); -- cgit v1.2.3-70-g09d2 From c1b60ece91460214b5135360a375f3f6fbb59608 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 11 Nov 2010 00:56:37 +0100 Subject: drm/nouveau: Fix a few confusions between "chipset" and "card_type". Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- drivers/gpu/drm/nouveau/nouveau_i2c.c | 2 +- drivers/gpu/drm/nouveau/nouveau_temp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 5f21030a293..b2293576f27 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6829,7 +6829,7 @@ nouveau_bios_posted(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; unsigned htotal; - if (dev_priv->chipset >= NV_50) { + if (dev_priv->card_type >= NV_50) { if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && NVReadVgaCrtc(dev, 0, 0x1a) == 0) return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index fdd7e3de79c..cb389d01432 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -256,7 +256,7 @@ nouveau_i2c_find(struct drm_device *dev, int index) if (index >= DCB_MAX_NUM_I2C_ENTRIES) return NULL; - if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) { + if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) { uint32_t reg = 0xe500, val; if (i2c->port_type == 6) { diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c index 16bbbf1eff6..7ecc4adc1e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_temp.c +++ b/drivers/gpu/drm/nouveau/nouveau_temp.c @@ -191,7 +191,7 @@ nv40_temp_get(struct drm_device *dev) int offset = sensor->offset_mult / sensor->offset_div; int core_temp; - if (dev_priv->chipset >= 0x50) { + if (dev_priv->card_type >= NV_50) { core_temp = nv_rd32(dev, 0x20008); } else { core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff; -- cgit v1.2.3-70-g09d2 From ab838338a2a9e0cb8346eb0cab9977be13e8dce5 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 16 Nov 2010 18:40:52 -0500 Subject: nouveau: Acknowledge HPD irq in handler, not bottom half The old code generated an interrupt storm bad enough to completely take down my system. Signed-off-by: Andy Lutomirski Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 6 ++++++ drivers/gpu/drm/nouveau/nouveau_irq.c | 1 + drivers/gpu/drm/nouveau/nv50_display.c | 35 +++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 10a8d4e78e5..1c7db64c03b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -584,6 +584,12 @@ struct drm_nouveau_private { struct work_struct irq_work; struct work_struct hpd_work; + struct { + spinlock_t lock; + uint32_t hpd0_bits; + uint32_t hpd1_bits; + } hpd_state; + struct list_head vbl_waiting; struct { diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index e2f2d59be3e..7bfd9e6c9d6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -60,6 +60,7 @@ nouveau_irq_preinstall(struct drm_device *dev) if (dev_priv->card_type >= NV_50) { INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); + spin_lock_init(&dev_priv->hpd_state.lock); INIT_LIST_HEAD(&dev_priv->vbl_waiting); } } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 55c9663ef2b..f624c611dde 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1032,11 +1032,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) struct drm_connector *connector; const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; uint32_t unplug_mask, plug_mask, change_mask; - uint32_t hpd0, hpd1 = 0; + uint32_t hpd0, hpd1; - hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); + spin_lock_irq(&dev_priv->hpd_state.lock); + hpd0 = dev_priv->hpd_state.hpd0_bits; + dev_priv->hpd_state.hpd0_bits = 0; + hpd1 = dev_priv->hpd_state.hpd1_bits; + dev_priv->hpd_state.hpd1_bits = 0; + spin_unlock_irq(&dev_priv->hpd_state.lock); + + hpd0 &= nv_rd32(dev, 0xe050); if (dev_priv->chipset >= 0x90) - hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); + hpd1 &= nv_rd32(dev, 0xe070); plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); @@ -1078,10 +1085,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); } - nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054)); - if (dev_priv->chipset >= 0x90) - nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074)); - drm_helper_hpd_irq_event(dev); } @@ -1092,8 +1095,22 @@ nv50_display_irq_handler(struct drm_device *dev) uint32_t delayed = 0; if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { - if (!work_pending(&dev_priv->hpd_work)) - queue_work(dev_priv->wq, &dev_priv->hpd_work); + uint32_t hpd0_bits, hpd1_bits = 0; + + hpd0_bits = nv_rd32(dev, 0xe054); + nv_wr32(dev, 0xe054, hpd0_bits); + + if (dev_priv->chipset >= 0x90) { + hpd1_bits = nv_rd32(dev, 0xe074); + nv_wr32(dev, 0xe074, hpd1_bits); + } + + spin_lock(&dev_priv->hpd_state.lock); + dev_priv->hpd_state.hpd0_bits |= hpd0_bits; + dev_priv->hpd_state.hpd1_bits |= hpd1_bits; + spin_unlock(&dev_priv->hpd_state.lock); + + queue_work(dev_priv->wq, &dev_priv->hpd_work); } while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { -- cgit v1.2.3-70-g09d2 From 16790569eddf4d406a16a65f4750f405fa669c52 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 14 Nov 2010 20:24:35 -0500 Subject: drm/radeon/kms: fix and unify tiled buffer alignment checking for r6xx/7xx Tiled buffers have the same alignment requirements regardless of whether the surface is for db, cb, or textures. Previously, the calculations where inconsistent for each buffer type. - Unify the alignment calculations in a common function - Standardize the alignment units (pixels for pitch/height/depth, bytes for base) - properly check the buffer base alignments Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 309 ++++++++++++++++++++++++--------------- drivers/gpu/drm/radeon/r600d.h | 6 + 2 files changed, 199 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 37cc2aa9f92..0f90fc3482c 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -50,6 +50,7 @@ struct r600_cs_track { u32 nsamples; u32 cb_color_base_last[8]; struct radeon_bo *cb_color_bo[8]; + u64 cb_color_bo_mc[8]; u32 cb_color_bo_offset[8]; struct radeon_bo *cb_color_frag_bo[8]; struct radeon_bo *cb_color_tile_bo[8]; @@ -67,6 +68,7 @@ struct r600_cs_track { u32 db_depth_size; u32 db_offset; struct radeon_bo *db_bo; + u64 db_bo_mc; }; static inline int r600_bpe_from_format(u32 *bpe, u32 format) @@ -140,6 +142,68 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format) return 0; } +struct array_mode_checker { + int array_mode; + u32 group_size; + u32 nbanks; + u32 npipes; + u32 nsamples; + u32 bpe; +}; + +/* returns alignment in pixels for pitch/height/depth and bytes for base */ +static inline int r600_get_array_mode_alignment(struct array_mode_checker *values, + u32 *pitch_align, + u32 *height_align, + u32 *depth_align, + u64 *base_align) +{ + u32 tile_width = 8; + u32 tile_height = 8; + u32 macro_tile_width = values->nbanks; + u32 macro_tile_height = values->npipes; + u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples; + u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; + + switch (values->array_mode) { + case ARRAY_LINEAR_GENERAL: + /* technically tile_width/_height for pitch/height */ + *pitch_align = 1; /* tile_width */ + *height_align = 1; /* tile_height */ + *depth_align = 1; + *base_align = 1; + break; + case ARRAY_LINEAR_ALIGNED: + *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe)); + *height_align = tile_height; + *depth_align = 1; + *base_align = values->group_size; + break; + case ARRAY_1D_TILED_THIN1: + *pitch_align = max((u32)tile_width, + (u32)(values->group_size / + (tile_height * values->bpe * values->nsamples))); + *height_align = tile_height; + *depth_align = 1; + *base_align = values->group_size; + break; + case ARRAY_2D_TILED_THIN1: + *pitch_align = max((u32)macro_tile_width, + (u32)(((values->group_size / tile_height) / + (values->bpe * values->nsamples)) * + values->nbanks)) * tile_width; + *height_align = macro_tile_height * tile_height; + *depth_align = 1; + *base_align = max(macro_tile_bytes, + (*pitch_align) * values->bpe * (*height_align) * values->nsamples); + break; + default: + return -EINVAL; + } + + return 0; +} + static void r600_cs_track_init(struct r600_cs_track *track) { int i; @@ -153,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track) track->cb_color_info[i] = 0; track->cb_color_bo[i] = NULL; track->cb_color_bo_offset[i] = 0xFFFFFFFF; + track->cb_color_bo_mc[i] = 0xFFFFFFFF; } track->cb_target_mask = 0xFFFFFFFF; track->cb_shader_mask = 0xFFFFFFFF; track->db_bo = NULL; + track->db_bo_mc = 0xFFFFFFFF; /* assume the biggest format and that htile is enabled */ track->db_depth_info = 7 | (1 << 25); track->db_depth_view = 0xFFFFC000; @@ -168,7 +234,10 @@ static void r600_cs_track_init(struct r600_cs_track *track) static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) { struct r600_cs_track *track = p->track; - u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; + u32 bpe = 0, slice_tile_max, size, tmp; + u32 height, height_align, pitch, pitch_align, depth_align; + u64 base_offset, base_align; + struct array_mode_checker array_check; volatile u32 *ib = p->ib->ptr; unsigned array_mode; @@ -183,60 +252,40 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) i, track->cb_color_info[i]); return -EINVAL; } - /* pitch is the number of 8x8 tiles per row */ - pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; + /* pitch in pixels */ + pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; slice_tile_max *= 64; - height = slice_tile_max / (pitch * 8); + height = slice_tile_max / pitch; if (height > 8192) height = 8192; array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); + + base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; + array_check.array_mode = array_mode; + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = track->nsamples; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, + G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, + track->cb_color_info[i]); + return -EINVAL; + } switch (array_mode) { case V_0280A0_ARRAY_LINEAR_GENERAL: - /* technically height & 0x7 */ break; case V_0280A0_ARRAY_LINEAR_ALIGNED: - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_0280A0_ARRAY_1D_TILED_THIN1: - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } /* avoid breaking userspace */ if (height > 7) height &= ~0x7; - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_0280A0_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED((height / 8), track->npipes)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; default: dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, @@ -244,8 +293,24 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) track->cb_color_info[i]); return -EINVAL; } + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, height_align)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; + } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + return -EINVAL; + } + /* check offset */ - tmp = height * pitch * 8 * bpe; + tmp = height * pitch * bpe; if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { /* the initial DDX does bad things with the CB size occasionally */ @@ -260,15 +325,11 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) return -EINVAL; } } - if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); - return -EINVAL; - } /* limit max tile */ - tmp = (height * pitch * 8) >> 6; + tmp = (height * pitch) >> 6; if (tmp < slice_tile_max) slice_tile_max = tmp; - tmp = S_028060_PITCH_TILE_MAX(pitch - 1) | + tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); ib[track->cb_color_size_idx[i]] = tmp; return 0; @@ -310,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) /* Check depth buffer */ if (G_028800_STENCIL_ENABLE(track->db_depth_control) || G_028800_Z_ENABLE(track->db_depth_control)) { - u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max; + u32 nviews, bpe, ntiles, size, slice_tile_max; + u32 height, height_align, pitch, pitch_align, depth_align; + u64 base_offset, base_align; + struct array_mode_checker array_check; + int array_mode; + if (track->db_bo == NULL) { dev_warn(p->dev, "z/stencil with no depth buffer\n"); return -EINVAL; @@ -353,41 +419,34 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); } else { size = radeon_bo_size(track->db_bo); - pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1; + /* pitch in pixels */ + pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; slice_tile_max *= 64; - height = slice_tile_max / (pitch * 8); + height = slice_tile_max / pitch; if (height > 8192) height = 8192; - switch (G_028010_ARRAY_MODE(track->db_depth_info)) { + base_offset = track->db_bo_mc + track->db_offset; + array_mode = G_028010_ARRAY_MODE(track->db_depth_info); + array_check.array_mode = array_mode; + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = track->nsamples; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, + G_028010_ARRAY_MODE(track->db_depth_info), + track->db_depth_info); + return -EINVAL; + } + switch (array_mode) { case V_028010_ARRAY_1D_TILED_THIN1: - pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8); - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } /* don't break userspace */ height &= ~0x7; - if (!IS_ALIGNED(height, 8)) { - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; case V_028010_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - if (!IS_ALIGNED((height / 8), track->npipes)) { - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", - __func__, __LINE__, height); - return -EINVAL; - } break; default: dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, @@ -395,15 +454,27 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) track->db_depth_info); return -EINVAL; } - if (!IS_ALIGNED(track->db_offset, track->group_size)) { - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset); + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, height_align)) { + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + return -EINVAL; + } + ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; tmp = ntiles * bpe * 64 * nviews; if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { - dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n", + dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, radeon_bo_size(track->db_bo)); return -EINVAL; @@ -954,6 +1025,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); track->cb_color_base_last[tmp] = ib[idx]; track->cb_color_bo[tmp] = reloc->robj; + track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset; break; case DB_DEPTH_BASE: r = r600_cs_packet_next_reloc(p, &reloc); @@ -965,6 +1037,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx track->db_offset = radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); track->db_bo = reloc->robj; + track->db_bo_mc = reloc->lobj.gpu_offset; break; case DB_HTILE_DATA_BASE: case SQ_PGM_START_FS: @@ -1086,16 +1159,25 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, struct radeon_bo *texture, struct radeon_bo *mipmap, + u64 base_offset, + u64 mip_offset, u32 tiling_flags) { struct r600_cs_track *track = p->track; u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; - u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align; + u32 word0, word1, l0_size, mipmap_size; + u32 height_align, pitch, pitch_align, depth_align; + u64 base_align; + struct array_mode_checker array_check; /* on legacy kernel we don't perform advanced check */ if (p->rdev == NULL) return 0; + /* convert to bytes */ + base_offset <<= 8; + mip_offset <<= 8; + word0 = radeon_get_ib_value(p, idx + 0); if (tiling_flags & RADEON_TILING_MACRO) word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); @@ -1128,46 +1210,38 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i return -EINVAL; } - pitch = G_038000_PITCH(word0) + 1; - switch (G_038000_TILE_MODE(word0)) { - case V_038000_ARRAY_LINEAR_GENERAL: - pitch_align = 1; - /* XXX check height align */ - break; - case V_038000_ARRAY_LINEAR_ALIGNED: - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - case V_038000_ARRAY_1D_TILED_THIN1: - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - case V_038000_ARRAY_2D_TILED_THIN1: - pitch_align = max((u32)track->nbanks, - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); - return -EINVAL; - } - /* XXX check height align */ - break; - default: - dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, - G_038000_TILE_MODE(word0), word0); + /* pitch in texels */ + pitch = (G_038000_PITCH(word0) + 1) * 8; + array_check.array_mode = G_038000_TILE_MODE(word0); + array_check.group_size = track->group_size; + array_check.nbanks = track->nbanks; + array_check.npipes = track->npipes; + array_check.nsamples = 1; + array_check.bpe = bpe; + if (r600_get_array_mode_alignment(&array_check, + &pitch_align, &height_align, &depth_align, &base_align)) { + dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", + __func__, __LINE__, G_038000_TILE_MODE(word0)); + return -EINVAL; + } + + /* XXX check height as well... */ + + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(base_offset, base_align)) { + dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", + __func__, __LINE__, base_offset); + return -EINVAL; + } + if (!IS_ALIGNED(mip_offset, base_align)) { + dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", + __func__, __LINE__, mip_offset); return -EINVAL; } - /* XXX check offset align */ word0 = radeon_get_ib_value(p, idx + 4); word1 = radeon_get_ib_value(p, idx + 5); @@ -1402,7 +1476,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); mipmap = reloc->robj; r = r600_check_texture_resource(p, idx+(i*7)+1, - texture, mipmap, reloc->lobj.tiling_flags); + texture, mipmap, + base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), + mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), + reloc->lobj.tiling_flags); if (r) return r; ib[idx+1+(i*7)+2] += base_offset; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 966a793e225..bff4dc4f410 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -51,6 +51,12 @@ #define PTE_READABLE (1 << 5) #define PTE_WRITEABLE (1 << 6) +/* tiling bits */ +#define ARRAY_LINEAR_GENERAL 0x00000000 +#define ARRAY_LINEAR_ALIGNED 0x00000001 +#define ARRAY_1D_TILED_THIN1 0x00000002 +#define ARRAY_2D_TILED_THIN1 0x00000004 + /* Registers */ #define ARB_POP 0x2418 #define ENABLE_TC128 (1 << 30) -- cgit v1.2.3-70-g09d2 From 21e2eae4daaecf2f2a391e4f4b596c800f198edf Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 14 Nov 2010 23:08:27 +0300 Subject: drm: radeon: fix error value sign enable_vblank implementations should use negative result to indicate error. radeon_enable_vblank() returns EINVAL in this case. Change this to -EINVAL. Signed-off-by: Vasiliy Kulikov Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index 2f349a30019..465746bd51b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c @@ -76,7 +76,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return EINVAL; + return -EINVAL; } } else { switch (crtc) { @@ -89,7 +89,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return EINVAL; + return -EINVAL; } } -- cgit v1.2.3-70-g09d2 From d33ef52d9db8a36900dd53f2e32db9a521ace259 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Nov 2010 16:53:14 -0500 Subject: drm/radeon/kms: fix typo in r600 cs checker Looks like a typo in: drm/radeon/r600: fix tiling issues in CS checker. (f30df2fad0c901e74ac9a52a488a54c69a373a41) Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0f90fc3482c..9bebac1ec00 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -315,7 +315,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { /* the initial DDX does bad things with the CB size occasionally */ /* it rounds up height too far for slice tile max but the BO is smaller */ - tmp = (height - 7) * 8 * bpe; + tmp = (height - 7) * pitch * bpe; if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); return -EINVAL; -- cgit v1.2.3-70-g09d2 From ba251bde9ab8bdce8fbd3f60dbb71b36cc4c9adf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Nov 2010 12:09:39 -0500 Subject: drm/radeon/kms: turn the backlight off explicitly for dpms Seems some newer systems require this explicitly. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index f678257c42e..d55cb58283a 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1086,6 +1086,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); } + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: @@ -1095,20 +1097,31 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); } + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); break; } } else { switch (mode) { case DRM_MODE_DPMS_ON: args.ucAction = ATOM_ENABLE; + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + args.ucAction = ATOM_LCD_BLON; + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + } break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: args.ucAction = ATOM_DISABLE; + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + args.ucAction = ATOM_LCD_BLOFF; + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + } break; } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); -- cgit v1.2.3-70-g09d2 From c7a71fc761551dc8be8543f14a90d08cda4e77f9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Nov 2010 02:49:40 -0500 Subject: drm/radeon/kms/atom: set sane defaults in atombios_get_encoder_mode() If there was no connector mapped to the encoder, atombios_get_encoder_mode() returned 0 which is the id for DP. Return something sane instead based on the encoder id. This avoids hitting the DP paths on non-DP encoders. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index d55cb58283a..c6981dfd915 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -595,6 +595,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) int atombios_get_encoder_mode(struct drm_encoder *encoder) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct drm_connector *connector; @@ -602,9 +603,20 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) struct radeon_connector_atom_dig *dig_connector; connector = radeon_get_connector_for_encoder(encoder); - if (!connector) - return 0; - + if (!connector) { + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + return ATOM_ENCODER_MODE_DVI; + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + default: + return ATOM_ENCODER_MODE_CRT; + } + } radeon_connector = to_radeon_connector(connector); switch (connector->connector_type) { -- cgit v1.2.3-70-g09d2 From 8b834852d705af75ba942b040ca28533329ff13c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Nov 2010 02:54:42 -0500 Subject: drm/radeon/kms: properly power up/down the eDP panel as needed (v4) The eDP panel must be powered up for aux transactions, so power it up for detect and mode probe functions, otherwise power it up or down based on dpms. v2: - only mess with eDP panel on DCE4+ - only mess with eDP panel on eDP connectors, not all DP connectors v3: - be extra careful to only mess with eDP panels on eDP connectors v4: - avoid possible null derefernce if a connector has not been assigned to the encoder Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 18 +++++++++++ drivers/gpu/drm/radeon/radeon_encoders.c | 50 ++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 2 ++ 3 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fe6c74780f1..3bef9f6d66f 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1008,9 +1008,21 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) static int radeon_dp_get_modes(struct drm_connector *connector) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; int ret; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_ON); + } ret = radeon_ddc_get_modes(radeon_connector); + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_OFF); + } + return ret; } @@ -1029,8 +1041,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { /* eDP is always DP */ radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_ON); if (radeon_dp_getdpcd(radeon_connector)) ret = connector_status_connected; + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_OFF); } else { radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index c6981dfd915..63f4964e8d2 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -990,6 +990,36 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +void +atombios_set_edp_panel_power(struct drm_connector *connector, int action) +{ + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct drm_device *dev = radeon_connector->base.dev; + struct radeon_device *rdev = dev->dev_private; + union dig_transmitter_control args; + int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); + uint8_t frev, crev; + + if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) + return; + + if (!ASIC_IS_DCE4(rdev)) + return; + + if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) || + (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) + return; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return; + + memset(&args, 0, sizeof(args)); + + args.v1.ucAction = action; + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + static void atombios_yuv_setup(struct drm_encoder *encoder, bool enable) { @@ -1094,6 +1124,15 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + if (connector && + (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *radeon_dig_connector = + radeon_connector->con_priv; + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_ON); + radeon_dig_connector->edp_on = true; + } dp_link_train(encoder, connector); if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); @@ -1106,8 +1145,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_OFF: atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); + if (connector && + (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *radeon_dig_connector = + radeon_connector->con_priv; + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_OFF); + radeon_dig_connector->edp_on = false; + } } if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 680f57644e8..ef588835201 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -385,6 +385,7 @@ struct radeon_connector_atom_dig { u8 dp_sink_type; int dp_clock; int dp_lane_count; + bool edp_on; }; struct radeon_gpio_rec { @@ -526,6 +527,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, i extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); extern void atombios_digital_setup(struct drm_encoder *encoder, int action); extern int atombios_get_encoder_mode(struct drm_encoder *encoder); +extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action); extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); extern void radeon_crtc_load_lut(struct drm_crtc *crtc); -- cgit v1.2.3-70-g09d2 From 99999aaa091bdb3e16b5eed22f3a9a567f84f0fe Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Nov 2010 12:09:41 -0500 Subject: drm/radeon/kms/atom: cleanup and unify DVO handling Handle all the various asic family specific things for DVO. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 4 ++ drivers/gpu/drm/radeon/radeon_encoders.c | 90 +++++++++++++------------ drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 2 +- drivers/gpu/drm/radeon/radeon_mode.h | 2 +- 4 files changed, 52 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 73f600d39ad..3a7095743d4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); (rdev->family == CHIP_RS400) || \ (rdev->family == CHIP_RS480)) #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) +#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ + (rdev->family == CHIP_RS690) || \ + (rdev->family == CHIP_RS740) || \ + (rdev->family >= CHIP_R600)) #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 63f4964e8d2..07df990a897 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) return false; } } + void radeon_link_encoder_connector(struct drm_device *dev) { @@ -426,52 +427,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) } -void -atombios_external_tmds_setup(struct drm_encoder *encoder, int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args; - int index = 0; - - memset(&args, 0, sizeof(args)); - - index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); - - args.sXTmdsEncoder.ucEnable = action; - - if (radeon_encoder->pixel_clock > 165000) - args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL; - - /*if (pScrn->rgbBits == 8)*/ - args.sXTmdsEncoder.ucMisc |= (1 << 1); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - -} +union dvo_encoder_control { + ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; + DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; + DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; +}; -static void -atombios_ddia_setup(struct drm_encoder *encoder, int action) +void +atombios_dvo_setup(struct drm_encoder *encoder, int action) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DVO_ENCODER_CONTROL_PS_ALLOCATION args; - int index = 0; + union dvo_encoder_control args; + int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); memset(&args, 0, sizeof(args)); - index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); + if (ASIC_IS_DCE3(rdev)) { + /* DCE3+ */ + args.dvo_v3.ucAction = action; + args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.dvo_v3.ucDVOConfig = 0; /* XXX */ + } else if (ASIC_IS_DCE2(rdev)) { + /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */ + args.dvo.sDVOEncoder.ucAction = action; + args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + /* DFP1, CRT1, TV1 depending on the type of port */ + args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; + + if (radeon_encoder->pixel_clock > 165000) + args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; + } else { + /* R4xx, R5xx */ + args.ext_tmds.sXTmdsEncoder.ucEnable = action; - args.sDVOEncoder.ucAction = action; - args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + if (radeon_encoder->pixel_clock > 165000) + args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (radeon_encoder->pixel_clock > 165000) - args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL; + /*if (pScrn->rgbBits == 8)*/ + args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; + } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - } union lvds_encoder_control { @@ -532,14 +530,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - args.v1.ucMisc |= (1 << 1); + args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; } else { if (dig->linkb) args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; if (radeon_encoder->pixel_clock > 165000) args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; /*if (pScrn->rgbBits == 8) */ - args.v1.ucMisc |= (1 << 1); + args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; } break; case 2: @@ -846,6 +844,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t memset(&args, 0, sizeof(args)); switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); + break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: @@ -1085,9 +1086,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); break; + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + if (ASIC_IS_DCE3(rdev)) + is_dig = true; + else + index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); + break; case ENCODER_OBJECT_ID_INTERNAL_LVDS: index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); break; @@ -1317,7 +1323,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) break; default: DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); - break; + return; } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -1475,11 +1481,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } break; case ENCODER_OBJECT_ID_INTERNAL_DDI: - atombios_ddia_setup(encoder, ATOM_ENABLE); - break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - atombios_external_tmds_setup(encoder, ATOM_ENABLE); + atombios_dvo_setup(encoder, ATOM_ENABLE); break; case ENCODER_OBJECT_ID_INTERNAL_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: @@ -1670,11 +1674,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) } break; case ENCODER_OBJECT_ID_INTERNAL_DDI: - atombios_ddia_setup(encoder, ATOM_DISABLE); - break; case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - atombios_external_tmds_setup(encoder, ATOM_DISABLE); + atombios_dvo_setup(encoder, ATOM_DISABLE); break; case ENCODER_OBJECT_ID_INTERNAL_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 0b8397000f4..59f834ba283 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, if (rdev->is_atom_bios) { radeon_encoder->pixel_clock = adjusted_mode->clock; - atombios_external_tmds_setup(encoder, ATOM_ENABLE); + atombios_dvo_setup(encoder, ATOM_ENABLE); fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); } else { fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ef588835201..663bc51cf99 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -524,7 +524,7 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); -extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); +extern void atombios_dvo_setup(struct drm_encoder *encoder, int action); extern void atombios_digital_setup(struct drm_encoder *encoder, int action); extern int atombios_get_encoder_mode(struct drm_encoder *encoder); extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action); -- cgit v1.2.3-70-g09d2 From 3e4b99828d1c8abefefd37474503605c811c1b51 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Nov 2010 12:09:42 -0500 Subject: drm/radeon/kms/atom: add proper external encoders support These are external encoder chips connected via DVO or DP. The actual external encoder programming is handled by the kms encoder functions for primary encoder. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 183 +++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 1 + 2 files changed, 184 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 07df990a897..041943df966 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -229,6 +229,27 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) return NULL; } +struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_encoder *other_encoder; + struct radeon_encoder *other_radeon_encoder; + + if (radeon_encoder->is_ext_encoder) + return NULL; + + list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { + if (other_encoder == encoder) + continue; + other_radeon_encoder = to_radeon_encoder(other_encoder); + if (other_radeon_encoder->is_ext_encoder && + (radeon_encoder->devices & other_radeon_encoder->devices)) + return other_encoder; + } + return NULL; +} + void radeon_panel_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { @@ -1021,6 +1042,75 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +union external_encoder_control { + EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; +}; + +static void +atombios_external_encoder_setup(struct drm_encoder *encoder, + struct drm_encoder *ext_encoder, + int action) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + union external_encoder_control args; + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); + u8 frev, crev; + int dp_clock = 0; + int dp_lane_count = 0; + int connector_object_id = 0; + + if (connector) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector = + radeon_connector->con_priv; + + dp_clock = dig_connector->dp_clock; + dp_lane_count = dig_connector->dp_lane_count; + connector_object_id = + (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + } + + memset(&args, 0, sizeof(args)); + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return; + + switch (frev) { + case 1: + /* no params on frev 1 */ + break; + case 2: + switch (crev) { + case 1: + case 2: + args.v1.sDigEncoder.ucAction = action; + args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); + + if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { + if (dp_clock == 270000) + args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; + args.v1.sDigEncoder.ucLaneNum = dp_lane_count; + } else if (radeon_encoder->pixel_clock > 165000) + args.v1.sDigEncoder.ucLaneNum = 8; + else + args.v1.sDigEncoder.ucLaneNum = 4; + break; + default: + DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); + return; + } + break; + default: + DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); + return; + } + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + static void atombios_yuv_setup(struct drm_encoder *encoder, bool enable) { @@ -1064,6 +1154,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; int index = 0; bool is_dig = false; @@ -1191,6 +1282,24 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) break; } } + + if (ext_encoder) { + int action; + + switch (mode) { + case DRM_MODE_DPMS_ON: + default: + action = ATOM_ENABLE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + action = ATOM_DISABLE; + break; + } + atombios_external_encoder_setup(encoder, ext_encoder, action); + } + radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); } @@ -1438,6 +1547,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); radeon_encoder->pixel_clock = adjusted_mode->clock; @@ -1498,6 +1608,11 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } break; } + + if (ext_encoder) { + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); + } + atombios_apply_encoder_quirks(encoder, adjusted_mode); if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { @@ -1698,6 +1813,53 @@ disable_done: radeon_encoder->active_device = 0; } +/* these are handled by the primary encoders */ +static void radeon_atom_ext_prepare(struct drm_encoder *encoder) +{ + +} + +static void radeon_atom_ext_commit(struct drm_encoder *encoder) +{ + +} + +static void +radeon_atom_ext_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + +} + +static void radeon_atom_ext_disable(struct drm_encoder *encoder) +{ + +} + +static void +radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) +{ + +} + +static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { + .dpms = radeon_atom_ext_dpms, + .mode_fixup = radeon_atom_ext_mode_fixup, + .prepare = radeon_atom_ext_prepare, + .mode_set = radeon_atom_ext_mode_set, + .commit = radeon_atom_ext_commit, + .disable = radeon_atom_ext_disable, + /* no detect for TMDS/LVDS yet */ +}; + static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { .dpms = radeon_atom_encoder_dpms, .mode_fixup = radeon_atom_mode_fixup, @@ -1807,6 +1969,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t radeon_encoder->devices = supported_device; radeon_encoder->rmx_type = RMX_OFF; radeon_encoder->underscan_type = UNDERSCAN_OFF; + radeon_encoder->is_ext_encoder = false; switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_LVDS: @@ -1848,6 +2011,9 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t radeon_encoder->rmx_type = RMX_FULL; drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); + } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); + radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); } else { drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); @@ -1856,5 +2022,22 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t } drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; + case ENCODER_OBJECT_ID_SI170B: + case ENCODER_OBJECT_ID_CH7303: + case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: + case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: + case ENCODER_OBJECT_ID_TITFP513: + case ENCODER_OBJECT_ID_VT1623: + case ENCODER_OBJECT_ID_HDMI_SI1930: + /* these are handled by the primary encoders */ + radeon_encoder->is_ext_encoder = true; + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); + else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); + else + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); + drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); + break; } } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 663bc51cf99..e301c6f9e05 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -375,6 +375,7 @@ struct radeon_encoder { int hdmi_config_offset; int hdmi_audio_workaround; int hdmi_buffer_status; + bool is_ext_encoder; }; struct radeon_connector_atom_dig { -- cgit v1.2.3-70-g09d2 From a5193fe50e7f21c26d22c17c8196420fac1a3ca7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Nov 2010 17:56:49 -0500 Subject: drm/radeon/kms: register an i2c adapter name for the dp aux bus This causes the connector to not be added since i2c init fails for the adapter. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=31688 Noticed by Ari Savolainen. Signed-off-by: Alex Deucher Cc: Ari Savolainen Cc: Jean Delvare Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_i2c.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 0cfbba02c4d..d263bd1a0d8 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -946,6 +946,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->dev = dev; + sprintf(i2c->adapter.name, "Radeon aux bus %s", name); i2c_set_adapdata(&i2c->adapter, i2c); i2c->adapter.algo_data = &i2c->algo.dp; i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; -- cgit v1.2.3-70-g09d2 From 2f5993cca67f9c80dcd390feef13695ca072b8a5 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 13:24:48 +0100 Subject: drm/vmwgfx: Fix up an error path during bo creation Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 36e129f0023..5408b1b7996 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -862,7 +862,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data, &vmw_vram_sys_placement, true, &vmw_user_dmabuf_destroy); if (unlikely(ret != 0)) - return ret; + goto out_no_dmabuf; tmp = ttm_bo_reference(&vmw_user_bo->dma.base); ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, @@ -870,19 +870,21 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data, false, ttm_buffer_type, &vmw_user_dmabuf_release, NULL); - if (unlikely(ret != 0)) { - ttm_bo_unref(&tmp); - } else { + if (unlikely(ret != 0)) + goto out_no_base_object; + else { rep->handle = vmw_user_bo->base.hash.key; rep->map_handle = vmw_user_bo->dma.base.addr_space_offset; rep->cur_gmr_id = vmw_user_bo->base.hash.key; rep->cur_gmr_offset = 0; } - ttm_bo_unref(&tmp); +out_no_base_object: + ttm_bo_unref(&tmp); +out_no_dmabuf: ttm_read_unlock(&vmaster->lock); - return 0; + return ret; } int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data, -- cgit v1.2.3-70-g09d2 From 268b2510de14f62134d87ba9b4981816192db386 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Nov 2010 19:00:26 -0500 Subject: drm/radeon/kms: fix alignment when allocating buffers We were previously dropping alignment requests on the floor when allocating buffers so we always ended up page aligned. Certain tiling modes on 6xx+ require larger alignment which wasn't happening before. Signed-off-by: Alex Deucher Cc: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 2 +- drivers/gpu/drm/radeon/r600.c | 2 +- drivers/gpu/drm/radeon/r600_blit_kms.c | 2 +- drivers/gpu/drm/radeon/radeon_benchmark.c | 4 ++-- drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/gpu/drm/radeon/radeon_gart.c | 4 ++-- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 7 ++++--- drivers/gpu/drm/radeon/radeon_object.h | 7 ++++--- drivers/gpu/drm/radeon/radeon_ring.c | 6 +++--- drivers/gpu/drm/radeon/radeon_test.c | 4 ++-- drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- drivers/gpu/drm/radeon/rv770.c | 4 ++-- 13 files changed, 25 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index ac3b6dde23d..e0e590110dd 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -459,7 +459,7 @@ int evergreen_blit_init(struct radeon_device *rdev) obj_size += evergreen_ps_size * 4; obj_size = ALIGN(obj_size, 256); - r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM, + r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, &rdev->r600_blit.shader_obj); if (r) { DRM_ERROR("evergreen failed to allocate shader\n"); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 0f806cc7dc7..a3552594ccc 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2718,7 +2718,7 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev) /* Allocate ring buffer */ if (rdev->ih.ring_obj == NULL) { r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, - true, + PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, &rdev->ih.ring_obj); if (r) { diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 8362974ef41..86e5aa07f0d 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -501,7 +501,7 @@ int r600_blit_init(struct radeon_device *rdev) obj_size += r6xx_ps_size * 4; obj_size = ALIGN(obj_size, 256); - r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM, + r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, &rdev->r600_blit.shader_obj); if (r) { DRM_ERROR("r600 failed to allocate shader\n"); diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 7932dc4d6b9..c558685cc63 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -41,7 +41,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, size = bsize; n = 1024; - r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj); + r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, sdomain, &sobj); if (r) { goto out_cleanup; } @@ -53,7 +53,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, if (r) { goto out_cleanup; } - r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj); + r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, ddomain, &dobj); if (r) { goto out_cleanup; } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 8adfedfe547..d8ac1849180 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -180,7 +180,7 @@ int radeon_wb_init(struct radeon_device *rdev) int r; if (rdev->wb.wb_obj == NULL) { - r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, + r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); if (r) { dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index e65b90317fa..65016117d95 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -79,8 +79,8 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) if (rdev->gart.table.vram.robj == NULL) { r = radeon_bo_create(rdev, NULL, rdev->gart.table_size, - true, RADEON_GEM_DOMAIN_VRAM, - &rdev->gart.table.vram.robj); + PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, + &rdev->gart.table.vram.robj); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d1e595d9172..df95eb83dac 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -67,7 +67,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, if (alignment < PAGE_SIZE) { alignment = PAGE_SIZE; } - r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj); + r = radeon_bo_create(rdev, gobj, size, alignment, kernel, initial_domain, &robj); if (r) { if (r != -ERESTARTSYS) DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8eb18346601..1d067743fee 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -86,11 +86,12 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) } int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, - unsigned long size, bool kernel, u32 domain, - struct radeon_bo **bo_ptr) + unsigned long size, int byte_align, bool kernel, u32 domain, + struct radeon_bo **bo_ptr) { struct radeon_bo *bo; enum ttm_bo_type type; + int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -115,7 +116,7 @@ retry: /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, - &bo->placement, 0, 0, !kernel, NULL, size, + &bo->placement, page_align, 0, !kernel, NULL, size, &radeon_ttm_bo_destroy); mutex_unlock(&rdev->vram_mutex); if (unlikely(r != 0)) { diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 3481bc7f6f5..d143702b244 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -137,9 +137,10 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, } extern int radeon_bo_create(struct radeon_device *rdev, - struct drm_gem_object *gobj, unsigned long size, - bool kernel, u32 domain, - struct radeon_bo **bo_ptr); + struct drm_gem_object *gobj, unsigned long size, + int byte_align, + bool kernel, u32 domain, + struct radeon_bo **bo_ptr); extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); extern void radeon_bo_kunmap(struct radeon_bo *bo); extern void radeon_bo_unref(struct radeon_bo **bo); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 6ea798ce821..06e79822a2b 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -176,8 +176,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev) INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); /* Allocate 1M object buffer */ r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, - true, RADEON_GEM_DOMAIN_GTT, - &rdev->ib_pool.robj); + PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, + &rdev->ib_pool.robj); if (r) { DRM_ERROR("radeon: failed to ib pool (%d).\n", r); return r; @@ -332,7 +332,7 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) rdev->cp.ring_size = ring_size; /* Allocate ring buffer */ if (rdev->cp.ring_obj == NULL) { - r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true, + r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, &rdev->cp.ring_obj); if (r) { diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 313c96bc09d..5b44f652145 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -52,7 +52,7 @@ void radeon_test_moves(struct radeon_device *rdev) goto out_cleanup; } - r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM, + r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, &vram_obj); if (r) { DRM_ERROR("Failed to create VRAM object\n"); @@ -71,7 +71,7 @@ void radeon_test_moves(struct radeon_device *rdev) void **gtt_start, **gtt_end; void **vram_start, **vram_end; - r = radeon_bo_create(rdev, NULL, size, true, + r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, gtt_obj + i); if (r) { DRM_ERROR("Failed to create GTT object %d\n", i); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 01c2c736a1d..1272e4b6a1d 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -529,7 +529,7 @@ int radeon_ttm_init(struct radeon_device *rdev) DRM_ERROR("Failed initializing VRAM heap.\n"); return r; } - r = radeon_bo_create(rdev, NULL, 256 * 1024, true, + r = radeon_bo_create(rdev, NULL, 256 * 1024, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, &rdev->stollen_vga_memory); if (r) { diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 245374e2b77..4dfead8cee3 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -915,8 +915,8 @@ static int rv770_vram_scratch_init(struct radeon_device *rdev) if (rdev->vram_scratch.robj == NULL) { r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, - true, RADEON_GEM_DOMAIN_VRAM, - &rdev->vram_scratch.robj); + PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, + &rdev->vram_scratch.robj); if (r) { return r; } -- cgit v1.2.3-70-g09d2 From 1aa52bd3bc839064d5a3e4de406850f4a3aa5378 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 17 Nov 2010 12:11:03 -0500 Subject: drm/radeon/kms: fix tiling info on evergreen We aren't currently using tiling in userspace on evergreen, but the info we currently return for the tiling info query (gb_addr_config) is no adequate for userspace tiling alignment calculations. It does not contain the bank info. Create a custom tiling info dword with all the necessary info (num channels, num banks, group size, row size). Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 488c36c8f5e..4dc5b4714c5 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1650,7 +1650,36 @@ static void evergreen_gpu_init(struct radeon_device *rdev) } } - rdev->config.evergreen.tile_config = gb_addr_config; + /* setup tiling info dword. gb_addr_config is not adequate since it does + * not have bank info, so create a custom tiling dword. + * bits 3:0 num_pipes + * bits 7:4 num_banks + * bits 11:8 group_size + * bits 15:12 row_size + */ + rdev->config.evergreen.tile_config = 0; + switch (rdev->config.evergreen.max_tile_pipes) { + case 1: + default: + rdev->config.evergreen.tile_config |= (0 << 0); + break; + case 2: + rdev->config.evergreen.tile_config |= (1 << 0); + break; + case 4: + rdev->config.evergreen.tile_config |= (2 << 0); + break; + case 8: + rdev->config.evergreen.tile_config |= (3 << 0); + break; + } + rdev->config.evergreen.tile_config |= + ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + rdev->config.evergreen.tile_config |= + ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; + rdev->config.evergreen.tile_config |= + ((gb_addr_config & 0x30000000) >> 28) << 12; + WREG32(GB_BACKEND_MAP, gb_backend_map); WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); -- cgit v1.2.3-70-g09d2 From 95ccb0f3bdc4438bf470c25450e6a8a6090ca253 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 11 Nov 2010 10:04:53 +0100 Subject: drm/ttm: Fix up a theoretical deadlock A process suspended waiting for a higher sequence or no sequence to unreserve, a bo may be beaten to the reservation by a process with a lower sequence. In that case the first process should give up trying to reserve and return -EAGAIN. In order for that to happen, we must wake waiting processes when we change sequence, so that they have a chance to detect the new sequence. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3ca77dc0391..148a322d8f5 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, int ret; while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { + /** + * Deadlock avoidance for multi-bo reserving. + */ if (use_sequence && bo->seq_valid && (sequence - bo->val_seq < (1 << 31))) { return -EAGAIN; @@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, } if (use_sequence) { + /** + * Wake up waiters that may need to recheck for deadlock, + * if we decreased the sequence number. + */ + if (unlikely((bo->val_seq - sequence < (1 << 31)) + || !bo->seq_valid)) + wake_up_all(&bo->event_queue); + bo->val_seq = sequence; bo->seq_valid = true; } else { -- cgit v1.2.3-70-g09d2 From de391d12500ede13faa7ecadbe900a8de1f76cfa Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Thu, 18 Nov 2010 09:06:43 -0800 Subject: Input: fix typo in keycode validation supporting large scancodes Check the input_keymap_entry keycode size (u32) instead of the device's (void*) when validating that keycode value can be stored in the keymap. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=22722 Signed-off-by: Mattia Dongili Tested-by: Norbert Preining Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index 7f26ca6ecf7..5edc41aa08f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -753,7 +753,7 @@ static int input_default_setkeycode(struct input_dev *dev, if (index >= dev->keycodemax) return -EINVAL; - if (dev->keycodesize < sizeof(dev->keycode) && + if (dev->keycodesize < sizeof(ke->keycode) && (ke->keycode >> (dev->keycodesize * 8))) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 3006bc38895895f1a0352c2e17e1a503f35f7e2f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Nov 2010 09:30:42 -0800 Subject: bonding: fix a race in IGMP handling RCU conversion in IGMP code done in net-next-2.6 raised a race in __bond_resend_igmp_join_requests(). It iterates in_dev->mc_list without appropriate protection (RTNL, or read_lock on in_dev->mc_list_lock). Another cpu might delete an entry while we use it and trigger a fault. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bdb68a60038..71a169740d0 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -878,8 +878,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev) rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); if (in_dev) { + read_lock(&in_dev->mc_list_lock); for (im = in_dev->mc_list; im; im = im->next) ip_mc_rejoin_group(im); + read_unlock(&in_dev->mc_list_lock); } rcu_read_unlock(); -- cgit v1.2.3-70-g09d2 From 3bf30b56c4f0a1c4fae34050b7db4527c92891e8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 18 Nov 2010 12:19:52 +0530 Subject: ath9k_htc: Avoid setting QoS control for non-QoS frames Setting tid information in the TX header is required only for QoS frames. Not handling this case causes severe data loss with some APs. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 3d19b5bc937..29d80ca7839 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -121,7 +121,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) tx_hdr.data_type = ATH9K_HTC_NORMAL; } - if (ieee80211_is_data(fc)) { + if (ieee80211_is_data_qos(fc)) { qc = ieee80211_get_qos_ctl(hdr); tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; } -- cgit v1.2.3-70-g09d2 From 8ea91226eccf6c8ab9c55054b24c21021d4d9d19 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Thu, 18 Nov 2010 10:35:58 -0800 Subject: net: caif: spi: fix potential NULL dereference alloc_netdev() is not checked here for NULL return value. dev is check instead. It might lead to NULL dereference of ndev. Signed-off-by: Vasiliy Kulikov Signed-off-by: David S. Miller --- drivers/net/caif/caif_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 8b4cea57a6c..20da1996d35 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -635,8 +635,8 @@ int cfspi_spi_probe(struct platform_device *pdev) ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", cfspi_setup); - if (!dev) - return -ENODEV; + if (!ndev) + return -ENOMEM; cfspi = netdev_priv(ndev); netif_stop_queue(ndev); -- cgit v1.2.3-70-g09d2 From 1aa46ec91cfd3cc4ab19780f664a3d089bb67173 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sat, 13 Nov 2010 13:42:08 +0000 Subject: ipg.c: remove id [SUNDANCE, 0x1021] ipg.c: The id [SUNDANCE, 0x1021] (=[0x13f0, 0x1021]) is defined at dl2k.h and ipg.c. But this device works better with dl2k driver. This problem is similar with the commit [25cca5352712561fba97bd37c495593d641c1d39 ipg: Remove device claimed by dl2k from pci id table] at 11 Feb 2010. Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller --- drivers/net/ipg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index dc019809234..aa93655c3aa 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -88,16 +88,14 @@ static const char *ipg_brand_name[] = { "IC PLUS IP1000 1000/100/10 based NIC", "Sundance Technology ST2021 based NIC", "Tamarack Microelectronics TC9020/9021 based NIC", - "Tamarack Microelectronics TC9020/9021 based NIC", "D-Link NIC IP1000A" }; static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = { { PCI_VDEVICE(SUNDANCE, 0x1023), 0 }, { PCI_VDEVICE(SUNDANCE, 0x2021), 1 }, - { PCI_VDEVICE(SUNDANCE, 0x1021), 2 }, - { PCI_VDEVICE(DLINK, 0x9021), 3 }, - { PCI_VDEVICE(DLINK, 0x4020), 4 }, + { PCI_VDEVICE(DLINK, 0x9021), 2 }, + { PCI_VDEVICE(DLINK, 0x4020), 3 }, { 0, } }; -- cgit v1.2.3-70-g09d2 From d530db0db90378b5674cb78d9c0cfcc83f851a5e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 16 Nov 2010 05:27:51 +0000 Subject: 3c59x: fix build failure on !CONFIG_PCI VORTEX_PCI() could return NULL so it needs to be casted before accessing any member of struct pci_dev. This fixes following build failure. Likewise VORTEX_EISA() was changed also. CC [M] drivers/net/3c59x.o drivers/net/3c59x.c: In function 'acpi_set_WOL': drivers/net/3c59x.c:3211:39: warning: dereferencing 'void *' pointer drivers/net/3c59x.c:3211:39: error: request for member 'current_state' in something not a structure or union make[3]: *** [drivers/net/3c59x.o] Error 1 make[2]: *** [drivers/net/3c59x.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- drivers/net/3c59x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index e1da258bbfb..0a92436f053 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -699,7 +699,8 @@ DEFINE_WINDOW_IO(32) #define DEVICE_PCI(dev) NULL #endif -#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL) +#define VORTEX_PCI(vp) \ + ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)) #ifdef CONFIG_EISA #define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL) @@ -707,7 +708,8 @@ DEFINE_WINDOW_IO(32) #define DEVICE_EISA(dev) NULL #endif -#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL) +#define VORTEX_EISA(vp) \ + ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)) /* The action to take with a media selection timer tick. Note that we deviate from the 3Com order by checking 10base2 before AUI. -- cgit v1.2.3-70-g09d2 From 515b4987ccd097cdf5416530b05fdf9e01afe95a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: asus_oled: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: Jakub Schmidtke Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/asus_oled/asus_oled.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 555157ff9a4..016c6f7f863 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device, #define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file -static DEVICE_ATTR(asus_oled_enabled, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO, get_enabled, set_enabled); -static DEVICE_ATTR(asus_oled_picture, S_IRUSR , NULL, set_picture); +static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture); -static DEVICE_ATTR(enabled, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, class_get_enabled, class_set_enabled); -static DEVICE_ATTR(picture, S_IRUSR, NULL, class_set_picture); +static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture); static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) -- cgit v1.2.3-70-g09d2 From 2a767fda5d0d8dcff465724dfad6ee131489b3f2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: frontier: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: David Taht Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/tranzport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index 1611a27e9b7..8894ab14f16 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev) t->value = temp; \ return count; \ } \ - static DEVICE_ATTR(value, S_IRUSR | S_IRUGO, show_##value, set_##value); + static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value); show_int(enable); show_int(offline); -- cgit v1.2.3-70-g09d2 From c9e51d9e4bee3da47623622884f4828e079a0581 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: iio: adis16220: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Acked-by: Jonathan Cameron Cc: Barry Song Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16220_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c2b20913937..1c1e98aee2d 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); #define IIO_DEV_ATTR_CAPTURE(_store) \ - IIO_DEVICE_ATTR(capture, S_IRUSR, NULL, _store, 0) + IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0) static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); -- cgit v1.2.3-70-g09d2 From 4d7bc388b44e42a1feafa35e50eef4f24d6ca59d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: samsung-laptop: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 28700b49827..ac2bf11e111 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev, } return count; } -static DEVICE_ATTR(silent, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO, get_silent_state, set_silent_state); -- cgit v1.2.3-70-g09d2 From 926c11151e3b82e4facbf2bd2bea15f0ca0ac6f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: udlfb: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: Bernie Thompson Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/udlfb/udlfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 0e0bc0b23d4..b7ac1600526 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = { __ATTR_RO(metrics_bytes_identical), __ATTR_RO(metrics_bytes_sent), __ATTR_RO(metrics_cpu_kcycles_used), - __ATTR(metrics_reset, S_IRUSR, NULL, metrics_reset_store), + __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store), }; /* -- cgit v1.2.3-70-g09d2 From a3d13107012ea614184d3c58bb7b579905d5da11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: zram: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: Nitin Gupta Cc: Pekka Enberg Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index c9b52b941d6..6b3cf00b0ff 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev, return sprintf(buf, "%llu\n", val); } -static DEVICE_ATTR(disksize, S_IRUGO | S_IRUSR, +static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR, disksize_show, disksize_store); static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); -static DEVICE_ATTR(reset, S_IRUSR, NULL, reset_store); +static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL); static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL); static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL); -- cgit v1.2.3-70-g09d2 From a3a972a053010bfd61c13cfa4ce688d4eebd9a19 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Nov 2010 11:21:04 -0800 Subject: Staging: line6: fix up my fixup for some sysfs attribute permissions They should be writable by root, not readable. Doh, stupid me with the wrong flags. Reported-by: Jonathan Cameron Cc: Markus Grabner Cc: Mariusz Kozlowski Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/control.c | 204 +++++++++++++++++++-------------------- drivers/staging/line6/midi.c | 4 +- drivers/staging/line6/pcm.c | 4 +- drivers/staging/line6/pod.c | 32 +++--- drivers/staging/line6/toneport.c | 4 +- drivers/staging/line6/variax.c | 12 +-- 6 files changed, 130 insertions(+), 130 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c index 95910ff4505..67e23b6e2d3 100644 --- a/drivers/staging/line6/control.c +++ b/drivers/staging/line6/control.c @@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2); VARIAX_PARAM_R(float, mix1); VARIAX_PARAM_R(int, pickup_wiring); -static DEVICE_ATTR(tweak, S_IRUSR | S_IRUGO, pod_get_tweak, pod_set_tweak); -static DEVICE_ATTR(wah_position, S_IRUSR | S_IRUGO, pod_get_wah_position, +static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak); +static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position, pod_set_wah_position); -static DEVICE_ATTR(compression_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain); -static DEVICE_ATTR(vol_pedal_position, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position); -static DEVICE_ATTR(compression_threshold, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold); -static DEVICE_ATTR(pan, S_IRUSR | S_IRUGO, pod_get_pan, pod_set_pan); -static DEVICE_ATTR(amp_model_setup, S_IRUSR | S_IRUGO, pod_get_amp_model_setup, +static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan); +static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup); -static DEVICE_ATTR(amp_model, S_IRUSR | S_IRUGO, pod_get_amp_model, +static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model, pod_set_amp_model); -static DEVICE_ATTR(drive, S_IRUSR | S_IRUGO, pod_get_drive, pod_set_drive); -static DEVICE_ATTR(bass, S_IRUSR | S_IRUGO, pod_get_bass, pod_set_bass); -static DEVICE_ATTR(mid, S_IRUSR | S_IRUGO, pod_get_mid, pod_set_mid); -static DEVICE_ATTR(lowmid, S_IRUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid); -static DEVICE_ATTR(treble, S_IRUSR | S_IRUGO, pod_get_treble, pod_set_treble); -static DEVICE_ATTR(highmid, S_IRUSR | S_IRUGO, pod_get_highmid, +static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive); +static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass); +static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid); +static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid); +static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble); +static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid, pod_set_highmid); -static DEVICE_ATTR(chan_vol, S_IRUSR | S_IRUGO, pod_get_chan_vol, +static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol); -static DEVICE_ATTR(reverb_mix, S_IRUSR | S_IRUGO, pod_get_reverb_mix, +static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix); -static DEVICE_ATTR(effect_setup, S_IRUSR | S_IRUGO, pod_get_effect_setup, +static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup); -static DEVICE_ATTR(band_1_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency); -static DEVICE_ATTR(presence, S_IRUSR | S_IRUGO, pod_get_presence, +static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence, pod_set_presence); -static DEVICE_ATTR2(treble__bass, treble, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass); -static DEVICE_ATTR(noise_gate_enable, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable); -static DEVICE_ATTR(gate_threshold, S_IRUSR | S_IRUGO, pod_get_gate_threshold, +static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold); -static DEVICE_ATTR(gate_decay_time, S_IRUSR | S_IRUGO, pod_get_gate_decay_time, +static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time); -static DEVICE_ATTR(stomp_enable, S_IRUSR | S_IRUGO, pod_get_stomp_enable, +static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable); -static DEVICE_ATTR(comp_enable, S_IRUSR | S_IRUGO, pod_get_comp_enable, +static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable); -static DEVICE_ATTR(stomp_time, S_IRUSR | S_IRUGO, pod_get_stomp_time, +static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time); -static DEVICE_ATTR(delay_enable, S_IRUSR | S_IRUGO, pod_get_delay_enable, +static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable); -static DEVICE_ATTR(mod_param_1, S_IRUSR | S_IRUGO, pod_get_mod_param_1, +static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1); -static DEVICE_ATTR(delay_param_1, S_IRUSR | S_IRUGO, pod_get_delay_param_1, +static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1); -static DEVICE_ATTR(delay_param_1_note_value, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value); -static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass); -static DEVICE_ATTR(delay_param_2, S_IRUSR | S_IRUGO, pod_get_delay_param_2, +static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2); -static DEVICE_ATTR(delay_volume_mix, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix); -static DEVICE_ATTR(delay_param_3, S_IRUSR | S_IRUGO, pod_get_delay_param_3, +static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3); -static DEVICE_ATTR(reverb_enable, S_IRUSR | S_IRUGO, pod_get_reverb_enable, +static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable); -static DEVICE_ATTR(reverb_type, S_IRUSR | S_IRUGO, pod_get_reverb_type, +static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type); -static DEVICE_ATTR(reverb_decay, S_IRUSR | S_IRUGO, pod_get_reverb_decay, +static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay); -static DEVICE_ATTR(reverb_tone, S_IRUSR | S_IRUGO, pod_get_reverb_tone, +static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone); -static DEVICE_ATTR(reverb_pre_delay, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); -static DEVICE_ATTR(reverb_pre_post, S_IRUSR | S_IRUGO, pod_get_reverb_pre_post, +static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post); -static DEVICE_ATTR(band_2_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency); -static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass); -static DEVICE_ATTR(wah_enable, S_IRUSR | S_IRUGO, pod_get_wah_enable, +static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable); -static DEVICE_ATTR(modulation_lo_cut, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); -static DEVICE_ATTR(delay_reverb_lo_cut, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); -static DEVICE_ATTR(volume_pedal_minimum, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); -static DEVICE_ATTR(eq_pre_post, S_IRUSR | S_IRUGO, pod_get_eq_pre_post, +static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post); -static DEVICE_ATTR(volume_pre_post, S_IRUSR | S_IRUGO, pod_get_volume_pre_post, +static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post); -static DEVICE_ATTR(di_model, S_IRUSR | S_IRUGO, pod_get_di_model, +static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model, pod_set_di_model); -static DEVICE_ATTR(di_delay, S_IRUSR | S_IRUGO, pod_get_di_delay, +static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay, pod_set_di_delay); -static DEVICE_ATTR(mod_enable, S_IRUSR | S_IRUGO, pod_get_mod_enable, +static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable); -static DEVICE_ATTR(mod_param_1_note_value, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value); -static DEVICE_ATTR(mod_param_2, S_IRUSR | S_IRUGO, pod_get_mod_param_2, +static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2); -static DEVICE_ATTR(mod_param_3, S_IRUSR | S_IRUGO, pod_get_mod_param_3, +static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3); -static DEVICE_ATTR(mod_param_4, S_IRUSR | S_IRUGO, pod_get_mod_param_4, +static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4); -static DEVICE_ATTR(mod_param_5, S_IRUSR | S_IRUGO, pod_get_mod_param_5, +static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5); -static DEVICE_ATTR(mod_volume_mix, S_IRUSR | S_IRUGO, pod_get_mod_volume_mix, +static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix); -static DEVICE_ATTR(mod_pre_post, S_IRUSR | S_IRUGO, pod_get_mod_pre_post, +static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post); -static DEVICE_ATTR(modulation_model, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model); -static DEVICE_ATTR(band_3_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency); -static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass); -static DEVICE_ATTR(mod_param_1_double_precision, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision); -static DEVICE_ATTR(delay_param_1_double_precision, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision); -static DEVICE_ATTR(eq_enable, S_IRUSR | S_IRUGO, pod_get_eq_enable, +static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable); -static DEVICE_ATTR(tap, S_IRUSR | S_IRUGO, pod_get_tap, pod_set_tap); -static DEVICE_ATTR(volume_tweak_pedal_assign, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap); +static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign); -static DEVICE_ATTR(band_5_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency); -static DEVICE_ATTR(tuner, S_IRUSR | S_IRUGO, pod_get_tuner, pod_set_tuner); -static DEVICE_ATTR(mic_selection, S_IRUSR | S_IRUGO, pod_get_mic_selection, +static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner); +static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection); -static DEVICE_ATTR(cabinet_model, S_IRUSR | S_IRUGO, pod_get_cabinet_model, +static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model); -static DEVICE_ATTR(stomp_model, S_IRUSR | S_IRUGO, pod_get_stomp_model, +static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model); -static DEVICE_ATTR(roomlevel, S_IRUSR | S_IRUGO, pod_get_roomlevel, +static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel); -static DEVICE_ATTR(band_4_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency); -static DEVICE_ATTR(band_6_frequency, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency); -static DEVICE_ATTR(stomp_param_1_note_value, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value); -static DEVICE_ATTR(stomp_param_2, S_IRUSR | S_IRUGO, pod_get_stomp_param_2, +static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2); -static DEVICE_ATTR(stomp_param_3, S_IRUSR | S_IRUGO, pod_get_stomp_param_3, +static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3); -static DEVICE_ATTR(stomp_param_4, S_IRUSR | S_IRUGO, pod_get_stomp_param_4, +static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4); -static DEVICE_ATTR(stomp_param_5, S_IRUSR | S_IRUGO, pod_get_stomp_param_5, +static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5); -static DEVICE_ATTR(stomp_param_6, S_IRUSR | S_IRUGO, pod_get_stomp_param_6, +static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6); -static DEVICE_ATTR(amp_switch_select, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select); -static DEVICE_ATTR(delay_param_4, S_IRUSR | S_IRUGO, pod_get_delay_param_4, +static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4); -static DEVICE_ATTR(delay_param_5, S_IRUSR | S_IRUGO, pod_get_delay_param_5, +static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5); -static DEVICE_ATTR(delay_pre_post, S_IRUSR | S_IRUGO, pod_get_delay_pre_post, +static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post); -static DEVICE_ATTR(delay_model, S_IRUSR | S_IRUGO, pod_get_delay_model, +static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model, pod_set_delay_model); -static DEVICE_ATTR(delay_verb_model, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model); -static DEVICE_ATTR(tempo_msb, S_IRUSR | S_IRUGO, pod_get_tempo_msb, +static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb); -static DEVICE_ATTR(tempo_lsb, S_IRUSR | S_IRUGO, pod_get_tempo_lsb, +static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb); -static DEVICE_ATTR(wah_model, S_IRUSR | S_IRUGO, pod_get_wah_model, +static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model, pod_set_wah_model); -static DEVICE_ATTR(bypass_volume, S_IRUSR | S_IRUGO, pod_get_bypass_volume, +static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume); -static DEVICE_ATTR(fx_loop_on_off, S_IRUSR | S_IRUGO, pod_get_fx_loop_on_off, +static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off); -static DEVICE_ATTR(tweak_param_select, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select); -static DEVICE_ATTR(amp1_engage, S_IRUSR | S_IRUGO, pod_get_amp1_engage, +static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage); -static DEVICE_ATTR(band_1_gain, S_IRUSR | S_IRUGO, pod_get_band_1_gain, +static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain); -static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); -static DEVICE_ATTR(band_2_gain, S_IRUSR | S_IRUGO, pod_get_band_2_gain, +static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain); -static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); -static DEVICE_ATTR(band_3_gain, S_IRUSR | S_IRUGO, pod_get_band_3_gain, +static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain); -static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass); -static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); -static DEVICE_ATTR(band_4_gain, S_IRUSR | S_IRUGO, pod_get_band_4_gain, +static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain); -static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IRUSR | S_IRUGO, +static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass); static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write); static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 5388bd7226c..ab67e889d2c 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev, return count; } -static DEVICE_ATTR(midi_mask_transmit, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); -static DEVICE_ATTR(midi_mask_receive, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); /* MIDI device destructor */ diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 9b34338178d..b9c55f9eb50 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev, return count; } -static DEVICE_ATTR(impulse_volume, S_IRUSR | S_IRUGO, pcm_get_impulse_volume, +static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume, pcm_set_impulse_volume); -static DEVICE_ATTR(impulse_period, S_IRUSR | S_IRUGO, pcm_get_impulse_period, +static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period, pcm_set_impulse_period); #endif diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index ed27ac19501..d9b30212585 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1); #undef GET_SYSTEM_PARAM /* POD special files: */ -static DEVICE_ATTR(channel, S_IRUSR | S_IRUGO, pod_get_channel, +static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel, pod_set_channel); static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write); static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write); static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write); -static DEVICE_ATTR(dump, S_IRUSR | S_IRUGO, pod_get_dump, pod_set_dump); -static DEVICE_ATTR(dump_buf, S_IRUSR | S_IRUGO, pod_get_dump_buf, +static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump); +static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf); -static DEVICE_ATTR(finish, S_IRUSR, line6_nop_read, pod_set_finish); +static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish); static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write); -static DEVICE_ATTR(midi_postprocess, S_IRUSR | S_IRUGO, +static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); -static DEVICE_ATTR(monitor_level, S_IRUSR | S_IRUGO, pod_get_monitor_level, +static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level); static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write); static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write); -static DEVICE_ATTR(retrieve_amp_setup, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_amp_setup); -static DEVICE_ATTR(retrieve_channel, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read, pod_set_retrieve_channel); -static DEVICE_ATTR(retrieve_effects_setup, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_effects_setup); -static DEVICE_ATTR(routing, S_IRUSR | S_IRUGO, pod_get_routing, +static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing, pod_set_routing); static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write); -static DEVICE_ATTR(store_amp_setup, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read, pod_set_store_amp_setup); -static DEVICE_ATTR(store_channel, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read, pod_set_store_channel); -static DEVICE_ATTR(store_effects_setup, S_IRUSR, line6_nop_read, +static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read, pod_set_store_effects_setup); -static DEVICE_ATTR(tuner_freq, S_IRUSR | S_IRUGO, pod_get_tuner_freq, +static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); -static DEVICE_ATTR(tuner_mute, S_IRUSR | S_IRUGO, pod_get_tuner_mute, +static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute); static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write); static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write); #ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); #endif /* control info callback */ diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 6bcf0366e89..879e6992bbc 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev, return count; } -static DEVICE_ATTR(led_red, S_IRUSR | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read, toneport_set_led_red); -static DEVICE_ATTR(led_green, S_IRUSR | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read, toneport_set_led_green); static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 803bc752ab8..81241cdf1be 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev, #endif /* Variax workbench special files: */ -static DEVICE_ATTR(model, S_IRUSR | S_IRUGO, variax_get_model, +static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model, variax_set_model); -static DEVICE_ATTR(volume, S_IRUSR | S_IRUGO, variax_get_volume, +static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume, variax_set_volume); -static DEVICE_ATTR(tone, S_IRUSR | S_IRUGO, variax_get_tone, variax_set_tone); +static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone); static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write); static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write); static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write); -static DEVICE_ATTR(active, S_IRUSR | S_IRUGO, variax_get_active, +static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active, variax_set_active); static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write); #ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw); -static DEVICE_ATTR(raw2, S_IRUSR, line6_nop_read, variax_set_raw2); +static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2); #endif /* -- cgit v1.2.3-70-g09d2 From 2811036a19624168ff9342bb85421dbbb1d2ac0d Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Thu, 18 Nov 2010 18:28:20 -0500 Subject: Fix build failure at cx25821-video driver Kernel build fail for cx25821-video has depends on smp_lock.h header file, but the dependency is removed in recent commit 451a3c24b013. Signed-off-by: Youquan Song Signed-off-by: Linus Torvalds --- drivers/staging/cx25821/cx25821.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h index acfd0176a18..c9400012578 100644 --- a/drivers/staging/cx25821/cx25821.h +++ b/drivers/staging/cx25821/cx25821.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-70-g09d2 From be66305718bee9927e6acc6b75618ce3cd745718 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Nov 2010 17:18:08 -0500 Subject: drm/radeon/kms: fix i2c pad masks on rs4xx These got lost in the last i2c cleanup. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=23222 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_combios.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 7b7ea269549..3bddea5b529 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -571,6 +571,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde } if (clk_mask && data_mask) { + /* system specific masks */ i2c.mask_clk_mask = clk_mask; i2c.mask_data_mask = data_mask; i2c.a_clk_mask = clk_mask; @@ -579,7 +580,19 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde i2c.en_data_mask = data_mask; i2c.y_clk_mask = clk_mask; i2c.y_data_mask = data_mask; + } else if ((ddc_line == RADEON_GPIOPAD_MASK) || + (ddc_line == RADEON_MDGPIO_MASK)) { + /* default gpiopad masks */ + i2c.mask_clk_mask = (0x20 << 8); + i2c.mask_data_mask = 0x80; + i2c.a_clk_mask = (0x20 << 8); + i2c.a_data_mask = 0x80; + i2c.en_clk_mask = (0x20 << 8); + i2c.en_data_mask = 0x80; + i2c.y_clk_mask = (0x20 << 8); + i2c.y_data_mask = 0x80; } else { + /* default masks for ddc pads */ i2c.mask_clk_mask = RADEON_GPIO_EN_1; i2c.mask_data_mask = RADEON_GPIO_EN_0; i2c.a_clk_mask = RADEON_GPIO_A_1; -- cgit v1.2.3-70-g09d2 From 164bcb94bc821fcbac752e809b4ac7c6f15d13b5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Nov 2010 11:37:18 -0500 Subject: drm/radeon/kms: i2c s/sprintf/snprintf/g for safety As per advice from Jean Delvare. Signed-off-by: Alex Deucher Acked-by: Jean Delvare Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_i2c.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index d263bd1a0d8..ded2a45bc95 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -896,7 +896,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, ((rdev->family <= CHIP_RS480) || ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { /* set the radeon hw i2c adapter */ - sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name); + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "Radeon i2c hw bus %s", name); i2c->adapter.algo = &radeon_i2c_algo; ret = i2c_add_adapter(&i2c->adapter); if (ret) { @@ -905,7 +906,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, } } else { /* set the radeon bit adapter */ - sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name); + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "Radeon i2c bit bus %s", name); i2c->adapter.algo_data = &i2c->algo.bit; i2c->algo.bit.pre_xfer = pre_xfer; i2c->algo.bit.post_xfer = post_xfer; @@ -946,7 +948,8 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->dev = dev; - sprintf(i2c->adapter.name, "Radeon aux bus %s", name); + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "Radeon aux bus %s", name); i2c_set_adapdata(&i2c->adapter, i2c); i2c->adapter.algo_data = &i2c->algo.dp; i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; -- cgit v1.2.3-70-g09d2 From 9045d47ea362e6a3727ee3f1b69a1b656976772e Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 18 Nov 2010 17:14:46 -0800 Subject: Revert "xen/privcmd: create address space to allow writable mmaps" This reverts commit 24a89b5be4cf2b7f1b49b56b6cb4a7b71fccf241. We should no longer need an address space now that we're correctly setting VM_PFNMAP on our vmas. Conflicts: drivers/xen/xenfs/super.c Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/super.c | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index 990ee42167a..1aa38971984 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include @@ -24,28 +22,12 @@ MODULE_DESCRIPTION("Xen filesystem"); MODULE_LICENSE("GPL"); -static int xenfs_set_page_dirty(struct page *page) -{ - return !TestSetPageDirty(page); -} - -static const struct address_space_operations xenfs_aops = { - .set_page_dirty = xenfs_set_page_dirty, -}; - -static struct backing_dev_info xenfs_backing_dev_info = { - .ra_pages = 0, /* No readahead */ - .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, -}; - static struct inode *xenfs_make_inode(struct super_block *sb, int mode) { struct inode *ret = new_inode(sb); if (ret) { ret->i_mode = mode; - ret->i_mapping->a_ops = &xenfs_aops; - ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info; ret->i_uid = ret->i_gid = 0; ret->i_blocks = 0; ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; @@ -137,25 +119,11 @@ static struct file_system_type xenfs_type = { static int __init xenfs_init(void) { - int err; - if (!xen_domain()) { - printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n"); - return 0; - } - - err = register_filesystem(&xenfs_type); - if (err) { - printk(KERN_ERR "xenfs: Unable to register filesystem!\n"); - goto out; - } - - err = bdi_init(&xenfs_backing_dev_info); - if (err) - unregister_filesystem(&xenfs_type); - - out: + if (xen_domain()) + return register_filesystem(&xenfs_type); - return err; + printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n"); + return 0; } static void __exit xenfs_exit(void) -- cgit v1.2.3-70-g09d2 From bc7fc5e33e1a093e5f9e196595843bb096471586 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 18 Nov 2010 22:32:17 -0800 Subject: xen/evtchn: the evtchn device is non-seekable Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/evtchn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index fec6ba3c08a..dd8e5e0f193 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -431,7 +431,7 @@ static int evtchn_open(struct inode *inode, struct file *filp) filp->private_data = u; - return 0; + return nonseekable_open(inode, filp);; } static int evtchn_release(struct inode *inode, struct file *filp) @@ -467,7 +467,7 @@ static const struct file_operations evtchn_fops = { .fasync = evtchn_fasync, .open = evtchn_open, .release = evtchn_release, - .llseek = noop_llseek, + .llseek = no_llseek, }; static struct miscdevice evtchn_miscdev = { -- cgit v1.2.3-70-g09d2 From f278ea849e15147269190e943937fa82e66078b1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 19 Nov 2010 16:40:35 +0900 Subject: sh: clkfwk: Build fix for non-legacy CPG changes. The disabling of the init op for non-legacy clocks neglected to do the same in the core clock framework, resulting in a build failure. Fix it up. Reported-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/sh/clk/core.c | 3 +++ drivers/sh/clk/cpg.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 87743e7d4d4..3f5e387ed56 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -418,8 +418,11 @@ int clk_register(struct clk *clk) list_add(&clk->sibling, &root_clks); list_add(&clk->node, &clock_list); + +#ifdef CONFIG_SH_CLK_CPG_LEGACY if (clk->ops && clk->ops->init) clk->ops->init(clk); +#endif out_unlock: mutex_unlock(&clock_list_sem); diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 359e9a322c7..6172335ae32 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -131,7 +131,7 @@ static int sh_clk_div6_enable(struct clk *clk) unsigned long value; int ret; - ret = sh_clk_div6_set_rate(clk, clk->rate, 0); + ret = sh_clk_div6_set_rate(clk, clk->rate); if (ret == 0) { value = __raw_readl(clk->enable_reg); value &= ~0x100; /* clear stop bit to enable clock */ -- cgit v1.2.3-70-g09d2 From b5d827b641b192ceb6968c21feb544c744e43108 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 7 Dec 2009 17:10:27 -0800 Subject: xen: make evtchn's name less generic Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index eb8a78d77d9..533a199e7a3 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -8,9 +8,12 @@ obj-$(CONFIG_BLOCK) += biomerge.o obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o obj-$(CONFIG_XEN_XENCOMM) += xencomm.o obj-$(CONFIG_XEN_BALLOON) += balloon.o -obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o +obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o obj-$(CONFIG_XENFS) += xenfs/ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o obj-$(CONFIG_XEN_DOM0) += pci.o + +xen-evtchn-y := evtchn.o + -- cgit v1.2.3-70-g09d2 From 51311d0a5c69adaec582080ad8d9b174a44dfd7a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 17 Nov 2010 09:10:42 +0000 Subject: drm/i915: Do not hold mutex when faulting in user addresses Linus Torvalds found that it was rather trivial to trigger a system freeze: In fact, with lockdep, I don't even need to do the sysrq-d thing: it shows the bug as it happens. It's the X server taking the same lock recursively. Here's the problem: ============================================= [ INFO: possible recursive locking detected ] 2.6.37-rc2-00012-gbdbd01a #7 --------------------------------------------- Xorg/2816 is trying to acquire lock: (&dev->struct_mutex){+.+.+.}, at: [] i915_gem_fault+0x50/0x17e but task is already holding lock: (&dev->struct_mutex){+.+.+.}, at: [] i915_mutex_lock_interruptible+0x28/0x4a other info that might help us debug this: 2 locks held by Xorg/2816: #0: (&dev->struct_mutex){+.+.+.}, at: [] i915_mutex_lock_interruptible+0x28/0x4a #1: (&mm->mmap_sem){++++++}, at: [] page_fault+0x156/0x37b This recursion was introduced by rearranging the locking to avoid the double locking on the fast path (4f27b5d and fbd5a26d) and the introduction of the prefault to encourage the fast paths (b5e4f2b). In order to undo the problem, we rearrange the code to perform the access validation upfront, attempt to prefault and then fight for control of the mutex. the best case scenario where the mutex is uncontended the prefaulting is not wasted. Reported-and-tested-by: Linus Torvalds Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 63 ++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 781c26c37b3..17b1cba3b5f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -547,6 +547,19 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_object *obj_priv; int ret = 0; + if (args->size == 0) + return 0; + + if (!access_ok(VERIFY_WRITE, + (char __user *)(uintptr_t)args->data_ptr, + args->size)) + return -EFAULT; + + ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr, + args->size); + if (ret) + return -EFAULT; + ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; @@ -564,23 +577,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, goto out; } - if (args->size == 0) - goto out; - - if (!access_ok(VERIFY_WRITE, - (char __user *)(uintptr_t)args->data_ptr, - args->size)) { - ret = -EFAULT; - goto out; - } - - ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr, - args->size); - if (ret) { - ret = -EFAULT; - goto out; - } - ret = i915_gem_object_get_pages_or_evict(obj); if (ret) goto out; @@ -981,7 +977,20 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_pwrite *args = data; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - int ret = 0; + int ret; + + if (args->size == 0) + return 0; + + if (!access_ok(VERIFY_READ, + (char __user *)(uintptr_t)args->data_ptr, + args->size)) + return -EFAULT; + + ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr, + args->size); + if (ret) + return -EFAULT; ret = i915_mutex_lock_interruptible(dev); if (ret) @@ -994,30 +1003,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, } obj_priv = to_intel_bo(obj); - /* Bounds check destination. */ if (args->offset > obj->size || args->size > obj->size - args->offset) { ret = -EINVAL; goto out; } - if (args->size == 0) - goto out; - - if (!access_ok(VERIFY_READ, - (char __user *)(uintptr_t)args->data_ptr, - args->size)) { - ret = -EFAULT; - goto out; - } - - ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr, - args->size); - if (ret) { - ret = -EFAULT; - goto out; - } - /* We can only do the GTT pwrite on untiled buffers, as otherwise * it would end up going through the fenced access, and we'll get * different detiling behavior between reading and writing. -- cgit v1.2.3-70-g09d2 From c9a1c4cded955176479a28556f546d3d015aee91 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 16 Nov 2010 10:58:37 +0000 Subject: drm/i915/crt: Introduce struct intel_crt We will use this structure in future patches to store CRT specific information on the encoder. Split out and tweaked from a patch by Keith Packard. Signed-off-by: Keith Packard Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_crt.c | 64 +++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index c55c7704335..e38bc676918 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -34,6 +34,16 @@ #include "i915_drm.h" #include "i915_drv.h" +struct intel_crt { + struct intel_encoder base; +}; + +static struct intel_crt *intel_attached_crt(struct drm_connector *connector) +{ + return container_of(intel_attached_encoder(connector), + struct intel_crt, base); +} + static void intel_crt_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; @@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; } -static bool intel_crt_detect_ddc(struct drm_encoder *encoder) +static bool intel_crt_detect_ddc(struct intel_crt *crt) { - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; /* CRT should always be at 0, but check anyway */ - if (intel_encoder->type != INTEL_OUTPUT_ANALOG) + if (crt->base.type != INTEL_OUTPUT_ANALOG) return false; if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { @@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) return true; } - if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) { + if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); return true; } @@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) } static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt) { - struct drm_encoder *encoder = &intel_encoder->base; + struct drm_encoder *encoder = &crt->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -434,7 +443,7 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; - struct intel_encoder *encoder = intel_attached_encoder(connector); + struct intel_crt *crt = intel_attached_crt(connector); struct drm_crtc *crtc; int dpms_mode; enum drm_connector_status status; @@ -447,24 +456,25 @@ intel_crt_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - if (intel_crt_detect_ddc(&encoder->base)) + if (intel_crt_detect_ddc(crt)) return connector_status_connected; if (!force) return connector->status; /* for pre-945g platforms use load detect */ - if (encoder->base.crtc && encoder->base.crtc->enabled) { - status = intel_crt_load_detect(encoder->base.crtc, encoder); + crtc = crt->base.base.crtc; + if (crtc && crtc->enabled) { + status = intel_crt_load_detect(crtc, crt); } else { - crtc = intel_get_load_detect_pipe(encoder, connector, + crtc = intel_get_load_detect_pipe(&crt->base, connector, NULL, &dpms_mode); if (crtc) { - if (intel_crt_detect_ddc(&encoder->base)) + if (intel_crt_detect_ddc(crt)) status = connector_status_connected; else - status = intel_crt_load_detect(crtc, encoder); - intel_release_load_detect_pipe(encoder, + status = intel_crt_load_detect(crtc, crt); + intel_release_load_detect_pipe(&crt->base, connector, dpms_mode); } else status = connector_status_unknown; @@ -536,17 +546,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; - struct intel_encoder *intel_encoder; + struct intel_crt *crt; struct intel_connector *intel_connector; struct drm_i915_private *dev_priv = dev->dev_private; - intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); - if (!intel_encoder) + crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); + if (!crt) return; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { - kfree(intel_encoder); + kfree(crt); return; } @@ -554,20 +564,20 @@ void intel_crt_init(struct drm_device *dev) drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs, + drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - intel_connector_attach_encoder(intel_connector, intel_encoder); + intel_connector_attach_encoder(intel_connector, &crt->base); - intel_encoder->type = INTEL_OUTPUT_ANALOG; - intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT) | - (1 << INTEL_SDVO_LVDS_CLONE_BIT); - intel_encoder->crtc_mask = (1 << 0) | (1 << 1); + crt->base.type = INTEL_OUTPUT_ANALOG; + crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | + 1 << INTEL_ANALOG_CLONE_BIT | + 1 << INTEL_SDVO_LVDS_CLONE_BIT); + crt->base.crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 1; connector->doublescan_allowed = 0; - drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs); + drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); -- cgit v1.2.3-70-g09d2 From e7dbb2f2f8ac843ab5e4d6a8e9a71d16089d324b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 16 Nov 2010 16:03:53 +0800 Subject: drm/i915: Take advantage of auto-polling CRT hotplug detection on PCH hardware Both IBX and CPT have an automatic hotplug detection mode which appears to work reliably enough that we can dispense with the manual force hotplug trigger stuff. This means that hotplug detection is as simple as reading the current hotplug register values. The first time the hotplug detection is activated, the code synchronously waits for a hotplug sequence in case the hardware hasn't bothered to do a detection cycle since being initialized. Signed-off-by: Keith Packard Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_crt.c | 95 ++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e38bc676918..8df57431606 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -34,8 +34,17 @@ #include "i915_drm.h" #include "i915_drv.h" +/* Here's the desired hotplug mode */ +#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ + ADPA_CRT_HOTPLUG_WARMUP_10MS | \ + ADPA_CRT_HOTPLUG_SAMPLE_4S | \ + ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ + ADPA_CRT_HOTPLUG_VOLREF_325MV | \ + ADPA_CRT_HOTPLUG_ENABLE) + struct intel_crt { struct intel_encoder base; + bool force_hotplug_required; }; static struct intel_crt *intel_attached_crt(struct drm_connector *connector) @@ -139,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); } - adpa = 0; + adpa = ADPA_HOTPLUG_BITS; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) adpa |= ADPA_HSYNC_ACTIVE_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) @@ -167,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct intel_crt *crt = intel_attached_crt(connector); struct drm_i915_private *dev_priv = dev->dev_private; - u32 adpa, temp; + u32 adpa; bool ret; - bool turn_off_dac = false; - temp = adpa = I915_READ(PCH_ADPA); + /* The first time through, trigger an explicit detection cycle */ + if (crt->force_hotplug_required) { + bool turn_off_dac = HAS_PCH_SPLIT(dev); + u32 save_adpa; - if (HAS_PCH_SPLIT(dev)) - turn_off_dac = true; - - adpa &= ~ADPA_CRT_HOTPLUG_MASK; - if (turn_off_dac) - adpa &= ~ADPA_DAC_ENABLE; - - /* disable HPD first */ - I915_WRITE(PCH_ADPA, adpa); - (void)I915_READ(PCH_ADPA); - - adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | - ADPA_CRT_HOTPLUG_WARMUP_10MS | - ADPA_CRT_HOTPLUG_SAMPLE_4S | - ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */ - ADPA_CRT_HOTPLUG_VOLREF_325MV | - ADPA_CRT_HOTPLUG_ENABLE | - ADPA_CRT_HOTPLUG_FORCE_TRIGGER); - - DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); - I915_WRITE(PCH_ADPA, adpa); - - if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) - DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); - - if (turn_off_dac) { - /* Make sure hotplug is enabled */ - I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE); - (void)I915_READ(PCH_ADPA); + crt->force_hotplug_required = 0; + + save_adpa = adpa = I915_READ(PCH_ADPA); + DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); + + adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; + if (turn_off_dac) + adpa &= ~ADPA_DAC_ENABLE; + + I915_WRITE(PCH_ADPA, adpa); + + if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, + 1000)) + DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); + + if (turn_off_dac) { + I915_WRITE(PCH_ADPA, save_adpa); + POSTING_READ(PCH_ADPA); + } } /* Check the status to see if both blue and green are on now */ adpa = I915_READ(PCH_ADPA); - adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; - if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || - (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) + if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) ret = true; else ret = false; + DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); return ret; } @@ -452,8 +452,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) if (intel_crt_detect_hotplug(connector)) { DRM_DEBUG_KMS("CRT detected via hotplug\n"); return connector_status_connected; - } else + } else { + DRM_DEBUG_KMS("CRT not detected via hotplug\n"); return connector_status_disconnected; + } } if (intel_crt_detect_ddc(crt)) @@ -587,5 +589,22 @@ void intel_crt_init(struct drm_device *dev) else connector->polled = DRM_CONNECTOR_POLL_CONNECT; + /* + * Configure the automatic hotplug detection stuff + */ + crt->force_hotplug_required = 0; + if (HAS_PCH_SPLIT(dev)) { + u32 adpa; + + adpa = I915_READ(PCH_ADPA); + adpa &= ~ADPA_CRT_HOTPLUG_MASK; + adpa |= ADPA_HOTPLUG_BITS; + I915_WRITE(PCH_ADPA, adpa); + POSTING_READ(PCH_ADPA); + + DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); + crt->force_hotplug_required = 1; + } + dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; } -- cgit v1.2.3-70-g09d2 From 16c59ef33b389217c29122235e475557bc1412a1 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Fri, 19 Nov 2010 09:33:55 +0000 Subject: drm/i915: Disable FBC on Ironlake to save 1W Frame buffer compression is broken on Ironlake due to buggy hardware. Currently it is disabled through chicken bits, but it still consumes over 1W more than if we simply never attempt to enable the FBC code paths. Signed-off-by: Alex Shi Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 80745f85902..f737960712e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -150,7 +150,8 @@ static const struct intel_device_info intel_ironlake_d_info = { static const struct intel_device_info intel_ironlake_m_info = { .gen = 5, .is_mobile = 1, - .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, + .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1, + .has_fbc = 0, /* disabled due to buggy hardware */ .has_bsd_ring = 1, }; -- cgit v1.2.3-70-g09d2 From 1b1d76e2df2a0aa965d6a227db7061d3fff029b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 18 Nov 2010 06:58:04 +0300 Subject: UBI: release locks in check_corruption Commit 45aafd32996e27 "UBI: tighten the corrupted PEB criteria" introduced some return paths that didn't release the ubi->buf_mutex Signed-off-by: Dan Carpenter Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 3c631863bf4..204345be8e6 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -787,16 +787,15 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, * erased, so it became unstable and corrupted, and should be * erased. */ - return 0; + err = 0; + goto out_unlock; } if (err) - return err; + goto out_unlock; - if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) { - mutex_unlock(&ubi->buf_mutex); - return 0; - } + if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) + goto out_unlock; ubi_err("PEB %d contains corrupted VID header, and the data does not " "contain all 0xFF, this may be a non-UBI PEB or a severe VID " @@ -806,8 +805,11 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, pnum, ubi->leb_start, ubi->leb_size); ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->peb_buf1, ubi->leb_size, 1); + err = 1; + +out_unlock: mutex_unlock(&ubi->buf_mutex); - return 1; + return err; } /** -- cgit v1.2.3-70-g09d2 From d9efd2af461abb7b54c49c1b7e654d496dd1d379 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Thu, 18 Nov 2010 23:44:45 +0000 Subject: be2net: Fix to avoid firmware update when interface is not open. Since interrupts are enabled only when open is called on the interface, Attempting a firmware update operation when interface is down could lead to partial success or failure of operation. This fix fails the request if netif_running is false. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index c36cd2ffbad..93354eee2cf 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2458,6 +2458,12 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) int status, i = 0, num_imgs = 0; const u8 *p; + if (!netif_running(adapter->netdev)) { + dev_err(&adapter->pdev->dev, + "Firmware load not allowed (interface is down)\n"); + return -EPERM; + } + strcpy(fw_file, func); status = request_firmware(&fw, fw_file, &adapter->pdev->dev); -- cgit v1.2.3-70-g09d2 From 412dc7f368bf10a8049a8a4c41abbfd0108742e7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 19 Nov 2010 09:30:18 -0800 Subject: staging: fix winbond build, needs delay.h winbond drivers use msleep() and delay(), so include linux/delay.h in a common header file to prevent build errors. drivers/staging/winbond/phy_calibration.c:987: error: implicit declaration of function 'msleep' drivers/staging/winbond/phy_calibration.c:1556: error: implicit declaration of function 'udelay' drivers/staging/winbond/reg.c:894: error: implicit declaration of function 'msleep' drivers/staging/winbond/reg.c:1178: error: implicit declaration of function 'udelay' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/sysdef.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index 9195adf98e1..d0d71f69bc8 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -2,6 +2,9 @@ #ifndef SYS_DEF_H #define SYS_DEF_H + +#include + #define WB_LINUX #define WB_LINUX_WPA_PSK -- cgit v1.2.3-70-g09d2 From b1353e4f40f6179ab26a3bb1b2e1fe29ffe534f5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 19 Nov 2010 15:29:19 +0100 Subject: sata_via: apply magic FIFO fix to vt6420 too vt6420 has the same FIFO overflow problem as vt6421 when combined with certain devices. This patch applies the magic fix to vt6420 too. Signed-off-by: Tejun Heo Reported-by: Martin Qvist Reported-by: Peter Zijlstra Cc: Joseph Chan Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index c21589986c6..8b677bbf2d3 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -538,7 +538,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) return 0; } -static void svia_configure(struct pci_dev *pdev) +static void svia_configure(struct pci_dev *pdev, int board_id) { u8 tmp8; @@ -577,7 +577,7 @@ static void svia_configure(struct pci_dev *pdev) } /* - * vt6421 has problems talking to some drives. The following + * vt6420/1 has problems talking to some drives. The following * is the fix from Joseph Chan . * * When host issues HOLD, device may send up to 20DW of data @@ -596,8 +596,9 @@ static void svia_configure(struct pci_dev *pdev) * * https://bugzilla.kernel.org/show_bug.cgi?id=15173 * http://article.gmane.org/gmane.linux.ide/46352 + * http://thread.gmane.org/gmane.linux.kernel/1062139 */ - if (pdev->device == 0x3249) { + if (board_id == vt6420 || board_id == vt6421) { pci_read_config_byte(pdev, 0x52, &tmp8); tmp8 |= 1 << 2; pci_write_config_byte(pdev, 0x52, tmp8); @@ -652,7 +653,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - svia_configure(pdev); + svia_configure(pdev, board_id); pci_set_master(pdev); return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, -- cgit v1.2.3-70-g09d2 From 4d0812c37f2f6cf6fc7ca086b5a5e572cbbe7f6d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Sun, 14 Nov 2010 12:40:33 +0200 Subject: mmc: sdio: fix nasty oops in mmc_sdio_detect Power off the card in mmc_sdio_detect __before__ a potential error handler, which completely removes the card, executes, and only if the card was successfully powered on beforehand. While we're at it, use the _sync variant of the runtime PM put API, in order to ensure that the card is left powered off in case an error occurred, and the card is going to be removed. Reproduced and tested on the OLPC XO-1.5. Reported-by: Daniel Drake Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c3ad1058cd3..42a949b723b 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -560,6 +560,19 @@ static void mmc_sdio_detect(struct mmc_host *host) mmc_release_host(host); + /* + * Tell PM core it's OK to power off the card now. + * + * The _sync variant is used in order to ensure that the card + * is left powered off in case an error occurred, and the card + * is going to be removed. + * + * Since there is no specific reason to believe a new user + * is about to show up at this point, the _sync variant is + * desirable anyway. + */ + pm_runtime_put_sync(&host->card->dev); + out: if (err) { mmc_sdio_remove(host); @@ -568,9 +581,6 @@ out: mmc_detach_bus(host); mmc_release_host(host); } - - /* Tell PM core that we're done */ - pm_runtime_put(&host->card->dev); } /* -- cgit v1.2.3-70-g09d2 From ed919b0125b26dcc052e44836f66e7e1f5c49c7e Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 19 Nov 2010 09:29:09 +0200 Subject: mmc: sdio: fix runtime PM anomalies by introducing MMC_CAP_POWER_OFF_CARD Some board/card/host configurations are not capable of powering off the card after boot. To support such configurations, and to allow smoother transition to runtime PM behavior, MMC_CAP_POWER_OFF_CARD is added, so hosts need to explicitly indicate whether it's OK to power off their cards after boot. SDIO core will enable runtime PM for a card only if that cap is set. As a result, the card will be powered down after boot, and will only be powered up again when a driver is loaded (and then it's up to the driver to decide whether power will be kept or not). This will prevent sdio_bus_probe() failures with setups that do not support powering off the card. Reported-and-tested-by: Daniel Drake Reported-and-tested-by: Arnd Hannemann Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 37 +++++++++++++++++++++++-------------- drivers/mmc/core/sdio_bus.c | 33 ++++++++++++++++++++++----------- include/linux/mmc/host.h | 1 + 3 files changed, 46 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 42a949b723b..efef5f94ac4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host) BUG_ON(!host->card); /* Make sure card is powered before detecting it */ - err = pm_runtime_get_sync(&host->card->dev); - if (err < 0) - goto out; + if (host->caps & MMC_CAP_POWER_OFF_CARD) { + err = pm_runtime_get_sync(&host->card->dev); + if (err < 0) + goto out; + } mmc_claim_host(host); @@ -571,7 +573,8 @@ static void mmc_sdio_detect(struct mmc_host *host) * is about to show up at this point, the _sync variant is * desirable anyway. */ - pm_runtime_put_sync(&host->card->dev); + if (host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_put_sync(&host->card->dev); out: if (err) { @@ -728,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) card = host->card; /* - * Let runtime PM core know our card is active + * Enable runtime PM only if supported by host+card+board */ - err = pm_runtime_set_active(&card->dev); - if (err) - goto remove; + if (host->caps & MMC_CAP_POWER_OFF_CARD) { + /* + * Let runtime PM core know our card is active + */ + err = pm_runtime_set_active(&card->dev); + if (err) + goto remove; - /* - * Enable runtime PM for this card - */ - pm_runtime_enable(&card->dev); + /* + * Enable runtime PM for this card + */ + pm_runtime_enable(&card->dev); + } /* * The number of functions on the card is encoded inside @@ -755,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) goto remove; /* - * Enable Runtime PM for this func + * Enable Runtime PM for this func (if supported) */ - pm_runtime_enable(&card->sdio_func[i]->dev); + if (host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_enable(&card->sdio_func[i]->dev); } mmc_release_host(host); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 2716c7ab6bb..203da443e33 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "sdio_cis.h" @@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev) * it should call pm_runtime_put_noidle() in its probe routine and * pm_runtime_get_noresume() in its remove routine. */ - ret = pm_runtime_get_sync(dev); - if (ret < 0) - goto out; + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { + ret = pm_runtime_get_sync(dev); + if (ret < 0) + goto out; + } /* Set the default block size so the driver is sure it's something * sensible. */ @@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev) return 0; disable_runtimepm: - pm_runtime_put_noidle(dev); + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_put_noidle(dev); out: return ret; } @@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev) { struct sdio_driver *drv = to_sdio_driver(dev->driver); struct sdio_func *func = dev_to_sdio_func(dev); - int ret; + int ret = 0; /* Make sure card is powered before invoking ->remove() */ - ret = pm_runtime_get_sync(dev); - if (ret < 0) - goto out; + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { + ret = pm_runtime_get_sync(dev); + if (ret < 0) + goto out; + } drv->remove(func); @@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev) } /* First, undo the increment made directly above */ - pm_runtime_put_noidle(dev); + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_put_noidle(dev); /* Then undo the runtime PM settings in sdio_bus_probe() */ - pm_runtime_put_noidle(dev); + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_put_noidle(dev); out: return ret; @@ -191,6 +199,8 @@ out: static int sdio_bus_pm_prepare(struct device *dev) { + struct sdio_func *func = dev_to_sdio_func(dev); + /* * Resume an SDIO device which was suspended at run time at this * point, in order to allow standard SDIO suspend/resume paths @@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev) * since there is little point in failing system suspend if a * device can't be resumed. */ - pm_runtime_resume(dev); + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_resume(dev); return 0; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6d87f68ce4b..30f6fad99a5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -168,6 +168,7 @@ struct mmc_host { /* DDR mode at 1.8V */ #define MMC_CAP_1_2V_DDR (1 << 12) /* can support */ /* DDR mode at 1.2V */ +#define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3-70-g09d2 From 7a3783efffc7bc2e702d774e47fad5b8e37e9ad1 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Wed, 17 Nov 2010 16:26:50 -0800 Subject: xhci: Fix reset-device and configure-endpoint commands We have been having problems with the USB-IF Gold Tree tests when plugging and unplugging devices from the tree. I have seen that the reset-device and configure-endpoint commands, which are invoked from xhci_discover_or_reset_device() and xhci_configure_endpoint(), will sometimes time out. After much debugging, I determined that the commands themselves do not actually time out, but rather their completion events do not get delivered to the right place. This happens when the command ring has just wrapped around, and it's enqueue pointer is left pointing to the link TRB. xhci_discover_or_reset_device() and xhci_configure_endpoint() use the enqueue pointer directly as their command TRB pointer, without checking whether it's pointing to the link TRB. When the completion event arrives, if the command TRB is pointing to the link TRB, the check against the command ring dequeue pointer in handle_cmd_in_cmd_wait_list() fails, so the completion inside the command does not get signaled. The patch below fixes the timeout problem for me. This should be queued for the 2.6.35 and 2.6.36 stable trees. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 06fca0835b5..45e4a3108cc 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1549,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, cmd_completion = command->completion; cmd_status = &command->status; command->command_trb = xhci->cmd_ring->enqueue; + + /* Enqueue pointer can be left pointing to the link TRB, + * we must handle that + */ + if ((command->command_trb->link.control & TRB_TYPE_BITMASK) + == TRB_TYPE(TRB_LINK)) + command->command_trb = + xhci->cmd_ring->enq_seg->next->trbs; + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); } else { in_ctx = virt_dev->in_ctx; @@ -2272,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) /* Attempt to submit the Reset Device command to the command ring */ spin_lock_irqsave(&xhci->lock, flags); reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; + + /* Enqueue pointer can be left pointing to the link TRB, + * we must handle that + */ + if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK) + == TRB_TYPE(TRB_LINK)) + reset_device_cmd->command_trb = + xhci->cmd_ring->enq_seg->next->trbs; + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); ret = xhci_queue_reset_device(xhci, slot_id); if (ret) { -- cgit v1.2.3-70-g09d2 From da6699ce4a889c3795624ccdcfe7181cc89f18e8 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 26 Oct 2010 16:47:13 -0700 Subject: xhci: Setup array of USB 2.0 and USB 3.0 ports. An xHCI host controller contains USB 2.0 and USB 3.0 ports, which can occur in any order in the PORTSC registers. We cannot read the port speed bits in the PORTSC registers at init time to determine the port speed, since those bits are only valid when a USB device is plugged into the port. Instead, we read the "Supported Protocol Capability" registers in the xHC Extended Capabilities space. Those describe the protocol, port offset in the PORTSC registers, and port count. We use those registers to create two arrays of pointers to the PORTSC registers, one for USB 3.0 ports, and another for USB 2.0 ports. A third array keeps track of the port protocol major revision, and is indexed with the internal xHCI port number. This commit is a bit big, but it should be queued for stable because the "Don't let the USB core disable SuperSpeed ports" patch depends on it. There is no other way to determine which ports are SuperSpeed ports without this patch. Signed-off-by: Sarah Sharp Tested-by: Don Zickus Cc: stable@kernel.org --- drivers/usb/host/xhci-mem.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 26 +++++++ 2 files changed, 190 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d178761c398..0fae58ef8af 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->dcbaa = NULL; scratchpad_free(xhci); + + xhci->num_usb2_ports = 0; + xhci->num_usb3_ports = 0; + kfree(xhci->usb2_ports); + kfree(xhci->usb3_ports); + kfree(xhci->port_array); + xhci->page_size = 0; xhci->page_shift = 0; xhci->bus_suspended = 0; @@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) &xhci->ir_set->erst_dequeue); } +static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, + u32 __iomem *addr, u8 major_revision) +{ + u32 temp, port_offset, port_count; + int i; + + if (major_revision > 0x03) { + xhci_warn(xhci, "Ignoring unknown port speed, " + "Ext Cap %p, revision = 0x%x\n", + addr, major_revision); + /* Ignoring port protocol we can't understand. FIXME */ + return; + } + + /* Port offset and count in the third dword, see section 7.2 */ + temp = xhci_readl(xhci, addr + 2); + port_offset = XHCI_EXT_PORT_OFF(temp); + port_count = XHCI_EXT_PORT_COUNT(temp); + xhci_dbg(xhci, "Ext Cap %p, port offset = %u, " + "count = %u, revision = 0x%x\n", + addr, port_offset, port_count, major_revision); + /* Port count includes the current port offset */ + if (port_offset == 0 || (port_offset + port_count - 1) > num_ports) + /* WTF? "Valid values are ‘1’ to MaxPorts" */ + return; + port_offset--; + for (i = port_offset; i < (port_offset + port_count); i++) { + /* Duplicate entry. Ignore the port if the revisions differ. */ + if (xhci->port_array[i] != 0) { + xhci_warn(xhci, "Duplicate port entry, Ext Cap %p," + " port %u\n", addr, i); + xhci_warn(xhci, "Port was marked as USB %u, " + "duplicated as USB %u\n", + xhci->port_array[i], major_revision); + /* Only adjust the roothub port counts if we haven't + * found a similar duplicate. + */ + if (xhci->port_array[i] != major_revision && + xhci->port_array[i] != (u8) -1) { + if (xhci->port_array[i] == 0x03) + xhci->num_usb3_ports--; + else + xhci->num_usb2_ports--; + xhci->port_array[i] = (u8) -1; + } + /* FIXME: Should we disable the port? */ + } + xhci->port_array[i] = major_revision; + if (major_revision == 0x03) + xhci->num_usb3_ports++; + else + xhci->num_usb2_ports++; + } + /* FIXME: Should we disable ports not in the Extended Capabilities? */ +} + +/* + * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that + * specify what speeds each port is supposed to be. We can't count on the port + * speed bits in the PORTSC register being correct until a device is connected, + * but we need to set up the two fake roothubs with the correct number of USB + * 3.0 and USB 2.0 ports at host controller initialization time. + */ +static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) +{ + u32 __iomem *addr; + u32 offset; + unsigned int num_ports; + int i, port_index; + + addr = &xhci->cap_regs->hcc_params; + offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); + if (offset == 0) { + xhci_err(xhci, "No Extended Capability registers, " + "unable to set up roothub.\n"); + return -ENODEV; + } + + num_ports = HCS_MAX_PORTS(xhci->hcs_params1); + xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags); + if (!xhci->port_array) + return -ENOMEM; + + /* + * For whatever reason, the first capability offset is from the + * capability register base, not from the HCCPARAMS register. + * See section 5.3.6 for offset calculation. + */ + addr = &xhci->cap_regs->hc_capbase + offset; + while (1) { + u32 cap_id; + + cap_id = xhci_readl(xhci, addr); + if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) + xhci_add_in_port(xhci, num_ports, addr, + (u8) XHCI_EXT_PORT_MAJOR(cap_id)); + offset = XHCI_EXT_CAPS_NEXT(cap_id); + if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports) + == num_ports) + break; + /* + * Once you're into the Extended Capabilities, the offset is + * always relative to the register holding the offset. + */ + addr += offset; + } + + if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) { + xhci_warn(xhci, "No ports on the roothubs?\n"); + return -ENODEV; + } + xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n", + xhci->num_usb2_ports, xhci->num_usb3_ports); + /* + * Note we could have all USB 3.0 ports, or all USB 2.0 ports. + * Not sure how the USB core will handle a hub with no ports... + */ + if (xhci->num_usb2_ports) { + xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)* + xhci->num_usb2_ports, flags); + if (!xhci->usb2_ports) + return -ENOMEM; + + port_index = 0; + for (i = 0; i < num_ports; i++) + if (xhci->port_array[i] != 0x03) { + xhci->usb2_ports[port_index] = + &xhci->op_regs->port_status_base + + NUM_PORT_REGS*i; + xhci_dbg(xhci, "USB 2.0 port at index %u, " + "addr = %p\n", i, + xhci->usb2_ports[port_index]); + port_index++; + } + } + if (xhci->num_usb3_ports) { + xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* + xhci->num_usb3_ports, flags); + if (!xhci->usb3_ports) + return -ENOMEM; + + port_index = 0; + for (i = 0; i < num_ports; i++) + if (xhci->port_array[i] == 0x03) { + xhci->usb3_ports[port_index] = + &xhci->op_regs->port_status_base + + NUM_PORT_REGS*i; + xhci_dbg(xhci, "USB 3.0 port at index %u, " + "addr = %p\n", i, + xhci->usb3_ports[port_index]); + port_index++; + } + } + return 0; +} int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) { @@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) if (scratchpad_alloc(xhci, flags)) goto fail; + if (xhci_setup_port_arrays(xhci, flags)) + goto fail; return 0; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 85e65647d44..170c367112d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -453,6 +453,24 @@ struct xhci_doorbell_array { #define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16) +/** + * struct xhci_protocol_caps + * @revision: major revision, minor revision, capability ID, + * and next capability pointer. + * @name_string: Four ASCII characters to say which spec this xHC + * follows, typically "USB ". + * @port_info: Port offset, count, and protocol-defined information. + */ +struct xhci_protocol_caps { + u32 revision; + u32 name_string; + u32 port_info; +}; + +#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff) +#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff) +#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff) + /** * struct xhci_container_ctx * @type: Type of context. Used to calculated offsets to contained contexts. @@ -1240,6 +1258,14 @@ struct xhci_hcd { u32 suspended_ports[8]; /* which ports are suspended */ unsigned long resume_done[MAX_HC_PORTS]; + /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ + u8 *port_array; + /* Array of pointers to USB 3.0 PORTSC registers */ + u32 __iomem **usb3_ports; + unsigned int num_usb3_ports; + /* Array of pointers to USB 2.0 PORTSC registers */ + u32 __iomem **usb2_ports; + unsigned int num_usb2_ports; }; /* For testing purposes */ -- cgit v1.2.3-70-g09d2 From 6dd0a3a7e0793dbeae1b951f091025d8cf896cb4 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 16 Nov 2010 15:58:52 -0800 Subject: xhci: Don't let the USB core disable SuperSpeed ports. Disabling SuperSpeed ports is a Very Bad Thing (TM). It disables SuperSpeed terminations, which means that devices will never connect at SuperSpeed on that port. For USB 2.0/1.1 ports, disabling the port meant that the USB core could always get a connect status change later. That's not true with USB 3.0 ports. Do not let the USB core disable SuperSpeed ports. We can't rely on the device speed in the port status registers, since that isn't valid until there's a USB device connected to the port. Instead, we use the port speed array that's created from the Extended Capabilities registers. Signed-off-by: Sarah Sharp Tested-by: Don Zickus Cc: stable@kernel.org --- drivers/usb/host/xhci-hub.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index fef5a1f9d48..5d963e35049 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, u32 __iomem *addr, u32 port_status) { + /* Don't allow the USB core to disable SuperSpeed ports. */ + if (xhci->port_array[wIndex] == 0x03) { + xhci_dbg(xhci, "Ignoring request to disable " + "SuperSpeed port.\n"); + return; + } + /* Write 1 to disable the port */ xhci_writel(xhci, port_status | PORT_PE, addr); port_status = xhci_readl(xhci, addr); -- cgit v1.2.3-70-g09d2 From 9be4d4575906af9698de660e477f949a076c87e1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 31 Aug 2010 15:01:16 -0700 Subject: xen: add extra pages to balloon Add extra pages in the pseudo-physical address space to the balloon so we can extend into them later. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/balloon.c | 15 +++++++++++---- include/xen/page.h | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 500290b150b..df26ee9caa6 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -119,7 +119,7 @@ static void scrub_page(struct page *page) } /* balloon_append: add the given page to the balloon. */ -static void balloon_append(struct page *page) +static void __balloon_append(struct page *page) { /* Lowmem is re-populated first, so highmem pages go at list tail. */ if (PageHighMem(page)) { @@ -130,7 +130,11 @@ static void balloon_append(struct page *page) list_add(&page->lru, &ballooned_pages); balloon_stats.balloon_low++; } +} +static void balloon_append(struct page *page) +{ + __balloon_append(page); totalram_pages--; } @@ -416,10 +420,13 @@ static int __init balloon_init(void) register_balloon(&balloon_sysdev); /* Initialise the balloon with excess memory space. */ - for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { + for (pfn = PFN_UP(xen_extra_mem_start); + pfn < PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size); + pfn++) { page = pfn_to_page(pfn); - if (!PageReserved(page)) - balloon_append(page); + /* totalram_pages doesn't include the boot-time + balloon extension, so don't subtract from it. */ + __balloon_append(page); } target_watch.callback = watch_target; diff --git a/include/xen/page.h b/include/xen/page.h index eaf85fab126..0be36b976f4 100644 --- a/include/xen/page.h +++ b/include/xen/page.h @@ -1 +1,8 @@ +#ifndef _XEN_PAGE_H +#define _XEN_PAGE_H + #include + +extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size; + +#endif /* _XEN_PAGE_H */ -- cgit v1.2.3-70-g09d2 From 2f70e0acd496398671606767122846278126a88b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 2 Sep 2010 23:11:17 -0700 Subject: xen/balloon: the balloon_lock is useless The balloon_lock is useless, since it protects nothing against nothing. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/balloon.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index df26ee9caa6..77b5dc3597e 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -195,7 +195,7 @@ static unsigned long current_target(void) static int increase_reservation(unsigned long nr_pages) { - unsigned long pfn, i, flags; + unsigned long pfn, i; struct page *page; long rc; struct xen_memory_reservation reservation = { @@ -207,8 +207,6 @@ static int increase_reservation(unsigned long nr_pages) if (nr_pages > ARRAY_SIZE(frame_list)) nr_pages = ARRAY_SIZE(frame_list); - spin_lock_irqsave(&xen_reservation_lock, flags); - page = balloon_first_page(); for (i = 0; i < nr_pages; i++) { BUG_ON(page == NULL); @@ -251,14 +249,12 @@ static int increase_reservation(unsigned long nr_pages) balloon_stats.current_pages += rc; out: - spin_unlock_irqrestore(&xen_reservation_lock, flags); - return rc < 0 ? rc : rc != nr_pages; } static int decrease_reservation(unsigned long nr_pages) { - unsigned long pfn, i, flags; + unsigned long pfn, i; struct page *page; int need_sleep = 0; int ret; @@ -296,8 +292,6 @@ static int decrease_reservation(unsigned long nr_pages) kmap_flush_unused(); flush_tlb_all(); - spin_lock_irqsave(&xen_reservation_lock, flags); - /* No more mappings: invalidate P2M and add to balloon. */ for (i = 0; i < nr_pages; i++) { pfn = mfn_to_pfn(frame_list[i]); @@ -312,8 +306,6 @@ static int decrease_reservation(unsigned long nr_pages) balloon_stats.current_pages -= nr_pages; - spin_unlock_irqrestore(&xen_reservation_lock, flags); - return need_sleep; } -- cgit v1.2.3-70-g09d2 From 66946f676776a6ef333db1cf7453ecf8a66c90df Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 14 Sep 2010 10:32:32 -0700 Subject: xen/balloon: make sure we only include remaining extra ram If the user specifies mem= on the kernel command line, some or all of the extra memory E820 region may be clipped away, so make sure we don't try to add more extra memory than exists in E820. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/balloon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 77b5dc3597e..2b17ad5b4b3 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -391,7 +392,7 @@ static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { - unsigned long pfn; + unsigned long pfn, extra_pfn_end; struct page *page; if (!xen_pv_domain()) @@ -412,8 +413,10 @@ static int __init balloon_init(void) register_balloon(&balloon_sysdev); /* Initialise the balloon with excess memory space. */ + extra_pfn_end = min(e820_end_of_ram_pfn(), + (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size)); for (pfn = PFN_UP(xen_extra_mem_start); - pfn < PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size); + pfn < extra_pfn_end; pfn++) { page = pfn_to_page(pfn); /* totalram_pages doesn't include the boot-time -- cgit v1.2.3-70-g09d2 From d1d788302e8c76e5138dfa61f4a5eee4f72a748f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 21 Nov 2010 09:23:48 +0000 Subject: drm/i915: Prevent integer overflow when validating the execbuffer Commit 2549d6c2 removed the vmalloc used for temporary storage of the relocation lists used during execbuffer. However, our use of vmalloc was being protected by an integer overflow check which we do want to preserve! Reported-by: Dan Carpenter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 17b1cba3b5f..bc416459005 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3630,8 +3630,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, for (i = 0; i < count; i++) { char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; - size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry); + int length; /* limited by fault_in_pages_readable() */ + /* First check for malicious input causing overflow */ + if (exec[i].relocation_count > + INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) + return -EINVAL; + + length = exec[i].relocation_count * + sizeof(struct drm_i915_gem_relocation_entry); if (!access_ok(VERIFY_READ, ptr, length)) return -EFAULT; -- cgit v1.2.3-70-g09d2 From f3c91c1deaf8493526d8216be94c33e963f00962 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 21 Nov 2010 09:56:00 +0000 Subject: drm/i915: Only save/restore cursor regs if !KMS Under KMS, restoring the cursor is handled upon modeswitch in order to avoid enabling an undefined set of registers. At the moment, the cursor is restored before the aperture and modes are fully setup causing some invalid access during resume, such as: PGTBL_ER: 0x00040000 Invalid GTT entry during Cursor Fetch Fix this by only performing cursor register save/restore under UMS where it is done in the correct sequence. Reported-by: Arkadiusz Miskiewicz Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_suspend.c | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 454c064f8ef..42729d25da5 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -239,6 +239,16 @@ static void i915_save_modeset_reg(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) return; + /* Cursor state */ + dev_priv->saveCURACNTR = I915_READ(CURACNTR); + dev_priv->saveCURAPOS = I915_READ(CURAPOS); + dev_priv->saveCURABASE = I915_READ(CURABASE); + dev_priv->saveCURBCNTR = I915_READ(CURBCNTR); + dev_priv->saveCURBPOS = I915_READ(CURBPOS); + dev_priv->saveCURBBASE = I915_READ(CURBBASE); + if (IS_GEN2(dev)) + dev_priv->saveCURSIZE = I915_READ(CURSIZE); + if (HAS_PCH_SPLIT(dev)) { dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); @@ -529,6 +539,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev) I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); + /* Cursor state */ + I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); + I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); + I915_WRITE(CURABASE, dev_priv->saveCURABASE); + I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); + I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); + I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); + if (IS_GEN2(dev)) + I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); + return; } @@ -543,16 +563,6 @@ void i915_save_display(struct drm_device *dev) /* Don't save them in KMS mode */ i915_save_modeset_reg(dev); - /* Cursor state */ - dev_priv->saveCURACNTR = I915_READ(CURACNTR); - dev_priv->saveCURAPOS = I915_READ(CURAPOS); - dev_priv->saveCURABASE = I915_READ(CURABASE); - dev_priv->saveCURBCNTR = I915_READ(CURBCNTR); - dev_priv->saveCURBPOS = I915_READ(CURBPOS); - dev_priv->saveCURBBASE = I915_READ(CURBBASE); - if (IS_GEN2(dev)) - dev_priv->saveCURSIZE = I915_READ(CURSIZE); - /* CRT state */ if (HAS_PCH_SPLIT(dev)) { dev_priv->saveADPA = I915_READ(PCH_ADPA); @@ -657,16 +667,6 @@ void i915_restore_display(struct drm_device *dev) /* Don't restore them in KMS mode */ i915_restore_modeset_reg(dev); - /* Cursor state */ - I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); - I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); - I915_WRITE(CURABASE, dev_priv->saveCURABASE); - I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); - I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); - I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); - if (IS_GEN2(dev)) - I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); - /* CRT state */ if (HAS_PCH_SPLIT(dev)) I915_WRITE(PCH_ADPA, dev_priv->saveADPA); -- cgit v1.2.3-70-g09d2 From ab08853fab2093e5c6f5de56827a4c93dce4b055 Mon Sep 17 00:00:00 2001 From: Anupam Chanda Date: Sun, 21 Nov 2010 09:54:21 -0800 Subject: e1000: fix screaming IRQ VMWare reports that the e1000 driver has a bug when bringing down the interface, such that interrupts are not disabled in the hardware but the driver stops reporting that it consumed the interrupt. The fix is to set the driver's "down" flag later in the routine, after all the timers and such have exited, preventing the interrupt handler from being called and exiting early without handling the interrupt. CC: Anupam Chanda CC: stable kernel Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4686c3983fc..4d62f7bfa03 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -31,7 +31,7 @@ char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -#define DRV_VERSION "7.3.21-k6-NAPI" +#define DRV_VERSION "7.3.21-k8-NAPI" const char e1000_driver_version[] = DRV_VERSION; static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -485,9 +485,6 @@ void e1000_down(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u32 rctl, tctl; - /* signal that we're down so the interrupt handler does not - * reschedule our watchdog timer */ - set_bit(__E1000_DOWN, &adapter->flags); /* disable receives in the hardware */ rctl = er32(RCTL); @@ -508,6 +505,13 @@ void e1000_down(struct e1000_adapter *adapter) e1000_irq_disable(adapter); + /* + * Setting DOWN must be after irq_disable to prevent + * a screaming interrupt. Setting DOWN also prevents + * timers and tasks from rescheduling. + */ + set_bit(__E1000_DOWN, &adapter->flags); + del_timer_sync(&adapter->tx_fifo_stall_timer); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); -- cgit v1.2.3-70-g09d2 From 33ac0b84eecaf5e7ee3baa3ef8294e8d8d267cd6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 21 Nov 2010 10:06:48 -0800 Subject: atl1c: Fix hardware type check for enabling OTP CLK Commit 496c185c9495629ef1c65387cb2594578393cfe0 "atl1c: Add support for Atheros AR8152 and AR8152" added the condition: if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) for enabling OTP CLK, and the condition: if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) for disabling OTP CLK. Since the two previously defined hardware types are athr_l1c and athr_l2c, the latter condition appears to be the correct one. Change the former to match. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index 919080b2c3a..1bf67200994 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c @@ -82,7 +82,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) addr[0] = addr[1] = 0; AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); if (atl1c_check_eeprom_exist(hw)) { - if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) { + if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) { /* Enable OTP CLK */ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { otp_ctrl_data |= OTP_CTRL_CLK_EN; -- cgit v1.2.3-70-g09d2 From ddab1a3b30452bf6d2a2780dbb5fd962a85bec48 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 18 Nov 2010 14:24:02 +0000 Subject: SuperH IrDA: correct Baud rate error correction It looks to me as if the second value of rate_err_array is intended to be a decimal 625. However, with a leading 0 it becomes an octal constant, and as such evaluates to a decimal 405. Signed-off-by: Nicolas Kaiser Signed-off-by: David S. Miller --- drivers/net/irda/sh_sir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index 00b38bccd6d..52a7c86af66 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c @@ -258,7 +258,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate) /* Baud Rate Error Correction x 10000 */ u32 rate_err_array[] = { - 0000, 0625, 1250, 1875, + 0, 625, 1250, 1875, 2500, 3125, 3750, 4375, 5000, 5625, 6250, 6875, 7500, 8125, 8750, 9375, -- cgit v1.2.3-70-g09d2 From 791cfe2684a74ed7155254816ff9e89e6064277c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 21 Nov 2010 10:58:05 -0500 Subject: drm/radeon/kms: fix regression in rs4xx i2c setup typo in my last i2c rework. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=23222 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_combios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 3bddea5b529..137b8075f6e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -729,7 +729,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) clk = RBIOS8(offset + 3 + (i * 5) + 3); data = RBIOS8(offset + 3 + (i * 5) + 4); i2c = combios_setup_i2c_bus(rdev, DDC_MONID, - clk, data); + (1 << clk), (1 << data)); rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); break; } -- cgit v1.2.3-70-g09d2 From f24d86f1a49505cdea56728b853a5d0a3f8e3d11 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 19 Nov 2010 23:27:04 +0000 Subject: drm/radeon/kms: fix resume regression for some r5xx laptops I had removed this when I switched the atom indirect io methods to use the io bar rather than the mmio bar, but it appears it's still needed. Reported-by: Mark Lord Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 8e421f644a5..05efb5b9f13 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, base += 3; break; case ATOM_IIO_WRITE: + (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1)); ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); base += 3; break; -- cgit v1.2.3-70-g09d2 From 92d2711f5dc15bf956546923a5718e74853f9912 Mon Sep 17 00:00:00 2001 From: Hema Kalliguddi Date: Mon, 15 Nov 2010 04:24:01 -0600 Subject: usb: musb: unmap dma buffer when switching to PIO Buffer is mapped to dma when dma channel is allocated. If, for some reason, dma channel programming fails, musb code will fallback to PIO mode to transfer that request. In that case, we need to unmap the buffer back to CPU. MUSB RTL1.8 and above cannot handle buffers which are not 32bit aligned. That happens to every request sent by g_ether gadget driver. Since the buffer sent was unaligned, we need to fallback to PIO. Because of that, g_ether was failing due to missing buffer unmapping. With this patch and [1] g_ether works fine with all MUSB revisions. Verified with OMAP3630 board, which has MUSB RTL1.8 using g_ether and g_zero. [1] http://www.spinics.net/lists/linux-usb/msg38400.html Signed-off-by: Hema HK Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 117 ++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 36cfd060dbe..0169dcf3a6f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -92,6 +92,59 @@ /* ----------------------------------------------------------------------- */ +/* Maps the buffer to dma */ + +static inline void map_dma_buffer(struct musb_request *request, + struct musb *musb) +{ + if (request->request.dma == DMA_ADDR_INVALID) { + request->request.dma = dma_map_single( + musb->controller, + request->request.buf, + request->request.length, + request->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + request->mapped = 1; + } else { + dma_sync_single_for_device(musb->controller, + request->request.dma, + request->request.length, + request->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + request->mapped = 0; + } +} + +/* Unmap the buffer from dma and maps it back to cpu */ +static inline void unmap_dma_buffer(struct musb_request *request, + struct musb *musb) +{ + if (request->request.dma == DMA_ADDR_INVALID) { + DBG(20, "not unmapping a never mapped buffer\n"); + return; + } + if (request->mapped) { + dma_unmap_single(musb->controller, + request->request.dma, + request->request.length, + request->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + request->request.dma = DMA_ADDR_INVALID; + request->mapped = 0; + } else { + dma_sync_single_for_cpu(musb->controller, + request->request.dma, + request->request.length, + request->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + + } +} + /* * Immediately complete a request. * @@ -119,24 +172,8 @@ __acquires(ep->musb->lock) ep->busy = 1; spin_unlock(&musb->lock); - if (is_dma_capable()) { - if (req->mapped) { - dma_unmap_single(musb->controller, - req->request.dma, - req->request.length, - req->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->request.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else if (req->request.dma != DMA_ADDR_INVALID) - dma_sync_single_for_cpu(musb->controller, - req->request.dma, - req->request.length, - req->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - } + if (is_dma_capable() && ep->dma) + unmap_dma_buffer(req, musb); if (request->status == 0) DBG(5, "%s done request %p, %d/%d\n", ep->end_point.name, request, @@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req) #endif if (!use_dma) { + /* + * Unmap the dma buffer back to cpu if dma channel + * programming fails + */ + if (is_dma_capable() && musb_ep->dma) + unmap_dma_buffer(req, musb); + musb_write_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); request->actual += fifo_count; @@ -713,6 +757,20 @@ static void rxstate(struct musb *musb, struct musb_request *req) return; } #endif + /* + * Unmap the dma buffer back to cpu if dma channel + * programming fails. This buffer is mapped if the + * channel allocation is successful + */ + if (is_dma_capable() && musb_ep->dma) { + unmap_dma_buffer(req, musb); + + /* Clear DMAENAB for the + * PIO mode transfer + */ + csr &= ~MUSB_RXCSR_DMAENAB; + musb_writew(epio, MUSB_RXCSR, csr); + } musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); @@ -1150,26 +1208,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, request->epnum = musb_ep->current_epnum; request->tx = musb_ep->is_in; - if (is_dma_capable() && musb_ep->dma) { - if (request->request.dma == DMA_ADDR_INVALID) { - request->request.dma = dma_map_single( - musb->controller, - request->request.buf, - request->request.length, - request->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - request->mapped = 1; - } else { - dma_sync_single_for_device(musb->controller, - request->request.dma, - request->request.length, - request->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - request->mapped = 0; - } - } else + if (is_dma_capable() && musb_ep->dma) + map_dma_buffer(request, musb); + else request->mapped = 0; spin_lock_irqsave(&musb->lock, lockflags); -- cgit v1.2.3-70-g09d2 From e75df37165c639b06213ec88b4763c3e50a7f079 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 16 Nov 2010 23:37:37 +0800 Subject: usb: musb: clear RXCSR_AUTOCLEAR before PIO read If RXCSR_AUTOCLEAR flag is not cleard before PIO reading, one packet may be recieved by musb fifo, but no chance to notify software, so cause packet loss, follows the detailed process: - PIO read one packet - musb fifo auto clear the MUSB_RXCSR_RXPKTRDY - musb continue to recieve the next packet, and MUSB_RXCSR_RXPKTRDY is set - software clear the MUSB_RXCSR_RXPKTRDY, so there is no chance for musb to notify software that the 2nd recieved packet. The patch does fix the g_ether issue below: - use fifo_mode 3 to enable double buffer - 'ping -s 1024 IP_OF_BEAGLE_XM' - one usb packet of 512 byte is lost, so ping failed, which can be observed by wireshark note: Beagle xm takes musb rtl1.8 and may fallback to pio mode for unaligned buffer. Signed-off-by: Ming Lei Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 0169dcf3a6f..363cfad003f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -765,10 +765,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) if (is_dma_capable() && musb_ep->dma) { unmap_dma_buffer(req, musb); - /* Clear DMAENAB for the + /* + * Clear DMAENAB and AUTOCLEAR for the * PIO mode transfer */ - csr &= ~MUSB_RXCSR_DMAENAB; + csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR); musb_writew(epio, MUSB_RXCSR, csr); } -- cgit v1.2.3-70-g09d2 From bb324b08165d5656d221af013ed9994a54e455be Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Mon, 22 Nov 2010 14:22:41 +0530 Subject: usb: musb: gadget: fix compilation warning Fixes below compilation warning when musb driver is compiled for PIO mode: drivers/usb/musb/musb_gadget.c: In function 'musb_g_rx': drivers/usb/musb/musb_gadget.c:840: warning: label 'exit' defined but not used Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 363cfad003f..c8de0e123f2 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -896,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!request) return; } +#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) exit: +#endif /* Analyze request */ rxstate(musb, to_musb_request(request)); } -- cgit v1.2.3-70-g09d2 From 07a8cdd2bb17a4da68136d963b8bc71959bd31a5 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Thu, 18 Nov 2010 18:54:17 +0530 Subject: usb: musb: do not use dma for control transfers The Inventra DMA engine used with the MUSB controller in many SoCs cannot use DMA for control transfers on EP0, but can use DMA for all other transfers. The USB core maps urbs for DMA if hcd->self.uses_dma is true. (hcd->self.uses_dma is true for MUSB as well). Split the uses_dma flag into two - one that says if the controller needs to use PIO for control transfers, and another which says if the controller uses DMA (for all other transfers). Also, populate this flag for all MUSB by default. (Tested on OMAP3 and OMAP4 boards, with EHCI and MUSB HCDs simultaneously in use). Signed-off-by: Maulik Mankad Signed-off-by: Santosh Shilimkar Signed-off-by: Anand Gadiyar Cc: Oliver Neukum Cc: Alan Stern Cc: Praveena NADAHALLY Cc: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/core/hcd.c | 2 ++ drivers/usb/musb/musb_core.c | 3 +++ drivers/usb/musb/musb_gadget.c | 4 ++++ include/linux/usb.h | 4 ++++ 4 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 61800f77dac..ced846ac414 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, */ if (usb_endpoint_xfer_control(&urb->ep->desc)) { + if (hcd->self.uses_pio_for_control) + return ret; if (hcd->self.uses_dma) { urb->setup_dma = dma_map_single( hcd->self.controller, diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e6669fc3b80..99beebce855 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2116,12 +2116,15 @@ bad_config: * Otherwise, wait till the gadget driver hooks up. */ if (!is_otg_enabled(musb) && is_host_enabled(musb)) { + struct usb_hcd *hcd = musb_to_hcd(musb); + MUSB_HST_MODE(musb); musb->xceiv->default_a = 1; musb->xceiv->state = OTG_STATE_A_IDLE; status = usb_add_hcd(musb_to_hcd(musb), -1, 0); + hcd->self.uses_pio_for_control = 1; DBG(1, "%s mode, status %d, devctl %02x %c\n", "HOST", status, musb_readb(musb->mregs, MUSB_DEVCTL), diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c8de0e123f2..9d6ade82b9f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1833,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&musb->lock, flags); if (is_otg_enabled(musb)) { + struct usb_hcd *hcd = musb_to_hcd(musb); + DBG(3, "OTG startup...\n"); /* REVISIT: funcall to other code, which also @@ -1847,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, musb->gadget_driver = NULL; musb->g.dev.driver = NULL; spin_unlock_irqrestore(&musb->lock, flags); + } else { + hcd->self.uses_pio_for_control = 1; } } } diff --git a/include/linux/usb.h b/include/linux/usb.h index 24300d8a1bc..a28eb259257 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -313,6 +313,10 @@ struct usb_bus { int busnum; /* Bus number (in order of reg) */ const char *bus_name; /* stable id (PCI slot_name etc) */ u8 uses_dma; /* Does the host controller use DMA? */ + u8 uses_pio_for_control; /* + * Does the host controller use PIO + * for control transfers? + */ u8 otg_port; /* 0, or number of OTG/HNP port */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ -- cgit v1.2.3-70-g09d2 From da79de97d254145dcb7c08c978b1093eac15ec9c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 22 Nov 2010 11:12:46 +0000 Subject: drm/i915/sdvo: Only enable HDMI encodings only if the commandset is supported As we conflated intel_sdvo->is_hdmi with both having HDMI support on the ADD along with having HDMI support on the monitor, we would attempt to use HDMI encodings even if the interface did not support those commands. Reported-by: Simon Farnsworth Signed-off-by: Chris Wilson Tested-by: Simon Farnsworth Reviewed-by: Simon Farnsworth --- drivers/gpu/drm/i915/intel_sdvo.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index de158b76bcd..843182528b7 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -107,7 +107,8 @@ struct intel_sdvo { * This is set if we treat the device as HDMI, instead of DVI. */ bool is_hdmi; - bool has_audio; + bool has_hdmi_monitor; + bool has_hdmi_audio; /** * This is set if we detect output of sdvo device as LVDS and @@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, if (!intel_sdvo_set_target_input(intel_sdvo)) return; - if (intel_sdvo->is_hdmi && + if (intel_sdvo->has_hdmi_monitor && !intel_sdvo_set_avi_infoframe(intel_sdvo)) return; @@ -1063,7 +1064,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, } if (intel_crtc->pipe == 1) sdvox |= SDVO_PIPE_B_SELECT; - if (intel_sdvo->has_audio) + if (intel_sdvo->has_hdmi_audio) sdvox |= SDVO_AUDIO_ENABLE; if (INTEL_INFO(dev)->gen >= 4) { @@ -1388,8 +1389,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) /* DDC bus is shared, match EDID to connector type */ if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; - intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); - intel_sdvo->has_audio = drm_detect_monitor_audio(edid); + if (intel_sdvo->is_hdmi) { + intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); + intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); + } } connector->display_info.raw_edid = NULL; kfree(edid); @@ -1398,7 +1401,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) if (status == connector_status_connected) { struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); if (intel_sdvo_connector->force_audio) - intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0; + intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0; } return status; @@ -1713,12 +1716,12 @@ intel_sdvo_set_property(struct drm_connector *connector, intel_sdvo_connector->force_audio = val; - if (val > 0 && intel_sdvo->has_audio) + if (val > 0 && intel_sdvo->has_hdmi_audio) return 0; - if (val < 0 && !intel_sdvo->has_audio) + if (val < 0 && !intel_sdvo->has_hdmi_audio) return 0; - intel_sdvo->has_audio = val > 0; + intel_sdvo->has_hdmi_audio = val > 0; goto done; } @@ -2070,6 +2073,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_set_colorimetry(intel_sdvo, SDVO_COLORIMETRY_RGB256); connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; + + intel_sdvo_add_hdmi_properties(intel_sdvo_connector); intel_sdvo->is_hdmi = true; } intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | @@ -2077,8 +2082,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); - intel_sdvo_add_hdmi_properties(intel_sdvo_connector); - return true; } -- cgit v1.2.3-70-g09d2 From dfc518dd6b5c5e00f98906eaa5c7d716d856c098 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 6 Nov 2010 18:30:25 -0300 Subject: Revert "i2c: Fix Kconfig dependencies" This reverts commit 0a57274ea026c2b7670683947b6cc08b195148cf. Signed-off-by: Arnaud Lacombe Signed-off-by: Mauro Carvalho Chehab --- drivers/i2c/Kconfig | 3 +-- drivers/i2c/algos/Kconfig | 12 ------------ 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index b923074b2cb..30f06e956bf 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -75,8 +75,7 @@ config I2C_HELPER_AUTO In doubt, say Y. config I2C_SMBUS - tristate - prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO + tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO help Say Y here if you want support for SMBus extensions to the I2C specification. At the moment, the only supported extension is diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig index 3998dd620a0..7b2ce4a0852 100644 --- a/drivers/i2c/algos/Kconfig +++ b/drivers/i2c/algos/Kconfig @@ -15,15 +15,3 @@ config I2C_ALGOPCA tristate "I2C PCA 9564 interfaces" endmenu - -# In automatic configuration mode, we still have to define the -# symbols to avoid unmet dependencies. - -if I2C_HELPER_AUTO -config I2C_ALGOBIT - tristate -config I2C_ALGOPCF - tristate -config I2C_ALGOPCA - tristate -endif -- cgit v1.2.3-70-g09d2 From 37e3273ee52fb995c1f531fa1d98d190cc35e1bc Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 6 Nov 2010 18:30:26 -0300 Subject: media/video: convert Kconfig to use the menu's `visible' keyword Signed-off-by: Arnaud Lacombe Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index ac16e815e27..6830d2848bd 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -112,7 +112,7 @@ config VIDEO_IR_I2C # menu "Encoders/decoders and other helper chips" - depends on !VIDEO_HELPER_CHIPS_AUTO + visible if !VIDEO_HELPER_CHIPS_AUTO comment "Audio decoders" -- cgit v1.2.3-70-g09d2 From c38bd4ffc7f24a99a14f9c776276e816f5de2509 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 6 Nov 2010 18:30:27 -0300 Subject: i2c/algos: convert Kconfig to use the menu's `visible' keyword Signed-off-by: Arnaud Lacombe Signed-off-by: Mauro Carvalho Chehab --- drivers/i2c/algos/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig index 7b2ce4a0852..f1cfe7e5508 100644 --- a/drivers/i2c/algos/Kconfig +++ b/drivers/i2c/algos/Kconfig @@ -3,7 +3,7 @@ # menu "I2C Algorithms" - depends on !I2C_HELPER_AUTO + visible if !I2C_HELPER_AUTO config I2C_ALGOBIT tristate "I2C bit-banging interfaces" -- cgit v1.2.3-70-g09d2 From 9b4320b77bab4031649c484da1c595f39c2e43cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Nov 2010 14:29:05 -0300 Subject: [media] Fix Kconfig errors due to two visible menus Use the new visible Kconfig keyword to avoid producing error for two menus that are visible only if Tuner/frontend customise options are enabled. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/Kconfig | 8 ++++---- drivers/media/dvb/frontends/Kconfig | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 2385e6cca63..78b089526e0 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -31,7 +31,7 @@ config MEDIA_TUNER select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE -menuconfig MEDIA_TUNER_CUSTOMISE +config MEDIA_TUNER_CUSTOMISE bool "Customize analog and hybrid tuner modules to build" depends on MEDIA_TUNER default y if EMBEDDED @@ -44,7 +44,8 @@ menuconfig MEDIA_TUNER_CUSTOMISE If unsure say N. -if MEDIA_TUNER_CUSTOMISE +menu "Customize TV tuners" + visible if MEDIA_TUNER_CUSTOMISE config MEDIA_TUNER_SIMPLE tristate "Simple tuner support" @@ -185,5 +186,4 @@ config MEDIA_TUNER_TDA18218 default m if MEDIA_TUNER_CUSTOMISE help NXP TDA18218 silicon tuner driver. - -endif # MEDIA_TUNER_CUSTOMISE +endmenu diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index e9062b08a48..96b27016670 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -12,9 +12,8 @@ config DVB_FE_CUSTOMISE If unsure say N. -if DVB_FE_CUSTOMISE - menu "Customise DVB Frontends" + visible if DVB_FE_CUSTOMISE comment "Multistandard (satellite) frontends" depends on DVB_CORE @@ -619,5 +618,3 @@ config DVB_DUMMY_FE tristate "Dummy frontend driver" default n endmenu - -endif -- cgit v1.2.3-70-g09d2 From aa2d8cbe169b7328eeabc9e2debccf5aee6f9199 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 23 Oct 2010 09:13:37 -0300 Subject: [media] v4l: Remove hardcoded module names passed to v4l2_i2c_new_subdev* (2) With the v4l2_i2c_new_subdev* functions now supporting loading modules based on modaliases, replace the hardcoded module name passed to those functions by NULL in the cafe-ccic, via-camera and s5p-fimc drivers. All corresponding I2C modules have been checked, and all of them include a module aliases table with names corresponding to what the drivers modified here use. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 3 +-- drivers/media/video/s5p-fimc/fimc-capture.c | 2 +- drivers/media/video/via-camera.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 7bc36670071..61a58d475b7 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2066,8 +2066,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, cam->sensor_addr = 0x42; cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter, - "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr, - NULL); + NULL, "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL); if (cam->sensor == NULL) { ret = -ENODEV; goto out_smbus; diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index e8f13d3e2df..26f7ad292ae 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc, return ERR_PTR(-ENOMEM); sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap, - MODULE_NAME, isp_info->board_info, NULL); + NULL, isp_info->board_info, NULL); if (!sd) { v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n"); return NULL; diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index 02a21bccae1..01bcdb44b5c 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c @@ -1360,7 +1360,7 @@ static __devinit int viacam_probe(struct platform_device *pdev) */ sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31); cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter, - "ov7670", "ov7670", 0x42 >> 1, NULL); + NULL, "ov7670", 0x42 >> 1, NULL); if (cam->sensor == NULL) { dev_err(&pdev->dev, "Unable to find the sensor!\n"); ret = -ENODEV; -- cgit v1.2.3-70-g09d2 From 9a1f8b34aa539000da17a06235e4bec254d0bfb5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 24 Sep 2010 10:16:44 -0300 Subject: [media] v4l: Remove module_name argument to the v4l2_i2c_new_subdev* functions The argument isn't used anymore by the functions, remove it. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si4713.c | 2 +- drivers/media/video/au0828/au0828-cards.c | 4 ++-- drivers/media/video/bt8xx/bttv-cards.c | 22 +++++++++++----------- drivers/media/video/cafe_ccic.c | 2 +- drivers/media/video/cx18/cx18-i2c.c | 8 ++++---- drivers/media/video/cx231xx/cx231xx-cards.c | 4 ++-- drivers/media/video/cx23885/cx23885-cards.c | 2 +- drivers/media/video/cx23885/cx23885-video.c | 4 ++-- drivers/media/video/cx88/cx88-cards.c | 9 ++++----- drivers/media/video/cx88/cx88-video.c | 7 +++---- drivers/media/video/davinci/vpfe_capture.c | 1 - drivers/media/video/davinci/vpif_capture.c | 1 - drivers/media/video/davinci/vpif_display.c | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 18 +++++++++--------- drivers/media/video/fsl-viu.c | 2 +- drivers/media/video/ivtv/ivtv-i2c.c | 22 +++++++++------------- drivers/media/video/mxb.c | 12 ++++++------ drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 ++---- drivers/media/video/s5p-fimc/fimc-capture.c | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 8 ++++---- drivers/media/video/saa7134/saa7134-core.c | 4 ++-- drivers/media/video/sh_vou.c | 2 +- drivers/media/video/soc_camera.c | 2 +- drivers/media/video/usbvision/usbvision-i2c.c | 6 +++--- drivers/media/video/v4l2-common.c | 15 +++++---------- drivers/media/video/via-camera.c | 2 +- drivers/media/video/vino.c | 4 ++-- drivers/media/video/zoran/zoran_card.c | 5 ++--- drivers/staging/go7007/go7007-driver.c | 2 +- drivers/staging/tm6000/tm6000-cards.c | 4 ++-- include/media/v4l2-common.h | 16 ++++++---------- 31 files changed, 90 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 6a435786b63..03829e6818b 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -291,7 +291,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) goto unregister_v4l2_dev; } - sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL, + sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, pdata->subdev_board_info, NULL); if (!sd) { dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 0453816d4ec..01be89fa5c7 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev) be abstracted out if we ever need to support a different demod) */ sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "au8522", 0x8e >> 1, NULL); + "au8522", 0x8e >> 1, NULL); if (sd == NULL) printk(KERN_ERR "analog subdev registration failed\n"); } @@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev) if (dev->board.tuner_type != TUNER_ABSENT) { /* Load the tuner module, which does the attach */ sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tuner", dev->board.tuner_addr, NULL); + "tuner", dev->board.tuner_addr, NULL); if (sd == NULL) printk(KERN_ERR "tuner subdev registration fail\n"); diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 87d8b006ef7..49efcf660ba 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv) struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "saa6588", 0, addrs); + &btv->c.i2c_adap, "saa6588", 0, addrs); btv->has_saa6588 = (sd != NULL); } @@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv) }; btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "msp3400", 0, addrs); + &btv->c.i2c_adap, "msp3400", 0, addrs); if (btv->sd_msp34xx) return; goto no_audio; @@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv) }; if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tda7432", 0, addrs)) + &btv->c.i2c_adap, "tda7432", 0, addrs)) return; goto no_audio; } @@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv) case 3: { /* The user specified that we should probe for tvaudio */ btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs()); + &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); if (btv->sd_tvaudio) return; goto no_audio; @@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv) found is really something else (e.g. a tea6300). */ if (!bttv_tvcards[btv->c.type].no_msp34xx) { btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "msp3400", + &btv->c.i2c_adap, "msp3400", 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1)); } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "msp3400", + &btv->c.i2c_adap, "msp3400", 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1)); } @@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv) }; if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tda7432", 0, addrs)) + &btv->c.i2c_adap, "tda7432", 0, addrs)) return; } /* Now see if we can find one of the tvaudio devices. */ btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs()); + &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); if (btv->sd_tvaudio) return; @@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv) /* Load tuner module before issuing tuner config call! */ if (bttv_tvcards[btv->c.type].has_radio) v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tuner", + &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tuner", + &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, NULL, "tuner", + &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 61a58d475b7..260c666ce93 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2066,7 +2066,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, cam->sensor_addr = 0x42; cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter, - NULL, "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL); + "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL); if (cam->sensor == NULL) { ret = -ENODEV; goto out_smbus; diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index a09caf88317..e71a026f341 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -122,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) if (hw == CX18_HW_TUNER) { /* special tuner group handling */ sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, - adap, NULL, type, 0, cx->card_i2c->radio); + adap, type, 0, cx->card_i2c->radio); if (sd != NULL) sd->grp_id = hw; sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, - adap, NULL, type, 0, cx->card_i2c->demod); + adap, type, 0, cx->card_i2c->demod); if (sd != NULL) sd->grp_id = hw; sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, - adap, NULL, type, 0, cx->card_i2c->tv); + adap, type, 0, cx->card_i2c->tv); if (sd != NULL) sd->grp_id = hw; return sd != NULL ? 0 : -1; @@ -144,7 +144,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) return -1; /* It's an I2C device other than an analog tuner or IR chip */ - sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx], + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx], NULL); if (sd != NULL) sd->grp_id = hw; diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 56c2d8195ac..2c78d188bb0 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -560,7 +560,7 @@ void cx231xx_card_setup(struct cx231xx *dev) if (dev->board.decoder == CX231XX_AVDECODER) { dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[0].i2c_adap, - NULL, "cx25840", 0x88 >> 1, NULL); + "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) cx231xx_info("cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); @@ -571,7 +571,7 @@ void cx231xx_card_setup(struct cx231xx *dev) if (dev->board.tuner_type != TUNER_ABSENT) { dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, - NULL, "tuner", + "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) cx231xx_info("tuner subdev registration failure\n"); diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index db054004e46..8861309268b 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -1247,7 +1247,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, - NULL, "cx25840", 0x88 >> 1, NULL); + "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840) { dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; v4l2_subdev_call(dev->sd_cx25840, core, load_fw); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 3cc9f462d08..8b2fb8a4375 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1507,10 +1507,10 @@ int cx23885_video_register(struct cx23885_dev *dev) if (dev->tuner_addr) sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[1].i2c_adap, - NULL, "tuner", dev->tuner_addr, NULL); + "tuner", dev->tuner_addr, NULL); else sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[1].i2c_adap, NULL, + &dev->i2c_bus[1].i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); if (sd) { struct tuner_setup tun_setup; diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index b26fcba8600..9b9e169cce9 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -3515,19 +3515,18 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) later code configures a tea5767. */ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - NULL, "tuner", - 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); + "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); if (has_demod) v4l2_i2c_new_subdev(&core->v4l2_dev, - &core->i2c_adap, NULL, "tuner", + &core->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (core->board.tuner_addr == ADDR_UNSET) { v4l2_i2c_new_subdev(&core->v4l2_dev, - &core->i2c_adap, NULL, "tuner", + &core->i2c_adap, "tuner", 0, has_demod ? tv_addrs + 4 : tv_addrs); } else { v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - NULL, "tuner", core->board.tuner_addr, NULL); + "tuner", core->board.tuner_addr, NULL); } } diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d2f159daa8b..ab98c0e07f9 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1896,14 +1896,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, if (core->board.audio_chip == V4L2_IDENT_WM8775) v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - NULL, "wm8775", 0x36 >> 1, NULL); + "wm8775", 0x36 >> 1, NULL); if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { /* This probes for a tda9874 as is used on some Pixelview Ultra boards. */ - v4l2_i2c_new_subdev(&core->v4l2_dev, - &core->i2c_adap, - NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); + v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, + "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); } switch (core->boardnr) { diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index d8e38cc4ec4..7333a9bb254 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1986,7 +1986,6 @@ static __init int vpfe_probe(struct platform_device *pdev) vpfe_dev->sd[i] = v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev, i2c_adap, - NULL, &sdinfo->board_info, NULL); if (vpfe_dev->sd[i]) { diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index 6ac6acd1635..193abab6b35 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c @@ -2013,7 +2013,6 @@ static __init int vpif_probe(struct platform_device *pdev) vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, i2c_adap, - NULL, &subdevdata->board_info, NULL); diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index 685f6a6ee60..412c65d54fe 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -1553,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev) for (i = 0; i < subdev_count; i++) { vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, - i2c_adap, NULL, + i2c_adap, &subdevdata[i].board_info, NULL); if (!vpif_obj.sd[i]) { diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 54859233f31..f7e9168157a 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2554,39 +2554,39 @@ void em28xx_card_setup(struct em28xx *dev) /* request some modules */ if (dev->board.has_msp34xx) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "msp3400", 0, msp3400_addrs); + "msp3400", 0, msp3400_addrs); if (dev->board.decoder == EM28XX_SAA711X) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "saa7115_auto", 0, saa711x_addrs); + "saa7115_auto", 0, saa711x_addrs); if (dev->board.decoder == EM28XX_TVP5150) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tvp5150", 0, tvp5150_addrs); + "tvp5150", 0, tvp5150_addrs); if (dev->em28xx_sensor == EM28XX_MT9V011) { struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs); + &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs); v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); } if (dev->board.adecoder == EM28XX_TVAUDIO) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tvaudio", dev->board.tvaudio_addr, NULL); + "tvaudio", dev->board.tvaudio_addr, NULL); if (dev->board.tuner_type != TUNER_ABSENT) { int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); if (dev->board.radio.type) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tuner", dev->board.radio_addr, NULL); + "tuner", dev->board.radio_addr, NULL); if (has_demod) v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (dev->tuner_addr == 0) { enum v4l2_i2c_tuner_type type = @@ -2594,14 +2594,14 @@ void em28xx_card_setup(struct em28xx *dev) struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(type)); if (sd) dev->tuner_addr = v4l2_i2c_subdev_addr(sd); } else { v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tuner", dev->tuner_addr, NULL); + "tuner", dev->tuner_addr, NULL); } } diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c index 9a075d83dd1..b8faff2dd71 100644 --- a/drivers/media/video/fsl-viu.c +++ b/drivers/media/video/fsl-viu.c @@ -1486,7 +1486,7 @@ static int __devinit viu_of_probe(struct platform_device *op, ad = i2c_get_adapter(0); viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad, - NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); + "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); viu_dev->vidq.timeout.function = viu_vid_timeout; viu_dev->vidq.timeout.data = (unsigned long)viu_dev; diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 9e8039ac909..665191c9b40 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -239,19 +239,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) return -1; if (hw == IVTV_HW_TUNER) { /* special tuner handling */ - sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, - adap, NULL, type, - 0, itv->card_i2c->radio); + sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, + itv->card_i2c->radio); if (sd) sd->grp_id = 1 << idx; - sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, - adap, NULL, type, - 0, itv->card_i2c->demod); + sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, + itv->card_i2c->demod); if (sd) sd->grp_id = 1 << idx; - sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, - adap, NULL, type, - 0, itv->card_i2c->tv); + sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, + itv->card_i2c->tv); if (sd) sd->grp_id = 1 << idx; return sd ? 0 : -1; @@ -267,17 +264,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) /* It's an I2C device other than an analog tuner or IR chip */ if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, - adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx])); + adap, type, 0, I2C_ADDRS(hw_addrs[idx])); } else if (hw == IVTV_HW_CX25840) { struct cx25840_platform_data pdata; pdata.pvr150_workaround = itv->pvr150_workaround; sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev, - adap, NULL, type, 0, &pdata, hw_addrs[idx], - NULL); + adap, type, 0, &pdata, hw_addrs[idx], NULL); } else { sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, - adap, NULL, type, hw_addrs[idx], NULL); + adap, type, hw_addrs[idx], NULL); } if (sd) sd->grp_id = 1 << idx; diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 94ba698d0ad..4e8fd965f15 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -185,17 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev) } mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "saa7111", I2C_SAA7111A, NULL); + "saa7111", I2C_SAA7111A, NULL); mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "tea6420", I2C_TEA6420_1, NULL); + "tea6420", I2C_TEA6420_1, NULL); mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "tea6420", I2C_TEA6420_2, NULL); + "tea6420", I2C_TEA6420_2, NULL); mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "tea6415c", I2C_TEA6415C, NULL); + "tea6415c", I2C_TEA6415C, NULL); mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "tda9840", I2C_TDA9840, NULL); + "tda9840", I2C_TDA9840, NULL); mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - NULL, "tuner", I2C_TUNER, NULL); + "tuner", I2C_TUNER, NULL); /* check if all devices are present */ if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index bef202752cc..66ad516bdfd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2088,16 +2088,14 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, " Setting up with specified i2c address 0x%x", mid, i2caddr[0]); sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, - NULL, fname, - i2caddr[0], NULL); + fname, i2caddr[0], NULL); } else { pvr2_trace(PVR2_TRACE_INIT, "Module ID %u:" " Setting up with address probe list", mid); sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, - NULL, fname, - 0, i2caddr); + fname, 0, i2caddr); } if (!sd) { diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 26f7ad292ae..1b93207c89e 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc, return ERR_PTR(-ENOMEM); sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap, - NULL, isp_info->board_info, NULL); + isp_info->board_info, NULL); if (!sd) { v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n"); return NULL; diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 0911cb580e1..1d4d0a49ea5 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -7551,22 +7551,22 @@ int saa7134_board_init2(struct saa7134_dev *dev) so we do not need to probe for a radio tuner device. */ if (dev->radio_type != UNSET) v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", dev->radio_addr, NULL); if (has_demod) v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (dev->tuner_addr == ADDR_UNSET) { enum v4l2_i2c_tuner_type type = has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(type)); } else { v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "tuner", + &dev->i2c_adap, "tuner", dev->tuner_addr, NULL); } } diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 764d7d219fe..756a2781226 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, if (card_is_empress(dev)) { struct v4l2_subdev *sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "saa6752hs", + "saa6752hs", saa7134_boards[dev->board].empress_addr, NULL); if (sd) @@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, NULL, "saa6588", + &dev->i2c_adap, "saa6588", 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr)); if (sd) { printk(KERN_INFO "%s: found RDS decoder\n", dev->name); diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 0f4906136b8..4e5a8cf76de 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c @@ -1406,7 +1406,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) goto ereset; subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap, - NULL, vou_pdata->board_info, NULL); + vou_pdata->board_info, NULL); if (!subdev) { ret = -ENOMEM; goto ei2cnd; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 43848a751d1..335120c2021 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -896,7 +896,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd, icl->board_info->platform_data = icd; subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, - NULL, icl->board_info, NULL); + icl->board_info, NULL); if (!subdev) goto ei2cnd; diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index e3bbae26e3c..81dd53bb526 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -251,7 +251,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) hit-and-miss. */ mdelay(10); v4l2_i2c_new_subdev(&usbvision->v4l2_dev, - &usbvision->i2c_adap, NULL, + &usbvision->i2c_adap, "saa7115_auto", 0, saa711x_addrs); break; } @@ -261,14 +261,14 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) struct tuner_setup tun_setup; sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, - &usbvision->i2c_adap, NULL, + &usbvision->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); /* depending on whether we found a demod or not, select the tuner type. */ type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, - &usbvision->i2c_adap, NULL, + &usbvision->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(type)); if (sd == NULL) diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 9294282b5ad..b5eb1f3950b 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -368,18 +368,15 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init); /* Load an i2c sub-device. */ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, const char *module_name, - struct i2c_board_info *info, const unsigned short *probe_addrs) + struct i2c_adapter *adapter, struct i2c_board_info *info, + const unsigned short *probe_addrs) { struct v4l2_subdev *sd = NULL; struct i2c_client *client; BUG_ON(!v4l2_dev); - if (module_name) - request_module(module_name); - else - request_module(I2C_MODULE_PREFIX "%s", info->type); + request_module(I2C_MODULE_PREFIX "%s", info->type); /* Create the i2c client */ if (info->addr == 0 && probe_addrs) @@ -432,8 +429,7 @@ error: EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board); struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, - const char *module_name, const char *client_type, + struct i2c_adapter *adapter, const char *client_type, int irq, void *platform_data, u8 addr, const unsigned short *probe_addrs) { @@ -447,8 +443,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, info.irq = irq; info.platform_data = platform_data; - return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name, - &info, probe_addrs); + return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs); } EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg); diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index 01bcdb44b5c..9eda7cc0312 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c @@ -1360,7 +1360,7 @@ static __devinit int viacam_probe(struct platform_device *pdev) */ sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31); cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter, - NULL, "ov7670", 0x42 >> 1, NULL); + "ov7670", 0x42 >> 1, NULL); if (cam->sensor == NULL) { dev_err(&pdev->dev, "Unable to find the sensor!\n"); ret = -ENODEV; diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index e5e005dc155..7e7eec48f8b 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -4334,10 +4334,10 @@ static int __init vino_module_init(void) vino_drvdata->decoder = v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, - NULL, "saa7191", 0, I2C_ADDRS(0x45)); + "saa7191", 0, I2C_ADDRS(0x45)); vino_drvdata->camera = v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, - NULL, "indycam", 0, I2C_ADDRS(0x2b)); + "indycam", 0, I2C_ADDRS(0x2b)); dprintk("init complete!\n"); diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 7e6d62467ea..e520abf9f4c 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -1343,13 +1343,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev, } zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, - &zr->i2c_adapter, NULL, zr->card.i2c_decoder, + &zr->i2c_adapter, zr->card.i2c_decoder, 0, zr->card.addrs_decoder); if (zr->card.i2c_encoder) zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, - &zr->i2c_adapter, - NULL, zr->card.i2c_encoder, + &zr->i2c_adapter, zr->card.i2c_encoder, 0, zr->card.addrs_encoder); dprintk(2, diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index b3f42f37a31..48d4e483d8a 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c @@ -199,7 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type, struct go7007 *go = i2c_get_adapdata(adapter); struct v4l2_device *v4l2_dev = &go->v4l2_dev; - if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL)) + if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL)) return 0; printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type); diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 664e6038090..b143258f094 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -545,7 +545,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev) /* Load tuner module */ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tuner", dev->tuner_addr, NULL); + "tuner", dev->tuner_addr, NULL); memset(&tun_setup, 0, sizeof(tun_setup)); tun_setup.type = dev->tuner_type; @@ -683,7 +683,7 @@ static int tm6000_init_dev(struct tm6000_core *dev) if (dev->caps.has_tda9874) v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - NULL, "tvaudio", I2C_ADDR_TDA9874, NULL); + "tvaudio", I2C_ADDR_TDA9874, NULL); /* register and initialize V4L2 */ rc = tm6000_v4l2_register(dev); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 41dd480e45f..239125af3ea 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -137,31 +137,27 @@ struct v4l2_subdev_ops; /* Load an i2c module and return an initialized v4l2_subdev struct. - Only call request_module if module_name != NULL. The client_type argument is the name of the chip that's on the adapter. */ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, - const char *module_name, const char *client_type, + struct i2c_adapter *adapter, const char *client_type, int irq, void *platform_data, u8 addr, const unsigned short *probe_addrs); /* Load an i2c module and return an initialized v4l2_subdev struct. - Only call request_module if module_name != NULL. The client_type argument is the name of the chip that's on the adapter. */ static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, - const char *module_name, const char *client_type, + struct i2c_adapter *adapter, const char *client_type, u8 addr, const unsigned short *probe_addrs) { - return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name, - client_type, 0, NULL, addr, probe_addrs); + return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, client_type, 0, NULL, + addr, probe_addrs); } struct i2c_board_info; struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, const char *module_name, - struct i2c_board_info *info, const unsigned short *probe_addrs); + struct i2c_adapter *adapter, struct i2c_board_info *info, + const unsigned short *probe_addrs); /* Initialize an v4l2_subdev with data from an i2c_client struct */ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, -- cgit v1.2.3-70-g09d2 From f570e1dd8469d39420f406a4f5442c270b1e759e Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 7 Nov 2010 09:43:33 -0500 Subject: EDAC: Remove deprecated kbuild goal definitions Change EDAC's Makefile to use -y instead of -objs because -objs is deprecated and not mentioned in Documentation/kbuild/makefiles.txt. [bp: Fixup commit message] [bp: Fixup indentation] Signed-off-by: Tracey Dent Signed-off-by: Borislav Petkov --- drivers/edac/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index b3781399b38..ba2898b3639 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -10,16 +10,16 @@ obj-$(CONFIG_EDAC) := edac_stub.o obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o obj-$(CONFIG_EDAC_MCE) += edac_mce.o -edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o -edac_core-objs += edac_module.o edac_device_sysfs.o +edac_core-y := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o +edac_core-y += edac_module.o edac_device_sysfs.o ifdef CONFIG_PCI -edac_core-objs += edac_pci.o edac_pci_sysfs.o +edac_core-y += edac_pci.o edac_pci_sysfs.o endif obj-$(CONFIG_EDAC_MCE_INJ) += mce_amd_inj.o -edac_mce_amd-objs := mce_amd.o +edac_mce_amd-y := mce_amd.o obj-$(CONFIG_EDAC_DECODE_MCE) += edac_mce_amd.o obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o -- cgit v1.2.3-70-g09d2 From df4b2a30e0b9e553abfd63ee75dbbd66be80f01a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 18 Nov 2010 22:05:43 -0500 Subject: EDAC, MCE: Fix edac_init_mce_inject error handling Otherwise, variable i will be -1 inside the latest iteration of the while loop. Signed-off-by: Axel Lin Signed-off-by: Borislav Petkov --- drivers/edac/mce_amd_inj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 8d0688f36d4..39faded3cad 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c @@ -139,7 +139,7 @@ static int __init edac_init_mce_inject(void) return 0; err_sysfs_create: - while (i-- >= 0) + while (--i >= 0) sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr); kobject_del(mce_kobj); -- cgit v1.2.3-70-g09d2 From 84cf7029b63ca3eef823438a29ceb5ba139b883a Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Thu, 18 Nov 2010 11:50:02 +0000 Subject: qlge: Fix incorrect usage of module parameters and netdev msg level Driver appears to be mistaking the permission field with default value in the case of debug and qlge_irq_type. Driver is also passing debug as a bitmask into netif_msg_init() which wants a number of bits. Ron Mercer suggests we should change this to pass in -1 so the defaults get used instead, which makes the default much less verbose. Signed-off-by: Milton Miller Signed-off-by: Sonny Rao Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c30e0fe55a3..528eaef5308 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -62,15 +62,15 @@ static const u32 default_msg = /* NETIF_MSG_PKTDATA | */ NETIF_MSG_HW | NETIF_MSG_WOL | 0; -static int debug = 0x00007fff; /* defaults above */ -module_param(debug, int, 0); +static int debug = -1; /* defaults above */ +module_param(debug, int, 0664); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); #define MSIX_IRQ 0 #define MSI_IRQ 1 #define LEG_IRQ 2 static int qlge_irq_type = MSIX_IRQ; -module_param(qlge_irq_type, int, MSIX_IRQ); +module_param(qlge_irq_type, int, 0664); MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); static int qlge_mpi_coredump; -- cgit v1.2.3-70-g09d2 From 27d916d680e7b324087a75d080f215e7c34a4e8f Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 19 Nov 2010 11:58:52 +0000 Subject: phylib: Use common page register definition for Marvell PHYs. The definition of the Marvell PHY page register is not specific to 88E1121, so rename the macro to MII_MARVELL_PHY_PAGE, and use it throughout. Suggested-by: Cyril Chemparathy Signed-off-by: David Daney Cc: Cyril Chemparathy Cc: Arnaud Patard Cc: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index f0bd1a1aba3..3600b8b21bf 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -35,6 +35,8 @@ #include #include +#define MII_MARVELL_PHY_PAGE 22 + #define MII_M1011_IEVENT 0x13 #define MII_M1011_IEVENT_CLEAR 0x0000 @@ -80,7 +82,6 @@ #define MII_88E1121_PHY_LED_CTRL 16 #define MII_88E1121_PHY_LED_PAGE 3 #define MII_88E1121_PHY_LED_DEF 0x0030 -#define MII_88E1121_PHY_PAGE 22 #define MII_M1011_PHY_STATUS 0x11 #define MII_M1011_PHY_STATUS_1000 0x8000 @@ -190,9 +191,9 @@ static int m88e1121_config_aneg(struct phy_device *phydev) { int err, oldpage, mscr; - oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - err = phy_write(phydev, MII_88E1121_PHY_PAGE, + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_MSCR_PAGE); if (err < 0) return err; @@ -218,7 +219,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev) return err; } - phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); + phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); err = phy_write(phydev, MII_BMCR, BMCR_RESET); if (err < 0) @@ -229,11 +230,11 @@ static int m88e1121_config_aneg(struct phy_device *phydev) if (err < 0) return err; - oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); + phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); - phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); + phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); err = genphy_config_aneg(phydev); @@ -244,9 +245,9 @@ static int m88e1318_config_aneg(struct phy_device *phydev) { int err, oldpage, mscr; - oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - err = phy_write(phydev, MII_88E1121_PHY_PAGE, + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_MSCR_PAGE); if (err < 0) return err; @@ -258,7 +259,7 @@ static int m88e1318_config_aneg(struct phy_device *phydev) if (err < 0) return err; - err = phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); if (err < 0) return err; @@ -398,7 +399,7 @@ static int m88e1118_config_init(struct phy_device *phydev) int err; /* Change address */ - err = phy_write(phydev, 0x16, 0x0002); + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); if (err < 0) return err; @@ -408,7 +409,7 @@ static int m88e1118_config_init(struct phy_device *phydev) return err; /* Change address */ - err = phy_write(phydev, 0x16, 0x0003); + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003); if (err < 0) return err; @@ -421,7 +422,7 @@ static int m88e1118_config_init(struct phy_device *phydev) return err; /* Reset address */ - err = phy_write(phydev, 0x16, 0x0); + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); if (err < 0) return err; -- cgit v1.2.3-70-g09d2 From 90600732d8b2fbc422bc9c57bdc73513d909367f Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 19 Nov 2010 11:58:53 +0000 Subject: phylib: Add support for Marvell 88E1149R devices. The 88E1149R is 10/100/1000 quad-gigabit Ethernet PHY. The .config_aneg function can be shared with 88E1118, but it needs its own .config_init. Signed-off-by: David Daney Cc: Cyril Chemparathy Cc: Arnaud Patard Cc: Benjamin Herrenschmidt Cc: Wolfram Sang Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/marvell_phy.h | 1 + 2 files changed, 41 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 3600b8b21bf..def19d7c53e 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -433,6 +433,32 @@ static int m88e1118_config_init(struct phy_device *phydev) return 0; } +static int m88e1149_config_init(struct phy_device *phydev) +{ + int err; + + /* Change address */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); + if (err < 0) + return err; + + /* Enable 1000 Mbit */ + err = phy_write(phydev, 0x15, 0x1048); + if (err < 0) + return err; + + /* Reset address */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); + if (err < 0) + return err; + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) + return err; + + return 0; +} + static int m88e1145_config_init(struct phy_device *phydev) { int err; @@ -685,6 +711,19 @@ static struct phy_driver marvell_drivers[] = { .config_intr = &marvell_config_intr, .driver = { .owner = THIS_MODULE }, }, + { + .phy_id = MARVELL_PHY_ID_88E1149R, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E1149R", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1149_config_init, + .config_aneg = &m88e1118_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = { .owner = THIS_MODULE }, + }, { .phy_id = MARVELL_PHY_ID_88E1240, .phy_id_mask = MARVELL_PHY_ID_MASK, @@ -736,6 +775,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = { { 0x01410e10, 0xfffffff0 }, { 0x01410cb0, 0xfffffff0 }, { 0x01410cd0, 0xfffffff0 }, + { 0x01410e50, 0xfffffff0 }, { 0x01410e30, 0xfffffff0 }, { 0x01410e90, 0xfffffff0 }, { } diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h index 1ff81b51b65..dd3c34ebca9 100644 --- a/include/linux/marvell_phy.h +++ b/include/linux/marvell_phy.h @@ -11,6 +11,7 @@ #define MARVELL_PHY_ID_88E1118 0x01410e10 #define MARVELL_PHY_ID_88E1121R 0x01410cb0 #define MARVELL_PHY_ID_88E1145 0x01410cd0 +#define MARVELL_PHY_ID_88E1149R 0x01410e50 #define MARVELL_PHY_ID_88E1240 0x01410e30 #define MARVELL_PHY_ID_88E1318S 0x01410e90 -- cgit v1.2.3-70-g09d2 From cf41a51db89850033efc11c18a5257de810b5417 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 19 Nov 2010 12:13:18 +0000 Subject: of/phylib: Use device tree properties to initialize Marvell PHYs. Some aspects of PHY initialization are board dependent, things like indicator LED connections and some clocking modes cannot be determined by probing. The dev_flags element of struct phy_device can be used to control these things if an appropriate value can be passed from the Ethernet driver. We run into problems however if the PHY connections are specified by the device tree. There is no way for the Ethernet driver to know what flags it should pass. If we are using the device tree, the struct phy_device will be populated with the device tree node corresponding to the PHY, and we can extract extra configuration information from there. The next question is what should the format of that information be? It is highly device specific, and the device tree representation should not be tied to any arbitrary kernel defined constants. A straight forward representation is just to specify the exact bits that should be set using the "marvell,reg-init" property: phy5: ethernet-phy@5 { reg = <5>; compatible = "marvell,88e1149r"; marvell,reg-init = /* led[0]:1000, led[1]:100, led[2]:10, led[3]:tx */ <3 0x10 0 0x5777>, /* Reg 3,16 <- 0x5777 */ /* mix %:0, led[0123]:drive low off hiZ */ <3 0x11 0 0x00aa>, /* Reg 3,17 <- 0x00aa */ /* default blink periods. */ <3 0x12 0 0x4105>, /* Reg 3,18 <- 0x4105 */ /* led[4]:rx, led[5]:dplx, led[45]:drive low off hiZ */ <3 0x13 0 0x0a60>; /* Reg 3,19 <- 0x0a60 */ }; phy6: ethernet-phy@6 { reg = <6>; compatible = "marvell,88e1118"; marvell,reg-init = /* Fix rx and tx clock transition timing */ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */ /* Adjust LED drive. */ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */ /* irq, blink-activity, blink-link */ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */ }; The Marvell PHYs have a page select register at register 22 (0x16), we can specify any register by its page and register number. These are the first and second word. The third word contains a mask to be ANDed with the existing register value, and the fourth word is ORed with the result to yield the new register value. The new marvell_of_reg_init function leaves the page select register unchanged, so a call to it can be dropped into the .config_init functions without unduly affecting the state of the PHY. If CONFIG_OF_MDIO is not set, there is no of_node, or no "marvell,reg-init" property, the PHY initialization is unchanged. Signed-off-by: David Daney Cc: Grant Likely Cc: Cyril Chemparathy Cc: David Daney Cc: Arnaud Patard Cc: Benjamin Herrenschmidt Reviewed-by: Grant Likely Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index def19d7c53e..e8b9c53c304 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -187,6 +188,87 @@ static int marvell_config_aneg(struct phy_device *phydev) return 0; } +#ifdef CONFIG_OF_MDIO +/* + * Set and/or override some configuration registers based on the + * marvell,reg-init property stored in the of_node for the phydev. + * + * marvell,reg-init = ,...; + * + * There may be one or more sets of : + * + * reg-page: which register bank to use. + * reg: the register. + * mask: if non-zero, ANDed with existing register value. + * value: ORed with the masked value and written to the regiser. + * + */ +static int marvell_of_reg_init(struct phy_device *phydev) +{ + const __be32 *paddr; + int len, i, saved_page, current_page, page_changed, ret; + + if (!phydev->dev.of_node) + return 0; + + paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len); + if (!paddr || len < (4 * sizeof(*paddr))) + return 0; + + saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); + if (saved_page < 0) + return saved_page; + page_changed = 0; + current_page = saved_page; + + ret = 0; + len /= sizeof(*paddr); + for (i = 0; i < len - 3; i += 4) { + u16 reg_page = be32_to_cpup(paddr + i); + u16 reg = be32_to_cpup(paddr + i + 1); + u16 mask = be32_to_cpup(paddr + i + 2); + u16 val_bits = be32_to_cpup(paddr + i + 3); + int val; + + if (reg_page != current_page) { + current_page = reg_page; + page_changed = 1; + ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); + if (ret < 0) + goto err; + } + + val = 0; + if (mask) { + val = phy_read(phydev, reg); + if (val < 0) { + ret = val; + goto err; + } + val &= mask; + } + val |= val_bits; + + ret = phy_write(phydev, reg, val); + if (ret < 0) + goto err; + + } +err: + if (page_changed) { + i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); + if (ret == 0) + ret = i; + } + return ret; +} +#else +static int marvell_of_reg_init(struct phy_device *phydev) +{ + return 0; +} +#endif /* CONFIG_OF_MDIO */ + static int m88e1121_config_aneg(struct phy_device *phydev) { int err, oldpage, mscr; @@ -369,6 +451,9 @@ static int m88e1111_config_init(struct phy_device *phydev) return err; } + err = marvell_of_reg_init(phydev); + if (err < 0) + return err; err = phy_write(phydev, MII_BMCR, BMCR_RESET); if (err < 0) @@ -421,6 +506,10 @@ static int m88e1118_config_init(struct phy_device *phydev) if (err < 0) return err; + err = marvell_of_reg_init(phydev); + if (err < 0) + return err; + /* Reset address */ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); if (err < 0) @@ -447,6 +536,10 @@ static int m88e1149_config_init(struct phy_device *phydev) if (err < 0) return err; + err = marvell_of_reg_init(phydev); + if (err < 0) + return err; + /* Reset address */ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); if (err < 0) @@ -518,6 +611,10 @@ static int m88e1145_config_init(struct phy_device *phydev) } } + err = marvell_of_reg_init(phydev); + if (err < 0) + return err; + return 0; } -- cgit v1.2.3-70-g09d2 From 09910509ebc74643e94fe6f3feb4c23b019aeb34 Mon Sep 17 00:00:00 2001 From: Glenn Sommer Date: Mon, 22 Nov 2010 12:00:05 -0800 Subject: Input: usbtouchscreen - add support for LG Flatron T1710B I've recently got my hands on a LG Flatron T1710B touchscreen. As other LG products, this seems to use the ITM panel. Signed-off-by: Glenn Sommer Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d33..73fd6642b68 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { #ifdef CONFIG_TOUCHSCREEN_USB_ITM {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, + {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, #endif #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO -- cgit v1.2.3-70-g09d2 From 12334715720b012180579f57650879d0fbb11a84 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 19 Nov 2010 11:27:09 -0500 Subject: xen/events: Use PIRQ instead of GSI value when unmapping MSI/MSI-X irqs. When we allocate a vector for MSI/MSI-X we save away the PIRQ, and the vector value. When we unmap (de-allocate) the MSI/MSI-X vector(s) we need to provide the PIRQ and the vector value. What we did instead was to provide the GSI (which was zero) and the vector value, and we got these unhappy error messages: (XEN) irq.c:1575: dom0: pirq 0 not mapped [ 7.733415] unmap irq failed -22 This patches fixes this and we use the PIRQ value instead of the GSI value. CC: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index d6d4f76ed50..2811bb988ea 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -755,7 +755,7 @@ int xen_destroy_irq(int irq) goto out; if (xen_initial_domain()) { - unmap_irq.pirq = info->u.pirq.gsi; + unmap_irq.pirq = info->u.pirq.pirq; unmap_irq.domid = DOMID_SELF; rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); if (rc) { -- cgit v1.2.3-70-g09d2 From 15ec44611904be0dcc97b84c29fbf964e5e2b36f Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Fri, 19 Nov 2010 16:48:39 -0500 Subject: mmc: sdhci: 8-bit bus width changes We now: * check for a v3 controller before setting 8-bit bus width * offer a callback for platform code to switch to 8-bit mode, which allows non-v3 controllers to support it * rely on mmc->caps |= MMC_CAP_8_BIT_DATA; in platform code to specify that the board designers have indeed brought out all the pins for 8-bit to the slot. We were previously relying only on whether the *controller* supported 8-bit, which doesn't tell us anything about the pin configuration in the board design. This fixes the MMC card regression reported by Maxim Levitsky here: http://thread.gmane.org/gmane.linux.kernel.mmc/4336 by no longer assuming that 8-bit works by default. Signed-off-by: Philip Rakity Tested-by: Giuseppe Cavallaro Signed-off-by: Chris Ball --- arch/arm/plat-pxa/include/plat/sdhci.h | 3 +++ drivers/mmc/host/sdhci-pxa.c | 4 ++++ drivers/mmc/host/sdhci.c | 44 +++++++++++++++++++++++++--------- drivers/mmc/host/sdhci.h | 5 +++- 4 files changed, 44 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index e49c5b6fc4e..1ab332e37d7 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h @@ -17,6 +17,9 @@ /* Require clock free running */ #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0) +/* Board design supports 8-bit data on SD/SDIO BUS */ +#define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2) + /* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI * @max_speed: the maximum speed supported diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c index fc406ac5d19..5a61208cbc6 100644 --- a/drivers/mmc/host/sdhci-pxa.c +++ b/drivers/mmc/host/sdhci-pxa.c @@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev) if (pdata->quirks) host->quirks |= pdata->quirks; + /* If slot design supports 8 bit data, indicate this to MMC. */ + if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) + host->mmc->caps |= MMC_CAP_8_BIT_DATA; + ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 154cbf83c1a..a25db426c91 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->ops->platform_send_init_74_clocks) host->ops->platform_send_init_74_clocks(host, ios->power_mode); - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - - if (ios->bus_width == MMC_BUS_WIDTH_8) - ctrl |= SDHCI_CTRL_8BITBUS; - else - ctrl &= ~SDHCI_CTRL_8BITBUS; + /* + * If your platform has 8-bit width support but is not a v3 controller, + * or if it requires special setup code, you should implement that in + * platform_8bit_width(). + */ + if (host->ops->platform_8bit_width) + host->ops->platform_8bit_width(host, ios->bus_width); + else { + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + if (ios->bus_width == MMC_BUS_WIDTH_8) { + ctrl &= ~SDHCI_CTRL_4BITBUS; + if (host->version >= SDHCI_SPEC_300) + ctrl |= SDHCI_CTRL_8BITBUS; + } else { + if (host->version >= SDHCI_SPEC_300) + ctrl &= ~SDHCI_CTRL_8BITBUS; + if (ios->bus_width == MMC_BUS_WIDTH_4) + ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; + } + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } - if (ios->bus_width == MMC_BUS_WIDTH_4) - ctrl |= SDHCI_CTRL_4BITBUS; - else - ctrl &= ~SDHCI_CTRL_4BITBUS; + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if ((ios->timing == MMC_TIMING_SD_HS || ios->timing == MMC_TIMING_MMC_HS) @@ -1855,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host) mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; else mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; + mmc->f_max = host->max_clk; mmc->caps |= MMC_CAP_SDIO_IRQ; + /* + * A controller may support 8-bit width, but the board itself + * might not have the pins brought out. Boards that support + * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in + * their platform code before calling sdhci_add_host(), and we + * won't assume 8-bit width for hosts without that CAP. + */ if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) - mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; + mmc->caps |= MMC_CAP_4_BIT_DATA; if (caps & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d52a7163b97..e42d7f00c06 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -76,7 +76,7 @@ #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 -#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_8BITBUS 0x20 #define SDHCI_POWER_CONTROL 0x29 #define SDHCI_POWER_ON 0x01 @@ -155,6 +155,7 @@ #define SDHCI_CLOCK_BASE_SHIFT 8 #define SDHCI_MAX_BLOCK_MASK 0x00030000 #define SDHCI_MAX_BLOCK_SHIFT 16 +#define SDHCI_CAN_DO_8BIT 0x00040000 #define SDHCI_CAN_DO_ADMA2 0x00080000 #define SDHCI_CAN_DO_ADMA1 0x00100000 #define SDHCI_CAN_DO_HISPD 0x00200000 @@ -215,6 +216,8 @@ struct sdhci_ops { unsigned int (*get_max_clock)(struct sdhci_host *host); unsigned int (*get_min_clock)(struct sdhci_host *host); unsigned int (*get_timeout_clock)(struct sdhci_host *host); + int (*platform_8bit_width)(struct sdhci_host *host, + int width); void (*platform_send_init_74_clocks)(struct sdhci_host *host, u8 power_mode); unsigned int (*get_ro)(struct sdhci_host *host); -- cgit v1.2.3-70-g09d2 From d47844a014fada1a788719f6426bc7044f2a0fd8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 20 Nov 2010 03:08:47 +0100 Subject: ath9k: fix timeout on stopping rx dma It seems that using ath9k_hw_stoppcurecv to stop rx dma is not enough. When it's time to stop DMA, the PCU is still busy, so the rx enable bit never clears. Using ath9k_hw_abortpcurecv helps with getting rx stopped much faster, with this change, I cannot reproduce the rx stop related WARN_ON anymore. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c76ea53c20c..1a62e351ec7 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc) bool stopped; spin_lock_bh(&sc->rx.rxbuflock); - ath9k_hw_stoppcurecv(ah); + ath9k_hw_abortpcurecv(ah); ath9k_hw_setrxfilter(ah, 0); stopped = ath9k_hw_stopdmarecv(ah); -- cgit v1.2.3-70-g09d2 From 1d8638d4038eb8709edc80e37a0bbb77253d86e9 Mon Sep 17 00:00:00 2001 From: Daniel Klaffenbach Date: Fri, 19 Nov 2010 21:25:21 -0600 Subject: ssb: b43-pci-bridge: Add new vendor for BCM4318 Add new vendor for Broadcom 4318. Signed-off-by: Daniel Klaffenbach Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/ssb/b43_pci_bridge.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index ef9c6a04ad8..744d3f6e470 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c @@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, + { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d278dd9cb76..f29c25ede70 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2043,6 +2043,7 @@ #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 +#define PCI_VENDOR_ID_BCM_GVC 0x14a4 #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_DEVICE_ID_TIGON3_5752 0x1600 #define PCI_DEVICE_ID_TIGON3_5752M 0x1601 -- cgit v1.2.3-70-g09d2 From b397492a8c1022887a9b2fb925fe92e69ce0ad4d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Nov 2010 13:15:27 +0100 Subject: carl9170: fix virtual interface setup crash This patch fixes a faulty bound check which caused a crash when too many virtual interface were brought up. BUG: unable to handle kernel NULL pointer dereference at 00000004 IP: [] carl9170_op_add_interface+0x1d7/0x2c0 [carl9170] *pde = 00000000 Oops: 0002 [#1] PREEMPT Modules linked in: carl9170 [...] Pid: 4720, comm: wpa_supplicant Not tainted 2.6.37-rc2-wl+ EIP: 0060:[] EFLAGS: 00210206 CPU: 0 EIP is at carl9170_op_add_interface+0x1d7/0x2c0 [carl9170] EAX: 00000000 ... Process wpa_supplicant Stack: f4f88f34 fffffff4 .. Call Trace: [] ? ieee80211_do_open+0x406/0x5c0 [mac80211] [...] Code: <89> 42 04 ... EIP: [] carl9170_op_add_interface+0x1d7/0x2c0 [carl9170] CR2: 0000000000000004 Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 980ae70ea42..a314c2c2bfb 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -647,7 +647,7 @@ init: } unlock: - if (err && (vif_id != -1)) { + if (err && (vif_id >= 0)) { vif_priv->active = false; bitmap_release_region(&ar->vif_bitmap, vif_id, 0); ar->vifs--; -- cgit v1.2.3-70-g09d2 From c48a2916355337895aea33839d39810eb575e775 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 19 Nov 2010 09:39:11 -0800 Subject: hwmon: (i5k_amb) Fix compile warning This patch fixes the following compile warning. drivers/hwmon/i5k_amb.c:500: warning: 'i5k_amb_ids' defined but not used The warning is seen if the driver is built into the kernel (not as module). Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/i5k_amb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 937983407e2..c4c40be0edb 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -497,12 +497,14 @@ static unsigned long chipset_ids[] = { 0 }; +#ifdef MODULE static struct pci_device_id i5k_amb_ids[] __devinitdata = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, { 0, } }; MODULE_DEVICE_TABLE(pci, i5k_amb_ids); +#endif static int __devinit i5k_amb_probe(struct platform_device *pdev) { -- cgit v1.2.3-70-g09d2 From 32292f49f9683622ad0fb95a8c754910121e7b16 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 18 Nov 2010 21:06:45 -0800 Subject: hwmon: (lis3lv02d_i2c) Fix compile warnings This commit fixes the following compile warnings. From v2.6.37-rc2/m68k/m68k-allmodconfig, v2.6.37-rc2/powerpc/powerpc-randconfig: drivers/hwmon/lis3lv02d_i2c.c:222: warning: 'lis3_i2c_runtime_suspend' defined but not used drivers/hwmon/lis3lv02d_i2c.c:231: warning: 'lis3_i2c_runtime_resume' defined but not used Seen if CONFIG_PM_RUNTIME is not set. From v2.6.37-rc2/sh4/sh-allyesconfig: drivers/hwmon/lis3lv02d_i2c.c:191: warning: 'lis3lv02d_i2c_suspend' defined but not used drivers/hwmon/lis3lv02d_i2c.c:201: warning: 'lis3lv02d_i2c_resume' defined but not used Seen if CONFIG_PM is set but CONFIG_PM_SLEEP is not. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lis3lv02d_i2c.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index 9f4bae07f71..8853afce85c 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c @@ -186,7 +186,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int lis3lv02d_i2c_suspend(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); @@ -213,12 +213,9 @@ static int lis3lv02d_i2c_resume(struct device *dev) return 0; } -#else -#define lis3lv02d_i2c_suspend NULL -#define lis3lv02d_i2c_resume NULL -#define lis3lv02d_i2c_shutdown NULL -#endif +#endif /* CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM_RUNTIME static int lis3_i2c_runtime_suspend(struct device *dev) { struct i2c_client *client = container_of(dev, struct i2c_client, dev); @@ -236,6 +233,7 @@ static int lis3_i2c_runtime_resume(struct device *dev) lis3lv02d_poweron(lis3); return 0; } +#endif /* CONFIG_PM_RUNTIME */ static const struct i2c_device_id lis3lv02d_id[] = { {"lis3lv02d", 0 }, -- cgit v1.2.3-70-g09d2 From e476a5a41ad67d0e2b4a652820c49a3923eb936b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 23 Nov 2010 17:10:24 +0100 Subject: wireless: b43: fix error path in SDIO Fix unbalanced call to sdio_release_host() on the error path. Signed-off-by: Guennadi Liakhovetski Acked-by: Larry Finger Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/b43/sdio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 9a55338d957..09e2dfd7b17 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func, err_free_ssb: kfree(sdio); err_disable_func: + sdio_claim_host(func); sdio_disable_func(func); err_release_host: sdio_release_host(func); -- cgit v1.2.3-70-g09d2 From bcf50e2775bbc3101932d8e4ab8c7902aa4163b4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 21 Nov 2010 22:07:12 +0000 Subject: drm/i915: Handle pagefaults in execbuffer user relocations Currently if we hit a pagefault when applying a user relocation for the execbuffer, we bail and return EFAULT to the application. Instead, we need to unwind, drop the dev->struct_mutex, copy all the relocation entries to a vmalloc array (to avoid any potential circular deadlocks when resolving the pagefault), retake the mutex and then apply the relocations. Afterwards, we need to again drop the lock and copy the vmalloc array back to userspace. v2: Incorporate feedback from Daniel Vetter. Reported-by: Daniel Vetter Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 461 +++++++++++++++++++++++++--------------- 1 file changed, 293 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bc416459005..92b097dbe4f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3254,192 +3254,230 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, return 0; } -/** - * Pin an object to the GTT and evaluate the relocations landing in it. - */ static int -i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, - struct drm_i915_gem_exec_object2 *entry) +i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry, + struct drm_i915_gem_relocation_entry *reloc) { struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_relocation_entry __user *user_relocs; - struct drm_gem_object *target_obj = NULL; - uint32_t target_handle = 0; - int i, ret = 0; + struct drm_gem_object *target_obj; + uint32_t target_offset; + int ret = -EINVAL; - user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; - for (i = 0; i < entry->relocation_count; i++) { - struct drm_i915_gem_relocation_entry reloc; - uint32_t target_offset; + target_obj = drm_gem_object_lookup(dev, file_priv, + reloc->target_handle); + if (target_obj == NULL) + return -ENOENT; - if (__copy_from_user_inatomic(&reloc, - user_relocs+i, - sizeof(reloc))) { - ret = -EFAULT; - break; - } + target_offset = to_intel_bo(target_obj)->gtt_offset; - if (reloc.target_handle != target_handle) { - drm_gem_object_unreference(target_obj); +#if WATCH_RELOC + DRM_INFO("%s: obj %p offset %08x target %d " + "read %08x write %08x gtt %08x " + "presumed %08x delta %08x\n", + __func__, + obj, + (int) reloc->offset, + (int) reloc->target_handle, + (int) reloc->read_domains, + (int) reloc->write_domain, + (int) target_offset, + (int) reloc->presumed_offset, + reloc->delta); +#endif - target_obj = drm_gem_object_lookup(dev, file_priv, - reloc.target_handle); - if (target_obj == NULL) { - ret = -ENOENT; - break; - } + /* The target buffer should have appeared before us in the + * exec_object list, so it should have a GTT space bound by now. + */ + if (target_offset == 0) { + DRM_ERROR("No GTT space found for object %d\n", + reloc->target_handle); + goto err; + } - target_handle = reloc.target_handle; - } - target_offset = to_intel_bo(target_obj)->gtt_offset; + /* Validate that the target is in a valid r/w GPU domain */ + if (reloc->write_domain & (reloc->write_domain - 1)) { + DRM_ERROR("reloc with multiple write domains: " + "obj %p target %d offset %d " + "read %08x write %08x", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->read_domains, + reloc->write_domain); + goto err; + } + if (reloc->write_domain & I915_GEM_DOMAIN_CPU || + reloc->read_domains & I915_GEM_DOMAIN_CPU) { + DRM_ERROR("reloc with read/write CPU domains: " + "obj %p target %d offset %d " + "read %08x write %08x", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->read_domains, + reloc->write_domain); + goto err; + } + if (reloc->write_domain && target_obj->pending_write_domain && + reloc->write_domain != target_obj->pending_write_domain) { + DRM_ERROR("Write domain conflict: " + "obj %p target %d offset %d " + "new %08x old %08x\n", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->write_domain, + target_obj->pending_write_domain); + goto err; + } -#if WATCH_RELOC - DRM_INFO("%s: obj %p offset %08x target %d " - "read %08x write %08x gtt %08x " - "presumed %08x delta %08x\n", - __func__, - obj, - (int) reloc.offset, - (int) reloc.target_handle, - (int) reloc.read_domains, - (int) reloc.write_domain, - (int) target_offset, - (int) reloc.presumed_offset, - reloc.delta); -#endif + target_obj->pending_read_domains |= reloc->read_domains; + target_obj->pending_write_domain |= reloc->write_domain; - /* The target buffer should have appeared before us in the - * exec_object list, so it should have a GTT space bound by now. - */ - if (target_offset == 0) { - DRM_ERROR("No GTT space found for object %d\n", - reloc.target_handle); - ret = -EINVAL; - break; - } + /* If the relocation already has the right value in it, no + * more work needs to be done. + */ + if (target_offset == reloc->presumed_offset) + goto out; - /* Validate that the target is in a valid r/w GPU domain */ - if (reloc.write_domain & (reloc.write_domain - 1)) { - DRM_ERROR("reloc with multiple write domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc.target_handle, - (int) reloc.offset, - reloc.read_domains, - reloc.write_domain); - ret = -EINVAL; - break; - } - if (reloc.write_domain & I915_GEM_DOMAIN_CPU || - reloc.read_domains & I915_GEM_DOMAIN_CPU) { - DRM_ERROR("reloc with read/write CPU domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc.target_handle, - (int) reloc.offset, - reloc.read_domains, - reloc.write_domain); - ret = -EINVAL; - break; - } - if (reloc.write_domain && target_obj->pending_write_domain && - reloc.write_domain != target_obj->pending_write_domain) { - DRM_ERROR("Write domain conflict: " - "obj %p target %d offset %d " - "new %08x old %08x\n", - obj, reloc.target_handle, - (int) reloc.offset, - reloc.write_domain, - target_obj->pending_write_domain); - ret = -EINVAL; - break; - } + /* Check that the relocation address is valid... */ + if (reloc->offset > obj->base.size - 4) { + DRM_ERROR("Relocation beyond object bounds: " + "obj %p target %d offset %d size %d.\n", + obj, reloc->target_handle, + (int) reloc->offset, + (int) obj->base.size); + goto err; + } + if (reloc->offset & 3) { + DRM_ERROR("Relocation not 4-byte aligned: " + "obj %p target %d offset %d.\n", + obj, reloc->target_handle, + (int) reloc->offset); + goto err; + } - target_obj->pending_read_domains |= reloc.read_domains; - target_obj->pending_write_domain |= reloc.write_domain; + /* and points to somewhere within the target object. */ + if (reloc->delta >= target_obj->size) { + DRM_ERROR("Relocation beyond target object bounds: " + "obj %p target %d delta %d size %d.\n", + obj, reloc->target_handle, + (int) reloc->delta, + (int) target_obj->size); + goto err; + } - /* If the relocation already has the right value in it, no - * more work needs to be done. - */ - if (target_offset == reloc.presumed_offset) - continue; + reloc->delta += target_offset; + if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { + uint32_t page_offset = reloc->offset & ~PAGE_MASK; + char *vaddr; - /* Check that the relocation address is valid... */ - if (reloc.offset > obj->base.size - 4) { - DRM_ERROR("Relocation beyond object bounds: " - "obj %p target %d offset %d size %d.\n", - obj, reloc.target_handle, - (int) reloc.offset, (int) obj->base.size); - ret = -EINVAL; - break; - } - if (reloc.offset & 3) { - DRM_ERROR("Relocation not 4-byte aligned: " - "obj %p target %d offset %d.\n", - obj, reloc.target_handle, - (int) reloc.offset); - ret = -EINVAL; - break; - } + vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]); + *(uint32_t *)(vaddr + page_offset) = reloc->delta; + kunmap_atomic(vaddr); + } else { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t __iomem *reloc_entry; + void __iomem *reloc_page; - /* and points to somewhere within the target object. */ - if (reloc.delta >= target_obj->size) { - DRM_ERROR("Relocation beyond target object bounds: " - "obj %p target %d delta %d size %d.\n", - obj, reloc.target_handle, - (int) reloc.delta, (int) target_obj->size); - ret = -EINVAL; - break; - } + ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1); + if (ret) + goto err; - reloc.delta += target_offset; - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { - uint32_t page_offset = reloc.offset & ~PAGE_MASK; - char *vaddr; + /* Map the page containing the relocation we're going to perform. */ + reloc->offset += obj->gtt_offset; + reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + reloc->offset & PAGE_MASK); + reloc_entry = (uint32_t __iomem *) + (reloc_page + (reloc->offset & ~PAGE_MASK)); + iowrite32(reloc->delta, reloc_entry); + io_mapping_unmap_atomic(reloc_page); + } - vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]); - *(uint32_t *)(vaddr + page_offset) = reloc.delta; - kunmap_atomic(vaddr); - } else { - uint32_t __iomem *reloc_entry; - void __iomem *reloc_page; + /* and update the user's relocation entry */ + reloc->presumed_offset = target_offset; - ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1); - if (ret) - break; +out: + ret = 0; +err: + drm_gem_object_unreference(target_obj); + return ret; +} - /* Map the page containing the relocation we're going to perform. */ - reloc.offset += obj->gtt_offset; - reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc.offset & PAGE_MASK); - reloc_entry = (uint32_t __iomem *) - (reloc_page + (reloc.offset & ~PAGE_MASK)); - iowrite32(reloc.delta, reloc_entry); - io_mapping_unmap_atomic(reloc_page); - } +static int +i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry) +{ + struct drm_i915_gem_relocation_entry __user *user_relocs; + int i, ret; + + user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; + for (i = 0; i < entry->relocation_count; i++) { + struct drm_i915_gem_relocation_entry reloc; + + if (__copy_from_user_inatomic(&reloc, + user_relocs+i, + sizeof(reloc))) + return -EFAULT; + + ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc); + if (ret) + return ret; - /* and update the user's relocation entry */ - reloc.presumed_offset = target_offset; if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, - &reloc.presumed_offset, - sizeof(reloc.presumed_offset))) { - ret = -EFAULT; - break; - } + &reloc.presumed_offset, + sizeof(reloc.presumed_offset))) + return -EFAULT; } - drm_gem_object_unreference(target_obj); - return ret; + return 0; +} + +static int +i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry, + struct drm_i915_gem_relocation_entry *relocs) +{ + int i, ret; + + for (i = 0; i < entry->relocation_count; i++) { + ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]); + if (ret) + return ret; + } + + return 0; +} + +static int +i915_gem_execbuffer_relocate(struct drm_device *dev, + struct drm_file *file, + struct drm_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; + ret = i915_gem_execbuffer_relocate_object(obj, file, + &exec_list[i]); + if (ret) + return ret; + } + + return 0; } static int -i915_gem_execbuffer_pin(struct drm_device *dev, - struct drm_file *file, - struct drm_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) +i915_gem_execbuffer_reserve(struct drm_device *dev, + struct drm_file *file, + struct drm_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) { struct drm_i915_private *dev_priv = dev->dev_private; int ret, i, retry; @@ -3501,6 +3539,87 @@ i915_gem_execbuffer_pin(struct drm_device *dev, return 0; } +static int +i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + struct drm_file *file, + struct drm_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) +{ + struct drm_i915_gem_relocation_entry *reloc; + int i, total, ret; + + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + obj->in_execbuffer = false; + } + + mutex_unlock(&dev->struct_mutex); + + total = 0; + for (i = 0; i < count; i++) + total += exec_list[i].relocation_count; + + reloc = drm_malloc_ab(total, sizeof(*reloc)); + if (reloc == NULL) { + mutex_lock(&dev->struct_mutex); + return -ENOMEM; + } + + total = 0; + for (i = 0; i < count; i++) { + struct drm_i915_gem_relocation_entry __user *user_relocs; + + user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; + + if (copy_from_user(reloc+total, user_relocs, + exec_list[i].relocation_count * + sizeof(*reloc))) { + ret = -EFAULT; + mutex_lock(&dev->struct_mutex); + goto err; + } + + total += exec_list[i].relocation_count; + } + + ret = i915_mutex_lock_interruptible(dev); + if (ret) { + mutex_lock(&dev->struct_mutex); + goto err; + } + + ret = i915_gem_execbuffer_reserve(dev, file, + object_list, exec_list, + count); + if (ret) + goto err; + + total = 0; + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; + ret = i915_gem_execbuffer_relocate_object_slow(obj, file, + &exec_list[i], + reloc + total); + if (ret) + goto err; + + total += exec_list[i].relocation_count; + } + + /* Leave the user relocations as are, this is the painfully slow path, + * and we want to avoid the complication of dropping the lock whilst + * having buffers reserved in the aperture and so causing spurious + * ENOSPC for random operations. + */ + +err: + drm_free_large(reloc); + return ret; +} + static int i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, struct drm_file *file, @@ -3781,18 +3900,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } /* Move the objects en-masse into the GTT, evicting if necessary. */ - ret = i915_gem_execbuffer_pin(dev, file, - object_list, exec_list, - args->buffer_count); + ret = i915_gem_execbuffer_reserve(dev, file, + object_list, exec_list, + args->buffer_count); if (ret) goto err; /* The objects are in their final locations, apply the relocations. */ - for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); - obj->base.pending_read_domains = 0; - obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]); + ret = i915_gem_execbuffer_relocate(dev, file, + object_list, exec_list, + args->buffer_count); + if (ret) { + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(dev, file, + object_list, + exec_list, + args->buffer_count); + BUG_ON(!mutex_is_locked(&dev->struct_mutex)); + } if (ret) goto err; } -- cgit v1.2.3-70-g09d2 From 5d61b718ec23694a87b2c5c590809c12453a1833 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 23 Nov 2010 22:19:08 +0000 Subject: SCSI: arm fas216: fix missing ';' f281233 (SCSI host lock push-down) broke the fas216 build: drivers/scsi/arm/fas216.h: In function 'fas216_noqueue_command': drivers/scsi/arm/fas216.h:354: error: storage class specified for parameter 'fas216_intr' drivers/scsi/arm/fas216.h:356: error: storage class specified for parameter 'fas216_remove' ... Fix it. Signed-off-by: Russell King --- drivers/scsi/arm/fas216.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 377cfb72cc6..f30f8d659dc 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -345,7 +345,7 @@ extern int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt); * : SCpnt - Command to queue * Returns : 0 - success, else error */ -extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *) +extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *); /* Function: irqreturn_t fas216_intr (FAS216_Info *info) * Purpose : handle interrupts from the interface to progress a command -- cgit v1.2.3-70-g09d2 From 0c1dab89ee0e483f382391d6aec77db4affb0931 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 22:37:01 +0000 Subject: drm/i915/sdvo: Always fallback to querying the shared DDC line On a few devices, like the Mac Mini, the CRT DDC pins are shared between the analog connector and the digital connector. In this scenario, rely on the EDID to determine if a digital panel is connected to the digital connector. Reported-and-tested-by: Tino Keitel Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_sdvo.c | 51 +++++---------------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 843182528b7..bf643100dec 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1296,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector) return drm_get_edid(connector, &sdvo->ddc); } -static struct drm_connector * -intel_find_analog_connector(struct drm_device *dev) -{ - struct drm_connector *connector; - struct intel_sdvo *encoder; - - list_for_each_entry(encoder, - &dev->mode_config.encoder_list, - base.base.head) { - if (encoder->base.type == INTEL_OUTPUT_ANALOG) { - list_for_each_entry(connector, - &dev->mode_config.connector_list, - head) { - if (&encoder->base == - intel_attached_encoder(connector)) - return connector; - } - } - } - - return NULL; -} - -static int -intel_analog_is_connected(struct drm_device *dev) -{ - struct drm_connector *analog_connector; - - analog_connector = intel_find_analog_connector(dev); - if (!analog_connector) - return false; - - if (analog_connector->funcs->detect(analog_connector, false) == - connector_status_disconnected) - return false; - - return true; -} - /* Mac mini hack -- use the same DDC as the analog connector */ static struct edid * intel_sdvo_get_analog_edid(struct drm_connector *connector) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - if (!intel_analog_is_connected(connector->dev)) - return NULL; - - return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); + return drm_get_edid(connector, + &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); } enum drm_connector_status @@ -1475,8 +1434,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) edid = intel_sdvo_get_analog_edid(connector); if (edid != NULL) { - drm_mode_connector_update_edid_property(connector, edid); - drm_add_edid_modes(connector, edid); + if (edid->input & DRM_EDID_INPUT_DIGITAL) { + drm_mode_connector_update_edid_property(connector, edid); + drm_add_edid_modes(connector, edid); + } connector->display_info.raw_edid = NULL; kfree(edid); } -- cgit v1.2.3-70-g09d2 From 7ae4b866f86f9ab7b99484b56dd303a860ad1cc9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 4 Nov 2010 14:24:24 +0200 Subject: virtio: return correct capacity to users We can't rely on indirect buffers for capacity calculations because they need a memory allocation which might fail. In particular, virtio_net can get into this situation under stress, and it drops packets and performs badly. So return the number of buffers we can guarantee users. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell Reported-By: Krishna Kumar2 --- drivers/virtio/virtio_ring.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 1475ed6b575..cc2f73e0347 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -230,9 +230,6 @@ add_head: pr_debug("Added buffer head %i to %p\n", head, vq); END_USE(vq); - /* If we're indirect, we can fit many (assuming not OOM). */ - if (vq->indirect) - return vq->num_free ? vq->vring.num : 0; return vq->num_free; } EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); -- cgit v1.2.3-70-g09d2 From 22e132ff2645aab1e1a25c45e9544a39ae1dc106 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 6 Nov 2010 10:06:50 +0100 Subject: Char: virtio_console, fix memory leak Stanse found that in init_vqs, memory is leaked under certain circumstanses (the fail path order is incorrect). Fix that by checking allocations in one turn and free all of them at once if some fails (some may be NULL, but this is OK). Signed-off-by: Jiri Slaby Cc: Amit Shah Cc: virtualization@lists.linux-foundation.org Cc: Greg Kroah-Hartman Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 6c1b676643a..896a2ced1d2 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1547,31 +1547,16 @@ static int init_vqs(struct ports_device *portdev) nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); - if (!vqs) { - err = -ENOMEM; - goto fail; - } io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL); - if (!io_callbacks) { - err = -ENOMEM; - goto free_vqs; - } io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL); - if (!io_names) { - err = -ENOMEM; - goto free_callbacks; - } portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), GFP_KERNEL); - if (!portdev->in_vqs) { - err = -ENOMEM; - goto free_names; - } portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), GFP_KERNEL); - if (!portdev->out_vqs) { + if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs || + !portdev->out_vqs) { err = -ENOMEM; - goto free_invqs; + goto free; } /* @@ -1605,7 +1590,7 @@ static int init_vqs(struct ports_device *portdev) io_callbacks, (const char **)io_names); if (err) - goto free_outvqs; + goto free; j = 0; portdev->in_vqs[0] = vqs[0]; @@ -1621,23 +1606,19 @@ static int init_vqs(struct ports_device *portdev) portdev->out_vqs[i] = vqs[j + 1]; } } - kfree(io_callbacks); kfree(io_names); + kfree(io_callbacks); kfree(vqs); return 0; -free_names: - kfree(io_names); -free_callbacks: - kfree(io_callbacks); -free_outvqs: +free: kfree(portdev->out_vqs); -free_invqs: kfree(portdev->in_vqs); -free_vqs: + kfree(io_names); + kfree(io_callbacks); kfree(vqs); -fail: + return err; } -- cgit v1.2.3-70-g09d2 From be6528b2e58d92ef2ffed6f130e2d42bb85dbf29 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 9 Nov 2010 22:20:29 -0800 Subject: virtio: fix format of sysfs driver/vendor files The sysfs files for virtio produce the wrong format and are missing the required newline. The output for virtio bus vendor/device should have the same format as the corresponding entries for PCI devices. Although this technically changes the ABI for sysfs, these files were broken to start with! Signed-off-by: Stephen Hemminger Signed-off-by: Rusty Russell --- drivers/virtio/virtio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 3a43ebf83a4..efb35aa8309 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -9,19 +9,19 @@ static ssize_t device_show(struct device *_d, struct device_attribute *attr, char *buf) { struct virtio_device *dev = container_of(_d,struct virtio_device,dev); - return sprintf(buf, "%hu", dev->id.device); + return sprintf(buf, "0x%04x\n", dev->id.device); } static ssize_t vendor_show(struct device *_d, struct device_attribute *attr, char *buf) { struct virtio_device *dev = container_of(_d,struct virtio_device,dev); - return sprintf(buf, "%hu", dev->id.vendor); + return sprintf(buf, "0x%04x\n", dev->id.vendor); } static ssize_t status_show(struct device *_d, struct device_attribute *attr, char *buf) { struct virtio_device *dev = container_of(_d,struct virtio_device,dev); - return sprintf(buf, "0x%08x", dev->config->get_status(dev)); + return sprintf(buf, "0x%08x\n", dev->config->get_status(dev)); } static ssize_t modalias_show(struct device *_d, struct device_attribute *attr, char *buf) -- cgit v1.2.3-70-g09d2 From c26a44ed1e552aaa1d4ceb71842002d235fe98d7 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Wed, 24 Nov 2010 16:36:17 +1100 Subject: md: fix return value of rdev_size_change() When trying to grow an array by enlarging component devices, rdev_size_store() expects the return value of rdev_size_change() to be in sectors, but the actual value is returned in KBs. This functionality was broken by commit dd8ac336c13fd8afdb082ebacb1cddd5cf727889 so this patch is suitable for any kernel since 2.6.30. Cc: stable@kernel.org Signed-off-by: Justin Maggard Signed-off-by: NeilBrown --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 324a3663fcd..7b9e229a05e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1337,7 +1337,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors / 2; /* kB for sysfs */ + return num_sectors; } @@ -1704,7 +1704,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors / 2; /* kB for sysfs */ + return num_sectors; } static struct super_type super_types[] = { -- cgit v1.2.3-70-g09d2 From 8f9e0ee38f75d4740daa9e42c8af628d33d19a02 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 24 Nov 2010 16:39:46 +1100 Subject: md/raid1: really fix recovery looping when single good device fails. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 4044ba58dd15cb01797c4fd034f39ef4a75f7cc3 supposedly fixed a problem where if a raid1 with just one good device gets a read-error during recovery, the recovery would abort and immediately restart in an infinite loop. However it depended on raid1_remove_disk removing the spare device from the array. But that does not happen in this case. So add a test so that in the 'recovery_disabled' case, the device will be removed. This suitable for any kernel since 2.6.29 which is when recovery_disabled was introduced. Cc: stable@kernel.org Reported-by: Sebastian Färber Signed-off-by: NeilBrown --- drivers/md/raid1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 45f8324196e..845cf95b612 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1161,6 +1161,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) * is not possible. */ if (!test_bit(Faulty, &rdev->flags) && + !mddev->recovery_disabled && mddev->degraded < conf->raid_disks) { err = -EBUSY; goto abort; -- cgit v1.2.3-70-g09d2 From be20e6c67b6c6024c19094d3447f144d118733b0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 24 Nov 2010 16:40:33 +1100 Subject: md: Call blk_queue_flush() to establish flush/fua support Before 2.6.37, the md layer had a mechanism for catching I/Os with the barrier flag set, and translating the barrier into barriers for all the underlying devices. With 2.6.37, I/O barriers have become plain old flushes, and the md code was updated to reflect this. However, one piece was left out -- the md layer does not tell the block layer that it supports flushes or FUA access at all, which results in md silently dropping flush requests. Since the support already seems there, just add this one piece of bookkeeping. Signed-off-by: Darrick J. Wong Signed-off-by: NeilBrown --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 7b9e229a05e..84c46a16192 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4338,6 +4338,8 @@ static int md_alloc(dev_t dev, char *name) if (mddev->kobj.sd && sysfs_create_group(&mddev->kobj, &md_bitmap_group)) printk(KERN_DEBUG "pointless warning\n"); + + blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); abort: mutex_unlock(&disks_mutex); if (!error && mddev->kobj.sd) { -- cgit v1.2.3-70-g09d2 From 8807236b1895b3aca022180cb9906022965344ad Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 19 Nov 2010 21:58:43 +0000 Subject: sisfb: delete obsolete PCI ROM bug workaround Delete a workaround for a PCI ROM bug that has been fixed ages ago by the commit 761a3ac08c63718dacde12aaf0ec6d6760e8c2b7. Signed-off-by: Aaro Koskinen Cc: Thomas Winischhofer Signed-off-by: Paul Mundt --- drivers/video/sis/sis_main.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 3dde12b0ab0..1073b70dd85 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -4114,14 +4114,6 @@ sisfb_find_rom(struct pci_dev *pdev) if(sisfb_check_rom(rom_base, ivideo)) { if((myrombase = vmalloc(65536))) { - - /* Work around bug in pci/rom.c: Folks forgot to check - * whether the size retrieved from the BIOS image eventually - * is larger than the mapped size - */ - if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize) - romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE); - memcpy_fromio(myrombase, rom_base, (romsize > 65536) ? 65536 : romsize); } -- cgit v1.2.3-70-g09d2 From f3fff7359415f3e6331fa727ab27e9a1556ee7e7 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 19 Nov 2010 21:58:44 +0000 Subject: sisfb: delete fallback code for pci_map_rom() If pci_map_rom() fails, there is some fallback code that basically duplicates pci_map_rom() on non-x86 platforms. No point in that. Signed-off-by: Aaro Koskinen Cc: Thomas Winischhofer Signed-off-by: Paul Mundt --- drivers/video/sis/sis_main.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 1073b70dd85..7feb6992c7c 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -4147,23 +4147,6 @@ sisfb_find_rom(struct pci_dev *pdev) } -#else - - pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp); - pci_write_config_dword(pdev, PCI_ROM_ADDRESS, - (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE); - - rom_base = ioremap(ivideo->video_base, 65536); - if(rom_base) { - if(sisfb_check_rom(rom_base, ivideo)) { - if((myrombase = vmalloc(65536))) - memcpy_fromio(myrombase, rom_base, 65536); - } - iounmap(rom_base); - } - - pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp); - #endif return myrombase; -- cgit v1.2.3-70-g09d2 From e7d828ab91c95e9fdc85f5167f236a8c85fb2445 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 19 Nov 2010 21:58:45 +0000 Subject: sisfb: delete dead SIS_XORG_XF86 code Delete code for compiling the driver for X.org/XFree86. The development has forked, so there is no point keeping this code in the tree. Signed-off-by: Aaro Koskinen Cc: Thomas Winischhofer Signed-off-by: Paul Mundt --- drivers/video/sis/init.c | 537 ------------------------------------------- drivers/video/sis/init.h | 40 ---- drivers/video/sis/init301.c | 162 ------------- drivers/video/sis/init301.h | 14 -- drivers/video/sis/osdef.h | 20 -- drivers/video/sis/vgatypes.h | 9 - drivers/video/sis/vstruct.h | 6 - 7 files changed, 788 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c index c311ad3c368..53e30ea5650 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c @@ -340,9 +340,7 @@ SiSInitPtr(struct SiS_Private *SiS_Pr) /* HELPER: Get ModeID */ /*********************************************/ -#ifndef SIS_XORG_XF86 static -#endif unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, bool FSTN, int LCDwidth, int LCDheight) @@ -2999,11 +2997,6 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho SiS_Pr->SiS_SelectCRT2Rate = 0; SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); -#ifdef SIS_XORG_XF86 - xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n", - SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo); -#endif - if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; @@ -3202,74 +3195,12 @@ SiS_Handle760(struct SiS_Private *SiS_Pr) #endif } -/*********************************************/ -/* X.org/XFree86: SET SCREEN PITCH */ -/*********************************************/ - -#ifdef SIS_XORG_XF86 -static void -SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned short HDisplay = pSiS->scrnPitch >> 3; - - SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF)); - SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8)); -} - -static void -SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned short HDisplay = pSiS->scrnPitch2 >> 3; - - /* Unlock CRT2 */ - if(pSiS->VGAEngine == SIS_315_VGA) - SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01); - else - SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01); - - SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF)); - SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8)); -} - -static void -SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - bool isslavemode = false; - - if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) && - ( ((pSiS->VGAEngine == SIS_300_VGA) && - (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || - ((pSiS->VGAEngine == SIS_315_VGA) && - (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) { - isslavemode = true; - } - - /* We need to set pitch for CRT1 if bridge is in slave mode, too */ - if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) { - SiS_SetPitchCRT1(SiS_Pr, pScrn); - } - /* We must not set the pitch for CRT2 if bridge is in slave mode */ - if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) { - SiS_SetPitchCRT2(SiS_Pr, pScrn); - } -} -#endif - /*********************************************/ /* SiSSetMode() */ /*********************************************/ -#ifdef SIS_XORG_XF86 -/* We need pScrn for setting the pitch correctly */ -bool -SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch) -#else bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) -#endif { SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; unsigned short RealModeNo, ModeIdIndex; @@ -3301,9 +3232,6 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_GetSysFlags(SiS_Pr); SiS_Pr->SiS_VGAINFO = 0x11; -#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)) - if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); -#endif #ifdef SIS_LINUX_KERNEL KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); @@ -3424,18 +3352,6 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) } } -#ifdef SIS_XORG_XF86 - if(pScrn) { - /* SetPitch: Adapt to virtual size & position */ - if((ModeNo > 0x13) && (dosetpitch)) { - SiS_SetPitch(SiS_Pr, pScrn); - } - - /* Backup/Set ModeNo in BIOS scratch area */ - SiS_GetSetModeID(pScrn, ModeNo); - } -#endif - SiS_CloseCRTC(SiS_Pr); SiS_Handle760(SiS_Pr); @@ -3448,400 +3364,6 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) return true; } -/*********************************************/ -/* X.org/XFree86: SiSBIOSSetMode() */ -/* for non-Dual-Head mode */ -/*********************************************/ - -#ifdef SIS_XORG_XF86 -bool -SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned short ModeNo = 0; - - SiS_Pr->UseCustomMode = false; - - if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", - SiS_Pr->CHDisplay, - (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : - (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : - SiS_Pr->CVDisplay))); - - } else { - - /* Don't need vbflags here; checks done earlier */ - ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); - if(!ModeNo) return false; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); - - } - - return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true)); -} - -/*********************************************/ -/* X.org/XFree86: SiSBIOSSetModeCRT2() */ -/* for Dual-Head modes */ -/*********************************************/ - -bool -SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom) -{ - SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; - SISPtr pSiS = SISPTR(pScrn); -#ifdef SISDUALHEAD - SISEntPtr pSiSEnt = pSiS->entityPrivate; -#endif - unsigned short ModeIdIndex; - unsigned short ModeNo = 0; - unsigned char backupreg = 0; - - SiS_Pr->UseCustomMode = false; - - /* Remember: Custom modes for CRT2 are ONLY supported - * -) on the 30x/B/C, and - * -) if CRT2 is LCD or VGA, or CRT1 is LCDA - */ - - if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - - ModeNo = 0xfe; - - } else { - - ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); - if(!ModeNo) return false; - - } - - SiSRegInit(SiS_Pr, BaseAddr); - SiSInitPtr(SiS_Pr); - SiS_GetSysFlags(SiS_Pr); -#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) - SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); -#else - SiS_Pr->SiS_VGAINFO = 0x11; -#endif - - SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); - - SiSInitPCIetc(SiS_Pr); - SiSSetLVDSetc(SiS_Pr); - SiSDetermineROMUsage(SiS_Pr); - - /* Save mode info so we can set it from within SetMode for CRT1 */ -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - pSiSEnt->CRT2ModeNo = ModeNo; - pSiSEnt->CRT2DMode = mode; - pSiSEnt->CRT2IsCustom = IsCustom; - pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); - pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); - pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); - pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); -#if 0 - /* We can't set CRT2 mode before CRT1 mode is set - says who...? */ - if(pSiSEnt->CRT1ModeNo == -1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting CRT2 mode delayed until after setting CRT1 mode\n"); - return true; - } -#endif - pSiSEnt->CRT2ModeSet = true; - } -#endif - - if(SiS_Pr->UseCustomMode) { - - unsigned short temptemp = SiS_Pr->CVDisplay; - - if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; - else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting custom mode %dx%d on CRT2\n", - SiS_Pr->CHDisplay, temptemp); - - } else { - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting standard mode 0x%x on CRT2\n", ModeNo); - - } - - SiS_UnLockCRT2(SiS_Pr); - - if(!SiS_Pr->UseCustomMode) { - if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false; - } else { - ModeIdIndex = 0; - } - - SiS_GetVBType(SiS_Pr); - - SiS_InitVB(SiS_Pr); - if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { - if(SiS_Pr->ChipType >= SIS_315H) { - SiS_ResetVB(SiS_Pr); - SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); - SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); - backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); - } else { - backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); - } - } - - /* Get VB information (connectors, connected devices) */ - if(!SiS_Pr->UseCustomMode) { - SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1); - } else { - /* If this is a custom mode, we don't check the modeflag for CRT2Mode */ - SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); - } - SiS_SetYPbPr(SiS_Pr); - SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); - SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); - SiS_SetLowModeTest(SiS_Pr, ModeNo); - - SiS_ResetSegmentRegisters(SiS_Pr); - - /* Set mode on CRT2 */ - if( (SiS_Pr->SiS_VBType & VB_SISVB) || - (SiS_Pr->SiS_IF_DEF_LVDS == 1) || - (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || - (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { - SiS_SetCRT2Group(SiS_Pr, ModeNo); - } - - SiS_StrangeStuff(SiS_Pr); - - SiS_DisplayOn(SiS_Pr); - SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); - - if(SiS_Pr->ChipType >= SIS_315H) { - if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { - if(!(SiS_IsDualEdge(SiS_Pr))) { - SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); - } - } - } - - if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { - if(SiS_Pr->ChipType >= SIS_315H) { - if(!SiS_Pr->SiS_ROMNew) { - if(SiS_IsVAMode(SiS_Pr)) { - SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); - } else { - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); - } - } - - SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); - - if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { - SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); - } - } else if((SiS_Pr->ChipType == SIS_630) || - (SiS_Pr->ChipType == SIS_730)) { - SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); - } - } - - /* SetPitch: Adapt to virtual size & position */ - SiS_SetPitchCRT2(SiS_Pr, pScrn); - - SiS_Handle760(SiS_Pr); - - return true; -} - -/*********************************************/ -/* X.org/XFree86: SiSBIOSSetModeCRT1() */ -/* for Dual-Head modes */ -/*********************************************/ - -bool -SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom) -{ - SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; - SISPtr pSiS = SISPTR(pScrn); - unsigned short ModeIdIndex, ModeNo = 0; - unsigned char backupreg = 0; -#ifdef SISDUALHEAD - SISEntPtr pSiSEnt = pSiS->entityPrivate; - unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0; - bool backupcustom; -#endif - - SiS_Pr->UseCustomMode = false; - - if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - - unsigned short temptemp = SiS_Pr->CVDisplay; - - if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; - else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting custom mode %dx%d on CRT1\n", - SiS_Pr->CHDisplay, temptemp); - ModeNo = 0xfe; - - } else { - - ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */ - if(!ModeNo) return false; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Setting standard mode 0x%x on CRT1\n", ModeNo); - } - - SiSInitPtr(SiS_Pr); - SiSRegInit(SiS_Pr, BaseAddr); - SiS_GetSysFlags(SiS_Pr); -#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) - SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); -#else - SiS_Pr->SiS_VGAINFO = 0x11; -#endif - - SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); - - SiSInitPCIetc(SiS_Pr); - SiSSetLVDSetc(SiS_Pr); - SiSDetermineROMUsage(SiS_Pr); - - SiS_UnLockCRT2(SiS_Pr); - - if(!SiS_Pr->UseCustomMode) { - if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false; - } else { - ModeIdIndex = 0; - } - - /* Determine VBType */ - SiS_GetVBType(SiS_Pr); - - SiS_InitVB(SiS_Pr); - if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { - if(SiS_Pr->ChipType >= SIS_315H) { - backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); - } else { - backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); - } - } - - /* Get VB information (connectors, connected devices) */ - /* (We don't care if the current mode is a CRT2 mode) */ - SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); - SiS_SetYPbPr(SiS_Pr); - SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); - SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); - SiS_SetLowModeTest(SiS_Pr, ModeNo); - - SiS_OpenCRTC(SiS_Pr); - - /* Set mode on CRT1 */ - SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); - if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { - SiS_SetCRT2Group(SiS_Pr, ModeNo); - } - - /* SetPitch: Adapt to virtual size & position */ - SiS_SetPitchCRT1(SiS_Pr, pScrn); - - SiS_HandleCRT1(SiS_Pr); - - SiS_StrangeStuff(SiS_Pr); - - SiS_CloseCRTC(SiS_Pr); - -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - pSiSEnt->CRT1ModeNo = ModeNo; - pSiSEnt->CRT1DMode = mode; - } -#endif - - if(SiS_Pr->UseCustomMode) { - SiS_Pr->CRT1UsesCustomMode = true; - SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; - SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; - } else { - SiS_Pr->CRT1UsesCustomMode = false; - } - - /* Reset CRT2 if changing mode on CRT1 */ -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - if(pSiSEnt->CRT2ModeNo != -1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "(Re-)Setting mode for CRT2\n"); - backupcustom = SiS_Pr->UseCustomMode; - backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); - backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); - backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); - backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); - if(SiS_Pr->SiS_VBType & VB_SISVB) { - /* Backup LUT-enable */ - if(pSiSEnt->CRT2ModeSet) { - backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08; - } - } - if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { - SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38); - } - - SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1, - pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom); - - SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35); - SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38); - if(SiS_Pr->SiS_VBType & VB_SISVB) { - SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d); - } - SiS_Pr->UseCustomMode = backupcustom; - } - } -#endif - - /* Warning: From here, the custom mode entries in SiS_Pr are - * possibly overwritten - */ - - SiS_DisplayOn(SiS_Pr); - SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); - - if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { - if(SiS_Pr->ChipType >= SIS_315H) { - SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); - } else if((SiS_Pr->ChipType == SIS_630) || - (SiS_Pr->ChipType == SIS_730)) { - SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); - } - } - - SiS_Handle760(SiS_Pr); - - /* Backup/Set ModeNo in BIOS scratch area */ - SiS_GetSetModeID(pScrn,ModeNo); - - return true; -} -#endif /* Linux_XF86 */ - #ifndef GETBITSTR #define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) #define GENMASK(mask) BITMASK(1?mask,0?mask) @@ -4054,33 +3576,11 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, if(modeflag & DoubleScanMode) tempax |= 0x80; SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", - SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, - SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, - SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); - xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", - SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], - SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], - SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], - SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); - xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", - SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], - SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], - SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], - SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); - xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); -#endif -#endif } void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, int yres, -#ifdef SIS_XORG_XF86 - DisplayModePtr current -#endif #ifdef SIS_LINUX_KERNEL struct fb_var_screeninfo *var, bool writeres #endif @@ -4127,19 +3627,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, D = B - F - C; -#ifdef SIS_XORG_XF86 - current->HDisplay = (E * 8); - current->HSyncStart = (E * 8) + (F * 8); - current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); - current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, - "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n", - A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE); -#else - (void)VBS; (void)HBS; (void)A; -#endif -#endif #ifdef SIS_LINUX_KERNEL if(writeres) var->xres = xres = E * 8; var->left_margin = D * 8; @@ -4192,24 +3679,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, D = B - F - C; -#ifdef SIS_XORG_XF86 - current->VDisplay = VDE + 1; - current->VSyncStart = VRS + 1; - current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1; - if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32; - current->VTotal = E + D + C + F; -#if 0 - current->VDisplay = E; - current->VSyncStart = E + D; - current->VSyncEnd = E + D + C; - current->VTotal = E + D + C + F; -#endif -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, - "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n", - A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE); -#endif -#endif #ifdef SIS_LINUX_KERNEL if(writeres) var->yres = yres = E; var->upper_margin = D; @@ -4224,12 +3693,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, * a negative D. The CRT controller does not * seem to like correcting HRE to 50) */ -#ifdef SIS_XORG_XF86 - current->HDisplay = 320; - current->HSyncStart = 328; - current->HSyncEnd = 376; - current->HTotal = 400; -#endif #ifdef SIS_LINUX_KERNEL var->left_margin = (400 - 376); var->right_margin = (328 - 320); diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index b96005c39c6..4a75c73e134 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h @@ -56,17 +56,6 @@ #include "osdef.h" #include "initdef.h" -#ifdef SIS_XORG_XF86 -#include "sis.h" -#define SIS_NEED_inSISREG -#define SIS_NEED_inSISREGW -#define SIS_NEED_inSISREGL -#define SIS_NEED_outSISREG -#define SIS_NEED_outSISREGW -#define SIS_NEED_outSISREGL -#include "sis_regs.h" -#endif - #ifdef SIS_LINUX_KERNEL #include "vgatypes.h" #include "vstruct.h" @@ -1521,10 +1510,6 @@ static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] = }; bool SiSInitPtr(struct SiS_Private *SiS_Pr); -#ifdef SIS_XORG_XF86 -unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, - int Depth, bool FSTN, int LCDwith, int LCDheight); -#endif unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, bool FSTN, unsigned short CustomT, int LCDwith, int LCDheight, @@ -1579,26 +1564,12 @@ unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2 unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index); #endif void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); -#ifdef SIS_XORG_XF86 -bool SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, - bool dosetpitch); -bool SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom); -bool SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom); -bool SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, - DisplayModePtr mode, bool IsCustom); -#endif #ifdef SIS_LINUX_KERNEL bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); #endif void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth); void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); -#ifdef SIS_XORG_XF86 -void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, - int yres, DisplayModePtr current); -#endif #ifdef SIS_LINUX_KERNEL void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, int yres, struct fb_var_screeninfo *var, bool writeres); @@ -1626,17 +1597,6 @@ extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short extern bool SiS_IsVAMode(struct SiS_Private *); extern bool SiS_IsDualEdge(struct SiS_Private *); -#ifdef SIS_XORG_XF86 -/* From other modules: */ -extern unsigned short SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned int VBFlags); -extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset, - unsigned char value); -extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); -extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned int VBFlags); -#endif - #ifdef SIS_LINUX_KERNEL #ifdef SIS300 extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg); diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index da33d801c22..a4b344e2dea 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c @@ -1166,12 +1166,6 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); #endif #endif -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", - SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); -#endif -#endif } /*********************************************/ @@ -1415,12 +1409,6 @@ SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short } SiS_Pr->SiS_VBInfo &= ~SetPALTV; - -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo); -#endif -#endif } /*********************************************/ @@ -1447,18 +1435,6 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) unsigned char *ROMAddr; unsigned short temp; -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", - SiS_Pr->PanelHT, SiS_Pr->PanelVT, - SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, - SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); -#endif -#endif - if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { SiS_Pr->SiS_NeedRomModeData = true; @@ -1480,18 +1456,6 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", - SiS_Pr->PanelHT, SiS_Pr->PanelVT, - SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, - SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, - SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); -#endif -#endif - } #endif } @@ -2192,11 +2156,6 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); #endif #endif -#ifdef SIS_XORG_XF86 - xf86DrvMsgVerb(0, X_PROBED, 4, - "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n", - SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag); -#endif } /*********************************************/ @@ -2410,12 +2369,6 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex); -#endif -#endif - return VCLKIndex; } @@ -3527,12 +3480,6 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex); -#endif -#endif - SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; @@ -3891,11 +3838,6 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr) ret = 1; } SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, 0, "Setting PWD %x\n", temp); -#endif -#endif } #endif return ret; @@ -5420,27 +5362,6 @@ SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned sho temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ - -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", - SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, - SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, - SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); - - xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", - SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], - SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], - SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], - SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); - xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", - SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], - SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], - SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], - SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); - xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); -#endif -#endif } /* Setup panel link @@ -7130,12 +7051,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx); -#endif -#endif - SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ @@ -7184,12 +7099,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short tempbx = SiS_Pr->CVSyncStart; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx); -#endif -#endif - SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ temp = (tempbx >> 4) & 0xF0; @@ -7201,12 +7110,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short temp |= (SiS_Pr->CVSyncEnd & 0x0f); } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f)); -#endif -#endif - SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); #ifdef SIS300 @@ -7245,12 +7148,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short tempax >>= 1; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx); -#endif -#endif - tempbx += bridgeoffset; SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ @@ -7276,12 +7173,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short tempbx += bridgeoffset; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx); -#endif -#endif - SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); @@ -7300,12 +7191,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short tempbx += bridgeoffset; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx); -#endif -#endif - SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ SiS_SetGroup2_Tail(SiS_Pr, ModeNo); @@ -8703,16 +8588,6 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES); - xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE); - xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE); - xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT); - xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT); -#endif -#endif - if(SiS_Pr->SiS_SetFlag & LowModeTests) { SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); } @@ -8923,11 +8798,6 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr) dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); if(!dataptr) return false; } -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Trumpion block success\n"); -#endif -#endif return true; } #endif @@ -9114,9 +8984,7 @@ SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, } /* Our own DDC functions */ -#ifndef SIS_XORG_XF86 static -#endif unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, @@ -9224,12 +9092,6 @@ SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, SiS_SetupDDCN(SiS_Pr); -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n", - SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp); -#endif -#endif return 0; } @@ -9292,11 +9154,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) SiS_SetSwitchDDC2(SiS_Pr); if(SiS_PrepareDDC(SiS_Pr)) { SiS_SetStop(SiS_Pr); -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n"); -#endif -#endif return 0xFFFF; } mask = 0xf0; @@ -9310,11 +9167,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) } else { failed = true; ret = 0xFFFF; -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n"); -#endif -#endif } } if(!failed) { @@ -9324,11 +9176,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) if(temp == value) ret = 0; else { ret = 0xFFFF; -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n"); -#endif -#endif if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { if(temp == 0x30) ret = 0; } @@ -9338,9 +9185,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) return ret; } -#ifndef SIS_XORG_XF86 static -#endif unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr) { @@ -9357,9 +9202,7 @@ SiS_ProbeDDC(struct SiS_Private *SiS_Pr) return flag; } -#ifndef SIS_XORG_XF86 static -#endif unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) { @@ -9606,11 +9449,6 @@ SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr) temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); if (!watchdog) { -#ifdef SIS_XORG_XF86 -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n"); -#endif -#endif return 0xFFFF; } SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index 51d99222375..c379dc7a997 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h @@ -56,11 +56,6 @@ #include "osdef.h" #include "initdef.h" -#ifdef SIS_XORG_XF86 -#include "sis.h" -#include "sis_regs.h" -#endif - #ifdef SIS_LINUX_KERNEL #include "vgatypes.h" #include "vstruct.h" @@ -412,21 +407,12 @@ unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, i unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer, unsigned int VBFlags2); -#ifdef SIS_XORG_XF86 -unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, - int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, - bool checkcr32, unsigned int VBFlags2); -unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); -unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, - unsigned char *buffer); -#else static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, unsigned int VBFlags2); static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer); -#endif static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr); static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr); static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr); diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h index 6ff8f988a1a..e24d21a7ae4 100644 --- a/drivers/video/sis/osdef.h +++ b/drivers/video/sis/osdef.h @@ -56,7 +56,6 @@ /* The choices are: */ #define SIS_LINUX_KERNEL /* Linux kernel framebuffer */ -#undef SIS_XORG_XF86 /* XFree86/X.org */ #ifdef OutPortByte #undef OutPortByte @@ -111,23 +110,4 @@ #endif /* LINUX_KERNEL */ -/**********************************************************************/ -/* XFree86/X.org */ -/**********************************************************************/ - -#ifdef SIS_XORG_XF86 - -#define SIS300 -#define SIS315H - -#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v)) -#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v)) -#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v)) -#define InPortByte(p) inSISREG((IOADDRESS)(p)) -#define InPortWord(p) inSISREGW((IOADDRESS)(p)) -#define InPortLong(p) inSISREGL((IOADDRESS)(p)) -#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) - -#endif /* XF86 */ - #endif /* _OSDEF_H_ */ diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h index 81a22eaabfd..f499062bba9 100644 --- a/drivers/video/sis/vgatypes.h +++ b/drivers/video/sis/vgatypes.h @@ -62,15 +62,6 @@ typedef unsigned long SISIOADDRESS; #define SISIOMEMTYPE __iomem #endif -#ifdef SIS_XORG_XF86 -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) -typedef unsigned long IOADDRESS; -typedef unsigned long SISIOADDRESS; -#else -typedef IOADDRESS SISIOADDRESS; -#endif -#endif - typedef enum _SIS_CHIP_TYPE { SIS_VGALegacy = 0, SIS_530, diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h index bef4aae388d..a860039c112 100644 --- a/drivers/video/sis/vstruct.h +++ b/drivers/video/sis/vstruct.h @@ -233,9 +233,6 @@ struct SiS_Private { unsigned char ChipType; unsigned char ChipRevision; -#ifdef SIS_XORG_XF86 - PCITAG PciTag; -#endif #ifdef SIS_LINUX_KERNEL void *ivideo; #endif @@ -280,9 +277,6 @@ struct SiS_Private unsigned short SiS_IF_DEF_FSTN; unsigned short SiS_SysFlags; unsigned char SiS_VGAINFO; -#ifdef SIS_XORG_XF86 - unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4; -#endif bool SiS_UseROM; bool SiS_ROMNew; bool SiS_XGIROM; -- cgit v1.2.3-70-g09d2 From b6c30ca6136c6c6900a086b6b843f738a588a2f3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 19 Nov 2010 21:58:46 +0000 Subject: sisfb: delete redudant #define SIS_LINUX_KERNEL It's not needed anymore with SIS_XORG_XF86 gone. Signed-off-by: Aaro Koskinen Cc: Thomas Winischhofer Signed-off-by: Paul Mundt --- drivers/video/sis/init.c | 50 -------------------------------------------- drivers/video/sis/init.h | 14 ------------- drivers/video/sis/init301.c | 23 -------------------- drivers/video/sis/init301.h | 14 ------------- drivers/video/sis/osdef.h | 7 ------- drivers/video/sis/vgatypes.h | 2 -- drivers/video/sis/vstruct.h | 6 ------ 7 files changed, 116 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c index 53e30ea5650..5634dfb4662 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c @@ -1150,9 +1150,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr) /* HELPER: SetLVDSetc */ /*********************************************/ -#ifdef SIS_LINUX_KERNEL static -#endif void SiSSetLVDSetc(struct SiS_Private *SiS_Pr) { @@ -1418,9 +1416,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) /* HELPER: GetVBType */ /*********************************************/ -#ifdef SIS_LINUX_KERNEL static -#endif void SiS_GetVBType(struct SiS_Private *SiS_Pr) { @@ -1485,7 +1481,6 @@ SiS_GetVBType(struct SiS_Private *SiS_Pr) /* HELPER: Check RAM size */ /*********************************************/ -#ifdef SIS_LINUX_KERNEL static bool SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) @@ -1499,7 +1494,6 @@ SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, if(AdapterMemSize < memorysize) return false; return true; } -#endif /*********************************************/ /* HELPER: Get DRAM type */ @@ -1572,7 +1566,6 @@ SiS_GetMCLK(struct SiS_Private *SiS_Pr) /* HELPER: ClearBuffer */ /*********************************************/ -#ifdef SIS_LINUX_KERNEL static void SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) { @@ -1597,7 +1590,6 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_SetMemory(memaddr, 0x8000, 0); } } -#endif /*********************************************/ /* HELPER: SearchModeID */ @@ -2504,11 +2496,7 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); /* Write foreground and background queue */ -#ifdef SIS_LINUX_KERNEL templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); -#else - templ = pciReadLong(0x00000000, 0x50); -#endif if(SiS_Pr->ChipType == SIS_730) { @@ -2528,13 +2516,8 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, } -#ifdef SIS_LINUX_KERNEL sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ); templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0); -#else - pciWriteLong(0x00000000, 0x50, templ); - templ = pciReadLong(0x00000000, 0xA0); -#endif /* GUI grant timer (PCI config 0xA3) */ if(SiS_Pr->ChipType == SIS_730) { @@ -2550,11 +2533,7 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, } -#ifdef SIS_LINUX_KERNEL sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ); -#else - pciWriteLong(0x00000000, 0xA0, templ); -#endif } #endif /* SIS300 */ @@ -3063,11 +3042,9 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); -#ifdef SIS_LINUX_KERNEL if(SiS_Pr->SiS_flag_clearbuffer) { SiS_ClearBuffer(SiS_Pr, ModeNo); } -#endif if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { SiS_WaitRetrace1(SiS_Pr); @@ -3163,11 +3140,7 @@ SiS_Handle760(struct SiS_Private *SiS_Pr) (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) ) return; -#ifdef SIS_LINUX_KERNEL somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74); -#else - somebase = pciReadWord(0x00001000, 0x74); -#endif somebase &= 0xffff; if(somebase == 0) return; @@ -3183,13 +3156,8 @@ SiS_Handle760(struct SiS_Private *SiS_Pr) temp2 = 0x0b; } -#ifdef SIS_LINUX_KERNEL sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1); sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2); -#else - pciWriteByte(0x00000000, 0x7e, temp1); - pciWriteByte(0x00000000, 0x8d, temp2); -#endif SiS_SetRegByte((somebase + 0x85), temp3); #endif @@ -3205,21 +3173,17 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; unsigned short RealModeNo, ModeIdIndex; unsigned char backupreg = 0; -#ifdef SIS_LINUX_KERNEL unsigned short KeepLockReg; SiS_Pr->UseCustomMode = false; SiS_Pr->CRT1UsesCustomMode = false; -#endif SiS_Pr->SiS_flag_clearbuffer = 0; if(SiS_Pr->UseCustomMode) { ModeNo = 0xfe; } else { -#ifdef SIS_LINUX_KERNEL if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1; -#endif ModeNo &= 0x7f; } @@ -3233,9 +3197,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_Pr->SiS_VGAINFO = 0x11; -#ifdef SIS_LINUX_KERNEL KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); -#endif SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); SiSInitPCIetc(SiS_Pr); @@ -3272,12 +3234,10 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); SiS_SetLowModeTest(SiS_Pr, ModeNo); -#ifdef SIS_LINUX_KERNEL /* Check memory size (kernel framebuffer driver only) */ if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) { return false; } -#endif SiS_OpenCRTC(SiS_Pr); @@ -3356,10 +3316,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) SiS_Handle760(SiS_Pr); -#ifdef SIS_LINUX_KERNEL /* We never lock registers in XF86 */ if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); -#endif return true; } @@ -3581,9 +3539,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, int yres, -#ifdef SIS_LINUX_KERNEL struct fb_var_screeninfo *var, bool writeres -#endif ) { unsigned short HRE, HBE, HRS, HBS, HDE, HT; @@ -3627,12 +3583,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, D = B - F - C; -#ifdef SIS_LINUX_KERNEL if(writeres) var->xres = xres = E * 8; var->left_margin = D * 8; var->right_margin = F * 8; var->hsync_len = C * 8; -#endif /* Vertical */ sr_data = crdata[13]; @@ -3679,12 +3633,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, D = B - F - C; -#ifdef SIS_LINUX_KERNEL if(writeres) var->yres = yres = E; var->upper_margin = D; var->lower_margin = F; var->vsync_len = C; -#endif if((xres == 320) && ((yres == 200) || (yres == 240))) { /* Terrible hack, but correct CRTC data for @@ -3693,11 +3645,9 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, * a negative D. The CRT controller does not * seem to like correcting HRE to 50) */ -#ifdef SIS_LINUX_KERNEL var->left_margin = (400 - 376); var->right_margin = (328 - 320); var->hsync_len = (376 - 328); -#endif } diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index 4a75c73e134..1d54759a49d 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h @@ -56,7 +56,6 @@ #include "osdef.h" #include "initdef.h" -#ifdef SIS_LINUX_KERNEL #include "vgatypes.h" #include "vstruct.h" #ifdef SIS_CP @@ -67,7 +66,6 @@ #include #include "sis.h" #include