]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2014 03:16:19 +0000 (20:16 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2014 03:16:19 +0000 (20:16 -0700)
added patches:
media-dmxdev-remove-dvb_ringbuffer_flush-on-writer-side.patch
media-gspca_kinect-add-kinect-for-windows-usb-id.patch
media-hdpvr-fix-iteration-over-uninitialized-lists-in-hdpvr_probe.patch
media-hdpvr-register-the-video-node-at-the-end-of-probe.patch
media-omap_vout-find_vma-needs-mmap_sem-held.patch
media-saa7164-fix-return-value-check-in-saa7164_initdev.patch
media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
powernow-k6-correctly-initialize-default-parameters.patch
powernow-k6-disable-cache-when-changing-frequency.patch
powernow-k6-reorder-frequencies.patch

queue-3.4/media-dmxdev-remove-dvb_ringbuffer_flush-on-writer-side.patch [new file with mode: 0644]
queue-3.4/media-gspca_kinect-add-kinect-for-windows-usb-id.patch [new file with mode: 0644]
queue-3.4/media-hdpvr-fix-iteration-over-uninitialized-lists-in-hdpvr_probe.patch [new file with mode: 0644]
queue-3.4/media-hdpvr-register-the-video-node-at-the-end-of-probe.patch [new file with mode: 0644]
queue-3.4/media-omap_vout-find_vma-needs-mmap_sem-held.patch [new file with mode: 0644]
queue-3.4/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch [new file with mode: 0644]
queue-3.4/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch [new file with mode: 0644]
queue-3.4/powernow-k6-correctly-initialize-default-parameters.patch [new file with mode: 0644]
queue-3.4/powernow-k6-disable-cache-when-changing-frequency.patch [new file with mode: 0644]
queue-3.4/powernow-k6-reorder-frequencies.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/media-dmxdev-remove-dvb_ringbuffer_flush-on-writer-side.patch b/queue-3.4/media-dmxdev-remove-dvb_ringbuffer_flush-on-writer-side.patch
new file mode 100644 (file)
index 0000000..94f081a
--- /dev/null
@@ -0,0 +1,59 @@
+From 2af951daef68fcb1c6cace0543c420a8c26fe756 Mon Sep 17 00:00:00 2001
+From: Soeren Moch <smoch@web.de>
+Date: Wed, 5 Jun 2013 21:26:23 -0300
+Subject: media: dmxdev: remove dvb_ringbuffer_flush() on writer side
+
+From: Soeren Moch <smoch@web.de>
+
+commit 414abbd2cd4c2618895f02ed3a76ec6647281436 upstream.
+
+In dvb_ringbuffer lock-less synchronizationof reader and writer threads is done
+with separateread and write pointers. Sincedvb_ringbuffer_flush() modifies the
+read pointer, this function must not be called from the writer thread.
+This patch removes the dvb_ringbuffer_flush() calls in the dmxdev ringbuffer
+write functions, this fixes Oopses "Unable to handle kernel paging request"
+I could observe for the call chaindvb_demux_read ->dvb_dmxdev_buffer_read ->
+dvb_ringbuffer_read_user -> __copy_to_user (the reader side of the ringbuffer).
+The flush calls at the write side are not necessary anyway since ringbuffer_flush
+is also called in dvb_dmxdev_buffer_read() when an error condition is set in the
+ringbuffer.
+This patch should also be applied to stable kernels.
+
+Signed-off-by: Soeren Moch <smoch@web.de>
+Reviewed-by: Sakari Ailus <sakari.ailus@iki.fi>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/dvb/dvb-core/dmxdev.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/media/dvb/dvb-core/dmxdev.c
++++ b/drivers/media/dvb/dvb-core/dmxdev.c
+@@ -379,10 +379,8 @@ static int dvb_dmxdev_section_callback(c
+               ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
+                                             buffer2_len);
+       }
+-      if (ret < 0) {
+-              dvb_ringbuffer_flush(&dmxdevfilter->buffer);
++      if (ret < 0)
+               dmxdevfilter->buffer.error = ret;
+-      }
+       if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
+               dmxdevfilter->state = DMXDEV_STATE_DONE;
+       spin_unlock(&dmxdevfilter->dev->lock);
+@@ -418,10 +416,8 @@ static int dvb_dmxdev_ts_callback(const
+       ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
+       if (ret == buffer1_len)
+               ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
+-      if (ret < 0) {
+-              dvb_ringbuffer_flush(buffer);
++      if (ret < 0)
+               buffer->error = ret;
+-      }
+       spin_unlock(&dmxdevfilter->dev->lock);
+       wake_up(&buffer->queue);
+       return 0;
diff --git a/queue-3.4/media-gspca_kinect-add-kinect-for-windows-usb-id.patch b/queue-3.4/media-gspca_kinect-add-kinect-for-windows-usb-id.patch
new file mode 100644 (file)
index 0000000..b1f83ff
--- /dev/null
@@ -0,0 +1,35 @@
+From fd61506bd23ffc170dac4ecf401acae8004efceb Mon Sep 17 00:00:00 2001
+From: Jacob Schloss <jacob.schloss@unlimitedautomata.com>
+Date: Sun, 9 Dec 2012 20:18:25 -0300
+Subject: media: gspca_kinect: add Kinect for Windows USB id
+
+From: Jacob Schloss <jacob.schloss@unlimitedautomata.com>
+
+commit 98fd485795db064d0885150e2c0c7f296d8fe06e upstream.
+
+Add the USB ID for the Kinect for Windows RGB camera so it can be used
+with the gspca_kinect driver.
+
+Signed-off-by: Jacob Schloss <jacob.schloss@unlimitedautomata.com>
+Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/gspca/kinect.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/media/video/gspca/kinect.c
++++ b/drivers/media/video/gspca/kinect.c
+@@ -390,6 +390,7 @@ static const struct sd_desc sd_desc = {
+ /* -- module initialisation -- */
+ static const struct usb_device_id device_table[] = {
+       {USB_DEVICE(0x045e, 0x02ae)},
++      {USB_DEVICE(0x045e, 0x02bf)},
+       {}
+ };
diff --git a/queue-3.4/media-hdpvr-fix-iteration-over-uninitialized-lists-in-hdpvr_probe.patch b/queue-3.4/media-hdpvr-fix-iteration-over-uninitialized-lists-in-hdpvr_probe.patch
new file mode 100644 (file)
index 0000000..b09fd8b
--- /dev/null
@@ -0,0 +1,62 @@
+From 9eb9bfa030d8a49d54f0e4ae671e33f406bbbeff Mon Sep 17 00:00:00 2001
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Date: Wed, 3 Jul 2013 16:17:34 -0300
+Subject: media: hdpvr: fix iteration over uninitialized lists in hdpvr_probe()
+
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+
+commit 2e923a0527ac439e135b9961e58d3acd876bba10 upstream.
+
+free_buff_list and rec_buff_list are initialized in the middle of hdpvr_probe(),
+but if something bad happens before that, error handling code calls hdpvr_delete(),
+which contains iteration over the lists (via hdpvr_free_buffers()).
+The patch moves the lists initialization to the beginning and by the way fixes
+goto label in error handling of registering videodev.
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/hdpvr/hdpvr-core.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/video/hdpvr/hdpvr-core.c
++++ b/drivers/media/video/hdpvr/hdpvr-core.c
+@@ -309,6 +309,11 @@ static int hdpvr_probe(struct usb_interf
+       dev->workqueue = 0;
++      /* init video transfer queues first of all */
++      /* to prevent oops in hdpvr_delete() on error paths */
++      INIT_LIST_HEAD(&dev->free_buff_list);
++      INIT_LIST_HEAD(&dev->rec_buff_list);
++
+       /* register v4l2_device early so it can be used for printks */
+       if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+               err("v4l2_device_register failed");
+@@ -331,10 +336,6 @@ static int hdpvr_probe(struct usb_interf
+       if (!dev->workqueue)
+               goto error;
+-      /* init video transfer queues */
+-      INIT_LIST_HEAD(&dev->free_buff_list);
+-      INIT_LIST_HEAD(&dev->rec_buff_list);
+-
+       dev->options = hdpvr_default_options;
+       if (default_video_input < HDPVR_VIDEO_INPUTS)
+@@ -409,7 +410,7 @@ static int hdpvr_probe(struct usb_interf
+                                   video_nr[atomic_inc_return(&dev_nr)]);
+       if (retval < 0) {
+               v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+-              goto error;
++              goto reg_fail;
+       }
+       /* let the user know what node this device is now attached to */
diff --git a/queue-3.4/media-hdpvr-register-the-video-node-at-the-end-of-probe.patch b/queue-3.4/media-hdpvr-register-the-video-node-at-the-end-of-probe.patch
new file mode 100644 (file)
index 0000000..56dd8fd
--- /dev/null
@@ -0,0 +1,52 @@
+From 559a2e36f047ac7e1ab27c489322cfd1409dd842 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hans.verkuil@cisco.com>
+Date: Tue, 19 Mar 2013 09:34:58 -0300
+Subject: media: hdpvr: register the video node at the end of probe
+
+From: Hans Verkuil <hans.verkuil@cisco.com>
+
+commit 280847b532433ffe7a22795f926327805a127162 upstream.
+
+Video nodes can be used at once after registration, so make sure the full
+initialization is done before registering them.
+
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+[bwh: Backported to 3.2: adjust filename, context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/hdpvr/hdpvr-core.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/media/video/hdpvr/hdpvr-core.c
++++ b/drivers/media/video/hdpvr/hdpvr-core.c
+@@ -385,12 +385,6 @@ static int hdpvr_probe(struct usb_interf
+       }
+       mutex_unlock(&dev->io_mutex);
+-      if (hdpvr_register_videodev(dev, &interface->dev,
+-                                  video_nr[atomic_inc_return(&dev_nr)])) {
+-              v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+-              goto error;
+-      }
+-
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+       retval = hdpvr_register_i2c_adapter(dev);
+       if (retval < 0) {
+@@ -411,6 +405,13 @@ static int hdpvr_probe(struct usb_interf
+       }
+ #endif
++      retval = hdpvr_register_videodev(dev, &interface->dev,
++                                  video_nr[atomic_inc_return(&dev_nr)]);
++      if (retval < 0) {
++              v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
++              goto error;
++      }
++
+       /* let the user know what node this device is now attached to */
+       v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
+                 video_device_node_name(dev->video_dev));
diff --git a/queue-3.4/media-omap_vout-find_vma-needs-mmap_sem-held.patch b/queue-3.4/media-omap_vout-find_vma-needs-mmap_sem-held.patch
new file mode 100644 (file)
index 0000000..fe5562f
--- /dev/null
@@ -0,0 +1,66 @@
+From 5a82145cb978983b79993ee1d0b1982f3b80cd9b Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@ZenIV.linux.org.uk>
+Date: Sun, 16 Dec 2012 16:04:46 -0300
+Subject: media: omap_vout: find_vma() needs ->mmap_sem held
+
+From: Al Viro <viro@ZenIV.linux.org.uk>
+
+commit 55ee64b30a38d688232e5eb2860467dddc493573 upstream.
+
+Walking rbtree while it's modified is a Bad Idea(tm); besides,
+the result of find_vma() can be freed just as it's getting returned
+to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
+earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
+in that case we don't even look at its result).
+
+While we are at it, what prevents VIDIOC_PREPARE_BUF calling
+v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
+__buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() -> find_vma(),
+AFAICS without having taken ->mmap_sem anywhere in process?  The code flow
+is bloody convoluted and depends on a bunch of things done by initialization,
+so I certainly might've missed something...
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Sakari Ailus <sakari.ailus@iki.fi>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: Archit Taneja <archit@ti.com>
+Cc: Prabhakar Lad <prabhakar.lad@ti.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/omap/omap_vout.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/video/omap/omap_vout.c
++++ b/drivers/media/video/omap/omap_vout.c
+@@ -206,19 +206,21 @@ static u32 omap_vout_uservirt_to_phys(u3
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+-      vma = find_vma(mm, virtp);
+       /* For kernel direct-mapped memory, take the easy way */
+-      if (virtp >= PAGE_OFFSET) {
+-              physp = virt_to_phys((void *) virtp);
+-      } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
++      if (virtp >= PAGE_OFFSET)
++              return virt_to_phys((void *) virtp);
++
++      down_read(&current->mm->mmap_sem);
++      vma = find_vma(mm, virtp);
++      if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
+               /* this will catch, kernel-allocated, mmaped-to-usermode
+                  addresses */
+               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
++              up_read(&current->mm->mmap_sem);
+       } else {
+               /* otherwise, use get_user_pages() for general userland pages */
+               int res, nr_pages = 1;
+               struct page *pages;
+-              down_read(&current->mm->mmap_sem);
+               res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
+                               0, &pages, NULL);
diff --git a/queue-3.4/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch b/queue-3.4/media-saa7164-fix-return-value-check-in-saa7164_initdev.patch
new file mode 100644 (file)
index 0000000..d1b311f
--- /dev/null
@@ -0,0 +1,40 @@
+From 47c55eb0a98d1f513f0bc1bc8065c7cc276c3335 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Fri, 25 Oct 2013 06:34:03 -0300
+Subject: media: saa7164: fix return value check in saa7164_initdev()
+
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+
+commit 89f4d45b2752df5d222b5f63919ce59e2d8afaf4 upstream.
+
+In case of error, the function kthread_run() returns ERR_PTR()
+and never returns NULL. The NULL test in the return value check
+should be replaced with IS_ERR().
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+[bwh: Backported to 3.2: adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/saa7164/saa7164-core.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/video/saa7164/saa7164-core.c
++++ b/drivers/media/video/saa7164/saa7164-core.c
+@@ -1386,9 +1386,11 @@ static int __devinit saa7164_initdev(str
+               if (fw_debug) {
+                       dev->kthread = kthread_run(saa7164_thread_function, dev,
+                               "saa7164 debug");
+-                      if (!dev->kthread)
++                      if (IS_ERR(dev->kthread)) {
++                              dev->kthread = NULL;
+                               printk(KERN_ERR "%s() Failed to create "
+                                       "debug kernel thread\n", __func__);
++                      }
+               }
+       } /* != BOARD_UNKNOWN */
diff --git a/queue-3.4/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch b/queue-3.4/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
new file mode 100644 (file)
index 0000000..538990b
--- /dev/null
@@ -0,0 +1,83 @@
+From 754aed1b98d1c1ed2a8eaae2fc933bc9c6a87629 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 24 Nov 2012 21:35:48 -0300
+Subject: media: v4l: Reset subdev v4l2_dev field to NULL if registration fails
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 317efce991620adc589b3005b9baed433dcb2a56 upstream.
+
+When subdev registration fails the subdev v4l2_dev field is left to a
+non-NULL value. Later calls to v4l2_device_unregister_subdev() will
+consider the subdev as registered and will module_put() the subdev
+module without any matching module_get().
+Fix this by setting the subdev v4l2_dev field to NULL in
+v4l2_device_register_subdev() when the function fails.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+[bwh: Backported to 3.2: adjust context, filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Jianguo Wu <wujianguo@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/video/v4l2-device.c |   30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+--- a/drivers/media/video/v4l2-device.c
++++ b/drivers/media/video/v4l2-device.c
+@@ -159,31 +159,21 @@ int v4l2_device_register_subdev(struct v
+       sd->v4l2_dev = v4l2_dev;
+       if (sd->internal_ops && sd->internal_ops->registered) {
+               err = sd->internal_ops->registered(sd);
+-              if (err) {
+-                      module_put(sd->owner);
+-                      return err;
+-              }
++              if (err)
++                      goto error_module;
+       }
+       /* This just returns 0 if either of the two args is NULL */
+       err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
+-      if (err) {
+-              if (sd->internal_ops && sd->internal_ops->unregistered)
+-                      sd->internal_ops->unregistered(sd);
+-              module_put(sd->owner);
+-              return err;
+-      }
++      if (err)
++              goto error_unregister;
+ #if defined(CONFIG_MEDIA_CONTROLLER)
+       /* Register the entity. */
+       if (v4l2_dev->mdev) {
+               err = media_device_register_entity(v4l2_dev->mdev, entity);
+-              if (err < 0) {
+-                      if (sd->internal_ops && sd->internal_ops->unregistered)
+-                              sd->internal_ops->unregistered(sd);
+-                      module_put(sd->owner);
+-                      return err;
+-              }
++              if (err < 0)
++                      goto error_unregister;
+       }
+ #endif
+@@ -192,6 +182,14 @@ int v4l2_device_register_subdev(struct v
+       spin_unlock(&v4l2_dev->lock);
+       return 0;
++
++error_unregister:
++      if (sd->internal_ops && sd->internal_ops->unregistered)
++              sd->internal_ops->unregistered(sd);
++error_module:
++      module_put(sd->owner);
++      sd->v4l2_dev = NULL;
++      return err;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
diff --git a/queue-3.4/powernow-k6-correctly-initialize-default-parameters.patch b/queue-3.4/powernow-k6-correctly-initialize-default-parameters.patch
new file mode 100644 (file)
index 0000000..fa93fab
--- /dev/null
@@ -0,0 +1,153 @@
+From d82b922a4acc1781d368aceac2f9da43b038cab2 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 11 Dec 2013 19:38:53 -0500
+Subject: powernow-k6: correctly initialize default parameters
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit d82b922a4acc1781d368aceac2f9da43b038cab2 upstream.
+
+The powernow-k6 driver used to read the initial multiplier from the
+powernow register. However, there is a problem with this:
+
+* If there was a frequency transition before, the multiplier read from the
+  register corresponds to the current multiplier.
+* If there was no frequency transition since reset, the field in the
+  register always reads as zero, regardless of the current multiplier that
+  is set using switches on the mainboard and that the CPU is running at.
+
+The zero value corresponds to multiplier 4.5, so as a consequence, the
+powernow-k6 driver always assumes multiplier 4.5.
+
+For example, if we have 550MHz CPU with bus frequency 100MHz and
+multiplier 5.5, the powernow-k6 driver thinks that the multiplier is 4.5
+and bus frequency is 122MHz. The powernow-k6 driver then sets the
+multiplier to 4.5, underclocking the CPU to 450MHz, but reports the
+current frequency as 550MHz.
+
+There is no reliable way how to read the initial multiplier. I modified
+the driver so that it contains a table of known frequencies (based on
+parameters of existing CPUs and some common overclocking schemes) and sets
+the multiplier according to the frequency. If the frequency is unknown
+(because of unusual overclocking or underclocking), the user must supply
+the bus speed and maximum multiplier as module parameters.
+
+This patch should be backported to all stable kernels. If it doesn't
+apply cleanly, change it, or ask me to change it.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/cpufreq/powernow-k6.c |   76 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 72 insertions(+), 4 deletions(-)
+
+--- a/drivers/cpufreq/powernow-k6.c
++++ b/drivers/cpufreq/powernow-k6.c
+@@ -26,6 +26,14 @@
+ static unsigned int                     busfreq;   /* FSB, in 10 kHz */
+ static unsigned int                     max_multiplier;
++static unsigned int                   param_busfreq = 0;
++static unsigned int                   param_max_multiplier = 0;
++
++module_param_named(max_multiplier, param_max_multiplier, uint, S_IRUGO);
++MODULE_PARM_DESC(max_multiplier, "Maximum multiplier (allowed values: 20 30 35 40 45 50 55 60)");
++
++module_param_named(bus_frequency, param_busfreq, uint, S_IRUGO);
++MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz");
+ /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
+ static struct cpufreq_frequency_table clock_ratio[] = {
+@@ -40,6 +48,27 @@ static struct cpufreq_frequency_table cl
+       {0, CPUFREQ_TABLE_END}
+ };
++static const struct {
++      unsigned freq;
++      unsigned mult;
++} usual_frequency_table[] = {
++      { 400000, 40 }, // 100   * 4
++      { 450000, 45 }, // 100   * 4.5
++      { 475000, 50 }, //  95   * 5
++      { 500000, 50 }, // 100   * 5
++      { 506250, 45 }, // 112.5 * 4.5
++      { 533500, 55 }, //  97   * 5.5
++      { 550000, 55 }, // 100   * 5.5
++      { 562500, 50 }, // 112.5 * 5
++      { 570000, 60 }, //  95   * 6
++      { 600000, 60 }, // 100   * 6
++      { 618750, 55 }, // 112.5 * 5.5
++      { 660000, 55 }, // 120   * 5.5
++      { 675000, 60 }, // 112.5 * 6
++      { 720000, 60 }, // 120   * 6
++};
++
++#define FREQ_RANGE            3000
+ /**
+  * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
+@@ -163,18 +192,57 @@ static int powernow_k6_target(struct cpu
+       return 0;
+ }
+-
+ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+ {
+       unsigned int i, f;
+       int result;
++      unsigned khz;
+       if (policy->cpu != 0)
+               return -ENODEV;
+-      /* get frequencies */
+-      max_multiplier = powernow_k6_get_cpu_multiplier();
+-      busfreq = cpu_khz / max_multiplier;
++      max_multiplier = 0;
++      khz = cpu_khz;
++      for (i = 0; i < ARRAY_SIZE(usual_frequency_table); i++) {
++              if (khz >= usual_frequency_table[i].freq - FREQ_RANGE &&
++                  khz <= usual_frequency_table[i].freq + FREQ_RANGE) {
++                      khz = usual_frequency_table[i].freq;
++                      max_multiplier = usual_frequency_table[i].mult;
++                      break;
++              }
++      }
++      if (param_max_multiplier) {
++              for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
++                      if (clock_ratio[i].index == param_max_multiplier) {
++                              max_multiplier = param_max_multiplier;
++                              goto have_max_multiplier;
++                      }
++              }
++              printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
++              return -EINVAL;
++      }
++
++      if (!max_multiplier) {
++              printk(KERN_WARNING "powernow-k6: unknown frequency %u, cannot determine current multiplier\n", khz);
++              printk(KERN_WARNING "powernow-k6: use module parameters max_multiplier and bus_frequency\n");
++              return -EOPNOTSUPP;
++      }
++
++have_max_multiplier:
++      param_max_multiplier = max_multiplier;
++
++      if (param_busfreq) {
++              if (param_busfreq >= 50000 && param_busfreq <= 150000) {
++                      busfreq = param_busfreq / 10;
++                      goto have_busfreq;
++              }
++              printk(KERN_ERR "powernow-k6: invalid bus_frequency parameter, allowed range 50000 - 150000 kHz\n");
++              return -EINVAL;
++      }
++
++      busfreq = khz / max_multiplier;
++have_busfreq:
++      param_busfreq = busfreq * 10;
+       /* table init */
+       for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
diff --git a/queue-3.4/powernow-k6-disable-cache-when-changing-frequency.patch b/queue-3.4/powernow-k6-disable-cache-when-changing-frequency.patch
new file mode 100644 (file)
index 0000000..e1963db
--- /dev/null
@@ -0,0 +1,144 @@
+From e20e1d0ac02308e2211306fc67abcd0b2668fb8b Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 11 Dec 2013 19:38:32 -0500
+Subject: powernow-k6: disable cache when changing frequency
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit e20e1d0ac02308e2211306fc67abcd0b2668fb8b upstream.
+
+I found out that a system with k6-3+ processor is unstable during network
+server load. The system locks up or the network card stops receiving. The
+reason for the instability is the CPU frequency scaling.
+
+During frequency transition the processor is in "EPM Stop Grant" state.
+The documentation says that the processor doesn't respond to inquiry
+requests in this state. Consequently, coherency of processor caches and
+bus master devices is not maintained, causing the system instability.
+
+This patch flushes the cache during frequency transition. It fixes the
+instability.
+
+Other minor changes:
+* u64 invalue changed to unsigned long because the variable is 32-bit
+* move the logic to set the multiplier to a separate function
+  powernow_k6_set_cpu_multiplier
+* preserve lower 5 bits of the powernow port instead of 4 (the voltage
+  field has 5 bits)
+* mask interrupts when reading the multiplier, so that the port is not
+  open during other activity (running other kernel code with the port open
+  shouldn't cause any misbehavior, but we should better be safe and keep
+  the port closed)
+
+This patch should be backported to all stable kernels. If it doesn't
+apply cleanly, change it, or ask me to change it.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/powernow-k6.c |   56 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 39 insertions(+), 17 deletions(-)
+
+--- a/drivers/cpufreq/powernow-k6.c
++++ b/drivers/cpufreq/powernow-k6.c
+@@ -44,23 +44,58 @@ static struct cpufreq_frequency_table cl
+ /**
+  * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
+  *
+- *   Returns the current setting of the frequency multiplier. Core clock
++ * Returns the current setting of the frequency multiplier. Core clock
+  * speed is frequency of the Front-Side Bus multiplied with this value.
+  */
+ static int powernow_k6_get_cpu_multiplier(void)
+ {
+-      u64 invalue = 0;
++      unsigned long invalue = 0;
+       u32 msrval;
++      local_irq_disable();
++
+       msrval = POWERNOW_IOPORT + 0x1;
+       wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+       invalue = inl(POWERNOW_IOPORT + 0x8);
+       msrval = POWERNOW_IOPORT + 0x0;
+       wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
++      local_irq_enable();
++
+       return clock_ratio[(invalue >> 5)&7].index;
+ }
++static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
++{
++      unsigned long outvalue, invalue;
++      unsigned long msrval;
++      unsigned long cr0;
++
++      /* we now need to transform best_i to the BVC format, see AMD#23446 */
++
++      /*
++       * The processor doesn't respond to inquiry cycles while changing the
++       * frequency, so we must disable cache.
++       */
++      local_irq_disable();
++      cr0 = read_cr0();
++      write_cr0(cr0 | X86_CR0_CD);
++      wbinvd();
++
++      outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
++
++      msrval = POWERNOW_IOPORT + 0x1;
++      wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
++      invalue = inl(POWERNOW_IOPORT + 0x8);
++      invalue = invalue & 0x1f;
++      outvalue = outvalue | invalue;
++      outl(outvalue, (POWERNOW_IOPORT + 0x8));
++      msrval = POWERNOW_IOPORT + 0x0;
++      wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
++
++      write_cr0(cr0);
++      local_irq_enable();
++}
+ /**
+  * powernow_k6_set_state - set the PowerNow! multiplier
+@@ -70,8 +105,6 @@ static int powernow_k6_get_cpu_multiplie
+  */
+ static void powernow_k6_set_state(unsigned int best_i)
+ {
+-      unsigned long outvalue = 0, invalue = 0;
+-      unsigned long msrval;
+       struct cpufreq_freqs freqs;
+       if (clock_ratio[best_i].index > max_multiplier) {
+@@ -85,18 +118,7 @@ static void powernow_k6_set_state(unsign
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+-      /* we now need to transform best_i to the BVC format, see AMD#23446 */
+-
+-      outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
+-
+-      msrval = POWERNOW_IOPORT + 0x1;
+-      wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+-      invalue = inl(POWERNOW_IOPORT + 0x8);
+-      invalue = invalue & 0xf;
+-      outvalue = outvalue | invalue;
+-      outl(outvalue , (POWERNOW_IOPORT + 0x8));
+-      msrval = POWERNOW_IOPORT + 0x0;
+-      wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
++      powernow_k6_set_cpu_multiplier(best_i);
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+@@ -164,7 +186,7 @@ static int powernow_k6_cpu_init(struct c
+       }
+       /* cpuinfo and default policy values */
+-      policy->cpuinfo.transition_latency = 200000;
++      policy->cpuinfo.transition_latency = 500000;
+       policy->cur = busfreq * max_multiplier;
+       result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
diff --git a/queue-3.4/powernow-k6-reorder-frequencies.patch b/queue-3.4/powernow-k6-reorder-frequencies.patch
new file mode 100644 (file)
index 0000000..5466a0f
--- /dev/null
@@ -0,0 +1,68 @@
+From 22c73795b101597051924556dce019385a1e2fa0 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 11 Dec 2013 19:39:19 -0500
+Subject: powernow-k6: reorder frequencies
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 22c73795b101597051924556dce019385a1e2fa0 upstream.
+
+This patch reorders reported frequencies from the highest to the lowest,
+just like in other frequency drivers.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/cpufreq/powernow-k6.c |   17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/cpufreq/powernow-k6.c
++++ b/drivers/cpufreq/powernow-k6.c
+@@ -37,17 +37,20 @@ MODULE_PARM_DESC(bus_frequency, "Bus fre
+ /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
+ static struct cpufreq_frequency_table clock_ratio[] = {
+-      {45,  /* 000 -> 4.5x */ 0},
++      {60,  /* 110 -> 6.0x */ 0},
++      {55,  /* 011 -> 5.5x */ 0},
+       {50,  /* 001 -> 5.0x */ 0},
++      {45,  /* 000 -> 4.5x */ 0},
+       {40,  /* 010 -> 4.0x */ 0},
+-      {55,  /* 011 -> 5.5x */ 0},
+-      {20,  /* 100 -> 2.0x */ 0},
+-      {30,  /* 101 -> 3.0x */ 0},
+-      {60,  /* 110 -> 6.0x */ 0},
+       {35,  /* 111 -> 3.5x */ 0},
++      {30,  /* 101 -> 3.0x */ 0},
++      {20,  /* 100 -> 2.0x */ 0},
+       {0, CPUFREQ_TABLE_END}
+ };
++static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 };
++static const u8 register_to_index[8] = { 3, 2, 4, 1, 7, 6, 0, 5 };
++
+ static const struct {
+       unsigned freq;
+       unsigned mult;
+@@ -91,7 +94,7 @@ static int powernow_k6_get_cpu_multiplie
+       local_irq_enable();
+-      return clock_ratio[(invalue >> 5)&7].index;
++      return clock_ratio[register_to_index[(invalue >> 5)&7]].index;
+ }
+ static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
+@@ -111,7 +114,7 @@ static void powernow_k6_set_cpu_multipli
+       write_cr0(cr0 | X86_CR0_CD);
+       wbinvd();
+-      outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
++      outvalue = (1<<12) | (1<<10) | (1<<9) | (index_to_register[best_i]<<5);
+       msrval = POWERNOW_IOPORT + 0x1;
+       wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
index fa5999b2a9e509f9306bd19415a784f86739fa5b..f433ba37a56f541140a2b693cabee8ffac913cf7 100644 (file)
@@ -122,3 +122,13 @@ mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch
 sb_edac-avoid-overflow-errors-at-memory-size-calculation.patch
 tg3-skip-powering-down-function-0-on-certain-serdes-devices.patch
 tg3-add-read-dma-workaround-for-5720.patch
+media-gspca_kinect-add-kinect-for-windows-usb-id.patch
+media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
+media-omap_vout-find_vma-needs-mmap_sem-held.patch
+media-dmxdev-remove-dvb_ringbuffer_flush-on-writer-side.patch
+media-hdpvr-register-the-video-node-at-the-end-of-probe.patch
+media-hdpvr-fix-iteration-over-uninitialized-lists-in-hdpvr_probe.patch
+media-saa7164-fix-return-value-check-in-saa7164_initdev.patch
+powernow-k6-disable-cache-when-changing-frequency.patch
+powernow-k6-correctly-initialize-default-parameters.patch
+powernow-k6-reorder-frequencies.patch