aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-20 18:15:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-20 18:15:03 -0400
commitbc259adc9b76f625fff0423df3ffb80a03802927 (patch)
tree68082b9f84a90eaaa8ed5b3ac3177eac32f9fe39
parentfe80352460971de12519bf46ed5ec4235350bcd7 (diff)
parent3026b0e942c65c65c8fc80d391d004228b52b916 (diff)
Merge tag 'staging-3.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree fixes from Greg Kroah-Hartman: "Here are a number of small fixes for the drivers/staging tree, as well as iio and pstore drivers (which came from the staging tree in the 3.5-rc1 merge). All of these are tiny, but resolve issues that people have been reporting. There's also a documentation update to reflect what the iio drivers really are doing, which is good to get straightened out. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'staging-3.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: r8712u: Add new USB IDs staging: gdm72xx: Release netlink socket properly iio: drop wrong reference from Kconfig pstore/inode: Make pstore_fill_super() static pstore/ram: Should zap persistent zone on unlink pstore/ram_core: Factor persistent_ram_zap() out of post_init() pstore/ram_core: Do not reset restored zone's position and size pstore/ram: Should update old dmesg buffer before reading staging:iio:ad7298: Fix linker error due to missing IIO kfifo buffer Revert "staging: usbip: bugfix for stack corruption on 64-bit architectures" staging: usbip: bugfix for stack corruption on 64-bit architectures staging/comedi: fix build for USB not enabled staging: omapdrm: fix crash when freeing bad fb staging:iio:ad7606: Re-add missing scale attribute iio: Fix potential use after free staging:iio: remove num_interrupt_lines from documentation iio: documentation: Add out_altvoltage and friends
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio31
-rw-r--r--drivers/iio/Kconfig3
-rw-r--r--drivers/iio/industrialio-core.c16
-rw-r--r--drivers/staging/comedi/drivers.c5
-rw-r--r--drivers/staging/gdm72xx/netlink_k.c2
-rw-r--r--drivers/staging/iio/Documentation/device.txt2
-rw-r--r--drivers/staging/iio/adc/Kconfig1
-rw-r--r--drivers/staging/iio/adc/ad7606_core.c3
-rw-r--r--drivers/staging/omapdrm/omap_fbdev.c10
-rw-r--r--drivers/staging/rtl8712/usb_intf.c2
-rw-r--r--fs/pstore/inode.c2
-rw-r--r--fs/pstore/ram.c3
-rw-r--r--fs/pstore/ram_core.c27
-rw-r--r--include/linux/pstore_ram.h2
14 files changed, 82 insertions, 27 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 5bc8a476c15e..cfedf63cce15 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -219,6 +219,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale
219What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale 219What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale
220What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale 220What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale
221What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale 221What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
222What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
222What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale 223What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale
223What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale 224What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
224What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale 225What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
@@ -273,6 +274,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
273What: /sys/.../iio:deviceX/in_voltageX_scale_available 274What: /sys/.../iio:deviceX/in_voltageX_scale_available
274What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available 275What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
275What: /sys/.../iio:deviceX/out_voltageX_scale_available 276What: /sys/.../iio:deviceX/out_voltageX_scale_available
277What: /sys/.../iio:deviceX/out_altvoltageX_scale_available
276What: /sys/.../iio:deviceX/in_capacitance_scale_available 278What: /sys/.../iio:deviceX/in_capacitance_scale_available
277KernelVersion: 2.635 279KernelVersion: 2.635
278Contact: linux-iio@vger.kernel.org 280Contact: linux-iio@vger.kernel.org
@@ -298,14 +300,19 @@ Description:
298 gives the 3dB frequency of the filter in Hz. 300 gives the 3dB frequency of the filter in Hz.
299 301
300What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw 302What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw
303What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw
301KernelVersion: 2.6.37 304KernelVersion: 2.6.37
302Contact: linux-iio@vger.kernel.org 305Contact: linux-iio@vger.kernel.org
303Description: 306Description:
304 Raw (unscaled, no bias etc.) output voltage for 307 Raw (unscaled, no bias etc.) output voltage for
305 channel Y. The number must always be specified and 308 channel Y. The number must always be specified and
306 unique if the output corresponds to a single channel. 309 unique if the output corresponds to a single channel.
310 While DAC like devices typically use out_voltage,
311 a continuous frequency generating device, such as
312 a DDS or PLL should use out_altvoltage.
307 313
308What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw 314What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw
315What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY&Z_raw
309KernelVersion: 2.6.37 316KernelVersion: 2.6.37
310Contact: linux-iio@vger.kernel.org 317Contact: linux-iio@vger.kernel.org
311Description: 318Description:
@@ -316,6 +323,8 @@ Description:
316 323
317What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode 324What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode
318What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode 325What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode
326What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode
327What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode
319KernelVersion: 2.6.38 328KernelVersion: 2.6.38
320Contact: linux-iio@vger.kernel.org 329Contact: linux-iio@vger.kernel.org
321Description: 330Description:
@@ -330,6 +339,8 @@ Description:
330 339
331What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available 340What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available
332What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available 341What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available
342What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available
343What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available
333KernelVersion: 2.6.38 344KernelVersion: 2.6.38
334Contact: linux-iio@vger.kernel.org 345Contact: linux-iio@vger.kernel.org
335Description: 346Description:
@@ -338,6 +349,8 @@ Description:
338 349
339What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown 350What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown
340What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown 351What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown
352What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown
353What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown
341KernelVersion: 2.6.38 354KernelVersion: 2.6.38
342Contact: linux-iio@vger.kernel.org 355Contact: linux-iio@vger.kernel.org
343Description: 356Description:
@@ -346,6 +359,24 @@ Description:
346 normal operation. Y may be suppressed if all outputs are 359 normal operation. Y may be suppressed if all outputs are
347 controlled together. 360 controlled together.
348 361
362What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency
363KernelVersion: 3.4.0
364Contact: linux-iio@vger.kernel.org
365Description:
366 Output frequency for channel Y in Hz. The number must always be
367 specified and unique if the output corresponds to a single
368 channel.
369
370What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase
371KernelVersion: 3.4.0
372Contact: linux-iio@vger.kernel.org
373Description:
374 Phase in radians of one frequency/clock output Y
375 (out_altvoltageY) relative to another frequency/clock output
376 (out_altvoltageZ) of the device X. The number must always be
377 specified and unique if the output corresponds to a single
378 channel.
379
349What: /sys/bus/iio/devices/iio:deviceX/events 380What: /sys/bus/iio/devices/iio:deviceX/events
350KernelVersion: 2.6.35 381KernelVersion: 2.6.35
351Contact: linux-iio@vger.kernel.org 382Contact: linux-iio@vger.kernel.org
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 56eecefcec75..2ec93da41e2c 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -8,8 +8,7 @@ menuconfig IIO
8 help 8 help
9 The industrial I/O subsystem provides a unified framework for 9 The industrial I/O subsystem provides a unified framework for
10 drivers for many different types of embedded sensors using a 10 drivers for many different types of embedded sensors using a
11 number of different physical interfaces (i2c, spi, etc). See 11 number of different physical interfaces (i2c, spi, etc).
12 Documentation/iio for more information.
13 12
14if IIO 13if IIO
15 14
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 1ddd8861c71b..4f947e4377ef 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -661,7 +661,6 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
661 * New channel registration method - relies on the fact a group does 661 * New channel registration method - relies on the fact a group does
662 * not need to be initialized if it is name is NULL. 662 * not need to be initialized if it is name is NULL.
663 */ 663 */
664 INIT_LIST_HEAD(&indio_dev->channel_attr_list);
665 if (indio_dev->channels) 664 if (indio_dev->channels)
666 for (i = 0; i < indio_dev->num_channels; i++) { 665 for (i = 0; i < indio_dev->num_channels; i++) {
667 ret = iio_device_add_channel_sysfs(indio_dev, 666 ret = iio_device_add_channel_sysfs(indio_dev,
@@ -725,12 +724,16 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
725static void iio_dev_release(struct device *device) 724static void iio_dev_release(struct device *device)
726{ 725{
727 struct iio_dev *indio_dev = dev_to_iio_dev(device); 726 struct iio_dev *indio_dev = dev_to_iio_dev(device);
728 cdev_del(&indio_dev->chrdev); 727 if (indio_dev->chrdev.dev)
728 cdev_del(&indio_dev->chrdev);
729 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) 729 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED)
730 iio_device_unregister_trigger_consumer(indio_dev); 730 iio_device_unregister_trigger_consumer(indio_dev);
731 iio_device_unregister_eventset(indio_dev); 731 iio_device_unregister_eventset(indio_dev);
732 iio_device_unregister_sysfs(indio_dev); 732 iio_device_unregister_sysfs(indio_dev);
733 iio_device_unregister_debugfs(indio_dev); 733 iio_device_unregister_debugfs(indio_dev);
734
735 ida_simple_remove(&iio_ida, indio_dev->id);
736 kfree(indio_dev);
734} 737}
735 738
736static struct device_type iio_dev_type = { 739static struct device_type iio_dev_type = {
@@ -761,6 +764,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
761 dev_set_drvdata(&dev->dev, (void *)dev); 764 dev_set_drvdata(&dev->dev, (void *)dev);
762 mutex_init(&dev->mlock); 765 mutex_init(&dev->mlock);
763 mutex_init(&dev->info_exist_lock); 766 mutex_init(&dev->info_exist_lock);
767 INIT_LIST_HEAD(&dev->channel_attr_list);
764 768
765 dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); 769 dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL);
766 if (dev->id < 0) { 770 if (dev->id < 0) {
@@ -778,10 +782,8 @@ EXPORT_SYMBOL(iio_device_alloc);
778 782
779void iio_device_free(struct iio_dev *dev) 783void iio_device_free(struct iio_dev *dev)
780{ 784{
781 if (dev) { 785 if (dev)
782 ida_simple_remove(&iio_ida, dev->id); 786 put_device(&dev->dev);
783 kfree(dev);
784 }
785} 787}
786EXPORT_SYMBOL(iio_device_free); 788EXPORT_SYMBOL(iio_device_free);
787 789
@@ -902,7 +904,7 @@ void iio_device_unregister(struct iio_dev *indio_dev)
902 mutex_lock(&indio_dev->info_exist_lock); 904 mutex_lock(&indio_dev->info_exist_lock);
903 indio_dev->info = NULL; 905 indio_dev->info = NULL;
904 mutex_unlock(&indio_dev->info_exist_lock); 906 mutex_unlock(&indio_dev->info_exist_lock);
905 device_unregister(&indio_dev->dev); 907 device_del(&indio_dev->dev);
906} 908}
907EXPORT_SYMBOL(iio_device_unregister); 909EXPORT_SYMBOL(iio_device_unregister);
908subsys_initcall(iio_init); 910subsys_initcall(iio_init);
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 1c3d6386ea36..aeac1caba3f9 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -30,6 +30,7 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/usb.h> 31#include <linux/usb.h>
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/kconfig.h>
33#include <linux/kernel.h> 34#include <linux/kernel.h>
34#include <linux/sched.h> 35#include <linux/sched.h>
35#include <linux/fcntl.h> 36#include <linux/fcntl.h>
@@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
981} 982}
982EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); 983EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
983 984
985#if IS_ENABLED(CONFIG_USB)
986
984static int comedi_old_usb_auto_config(struct usb_interface *intf, 987static int comedi_old_usb_auto_config(struct usb_interface *intf,
985 struct comedi_driver *driver) 988 struct comedi_driver *driver)
986{ 989{
@@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver,
1043 comedi_driver_unregister(comedi_driver); 1046 comedi_driver_unregister(comedi_driver);
1044} 1047}
1045EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); 1048EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister);
1049
1050#endif
diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c
index 292af0f7f451..51665132c61b 100644
--- a/drivers/staging/gdm72xx/netlink_k.c
+++ b/drivers/staging/gdm72xx/netlink_k.c
@@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
104 104
105void netlink_exit(struct sock *sock) 105void netlink_exit(struct sock *sock)
106{ 106{
107 sock_release(sock->sk_socket); 107 netlink_kernel_release(sock);
108} 108}
109 109
110int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) 110int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len)
diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
index 0338c7cd0a8b..f03fbd3bb454 100644
--- a/drivers/staging/iio/Documentation/device.txt
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -29,8 +29,6 @@ Then fill in the following:
29 * info->driver_module: 29 * info->driver_module:
30 Set to THIS_MODULE. Used to ensure correct ownership 30 Set to THIS_MODULE. Used to ensure correct ownership
31 of various resources allocate by the core. 31 of various resources allocate by the core.
32 * info->num_interrupt_lines:
33 Number of event triggering hardware lines the device has.
34 * info->event_attrs: 32 * info->event_attrs:
35 Attributes used to enable / disable hardware events. 33 Attributes used to enable / disable hardware events.
36 * info->attrs: 34 * info->attrs:
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 2490dd25093b..8f1b3af02f29 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -13,6 +13,7 @@ config AD7291
13config AD7298 13config AD7298
14 tristate "Analog Devices AD7298 ADC driver" 14 tristate "Analog Devices AD7298 ADC driver"
15 depends on SPI 15 depends on SPI
16 select IIO_KFIFO_BUF if IIO_BUFFER
16 help 17 help
17 Say yes here to build support for Analog Devices AD7298 18 Say yes here to build support for Analog Devices AD7298
18 8 Channel ADC with temperature sensor. 19 8 Channel ADC with temperature sensor.
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 10ab6dc823b9..a13afff2dfe6 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -235,7 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = {
235 .indexed = 1, \ 235 .indexed = 1, \
236 .channel = num, \ 236 .channel = num, \
237 .address = num, \ 237 .address = num, \
238 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ 238 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
239 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
239 .scan_index = num, \ 240 .scan_index = num, \
240 .scan_type = IIO_ST('s', 16, 16, 0), \ 241 .scan_type = IIO_ST('s', 16, 16, 0), \
241 } 242 }
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
index 11acd4c35ed2..8c6ed3b0c6f6 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
208 */ 208 */
209 ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); 209 ret = omap_gem_get_paddr(fbdev->bo, &paddr, true);
210 if (ret) { 210 if (ret) {
211 dev_err(dev->dev, "could not map (paddr)!\n"); 211 dev_err(dev->dev,
212 "could not map (paddr)! Skipping framebuffer alloc\n");
212 ret = -ENOMEM; 213 ret = -ENOMEM;
213 goto fail; 214 goto fail;
214 } 215 }
@@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev)
388 389
389 fbi = helper->fbdev; 390 fbi = helper->fbdev;
390 391
391 unregister_framebuffer(fbi); 392 /* only cleanup framebuffer if it is present */
392 framebuffer_release(fbi); 393 if (fbi) {
394 unregister_framebuffer(fbi);
395 framebuffer_release(fbi);
396 }
393 397
394 drm_fb_helper_fini(helper); 398 drm_fb_helper_fini(helper);
395 399
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 9bd18e2d0513..69f616c6964e 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -102,6 +102,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = {
102 /* - */ 102 /* - */
103 {USB_DEVICE(0x20F4, 0x646B)}, 103 {USB_DEVICE(0x20F4, 0x646B)},
104 {USB_DEVICE(0x083A, 0xC512)}, 104 {USB_DEVICE(0x083A, 0xC512)},
105 {USB_DEVICE(0x25D4, 0x4CA1)},
106 {USB_DEVICE(0x25D4, 0x4CAB)},
105 107
106/* RTL8191SU */ 108/* RTL8191SU */
107 /* Realtek */ 109 /* Realtek */
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index aeb19e68e086..11a2aa2a56c4 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -258,7 +258,7 @@ fail:
258 return rc; 258 return rc;
259} 259}
260 260
261int pstore_fill_super(struct super_block *sb, void *data, int silent) 261static int pstore_fill_super(struct super_block *sb, void *data, int silent)
262{ 262{
263 struct inode *inode; 263 struct inode *inode;
264 264
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 9123cce28c1e..453030f9c5bc 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -106,6 +106,8 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
106 time->tv_sec = 0; 106 time->tv_sec = 0;
107 time->tv_nsec = 0; 107 time->tv_nsec = 0;
108 108
109 /* Update old/shadowed buffer. */
110 persistent_ram_save_old(prz);
109 size = persistent_ram_old_size(prz); 111 size = persistent_ram_old_size(prz);
110 *buf = kmalloc(size, GFP_KERNEL); 112 *buf = kmalloc(size, GFP_KERNEL);
111 if (*buf == NULL) 113 if (*buf == NULL)
@@ -184,6 +186,7 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
184 return -EINVAL; 186 return -EINVAL;
185 187
186 persistent_ram_free_old(cxt->przs[id]); 188 persistent_ram_free_old(cxt->przs[id]);
189 persistent_ram_zap(cxt->przs[id]);
187 190
188 return 0; 191 return 0;
189} 192}
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 31f8d184f3a0..c5fbdbbf81ac 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
250 persistent_ram_update_ecc(prz, start, count); 250 persistent_ram_update_ecc(prz, start, count);
251} 251}
252 252
253static void __init 253void persistent_ram_save_old(struct persistent_ram_zone *prz)
254persistent_ram_save_old(struct persistent_ram_zone *prz)
255{ 254{
256 struct persistent_ram_buffer *buffer = prz->buffer; 255 struct persistent_ram_buffer *buffer = prz->buffer;
257 size_t size = buffer_size(prz); 256 size_t size = buffer_size(prz);
258 size_t start = buffer_start(prz); 257 size_t start = buffer_start(prz);
259 char *dest;
260 258
261 persistent_ram_ecc_old(prz); 259 if (!size)
260 return;
262 261
263 dest = kmalloc(size, GFP_KERNEL); 262 if (!prz->old_log) {
264 if (dest == NULL) { 263 persistent_ram_ecc_old(prz);
264 prz->old_log = kmalloc(size, GFP_KERNEL);
265 }
266 if (!prz->old_log) {
265 pr_err("persistent_ram: failed to allocate buffer\n"); 267 pr_err("persistent_ram: failed to allocate buffer\n");
266 return; 268 return;
267 } 269 }
268 270
269 prz->old_log = dest;
270 prz->old_log_size = size; 271 prz->old_log_size = size;
271 memcpy(prz->old_log, &buffer->data[start], size - start); 272 memcpy(prz->old_log, &buffer->data[start], size - start);
272 memcpy(prz->old_log + size - start, &buffer->data[0], start); 273 memcpy(prz->old_log + size - start, &buffer->data[0], start);
@@ -319,6 +320,13 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz)
319 prz->old_log_size = 0; 320 prz->old_log_size = 0;
320} 321}
321 322
323void persistent_ram_zap(struct persistent_ram_zone *prz)
324{
325 atomic_set(&prz->buffer->start, 0);
326 atomic_set(&prz->buffer->size, 0);
327 persistent_ram_update_header_ecc(prz);
328}
329
322static void *persistent_ram_vmap(phys_addr_t start, size_t size) 330static void *persistent_ram_vmap(phys_addr_t start, size_t size)
323{ 331{
324 struct page **pages; 332 struct page **pages;
@@ -405,6 +413,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool
405 " size %zu, start %zu\n", 413 " size %zu, start %zu\n",
406 buffer_size(prz), buffer_start(prz)); 414 buffer_size(prz), buffer_start(prz));
407 persistent_ram_save_old(prz); 415 persistent_ram_save_old(prz);
416 return 0;
408 } 417 }
409 } else { 418 } else {
410 pr_info("persistent_ram: no valid data in buffer" 419 pr_info("persistent_ram: no valid data in buffer"
@@ -412,8 +421,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool
412 } 421 }
413 422
414 prz->buffer->sig = PERSISTENT_RAM_SIG; 423 prz->buffer->sig = PERSISTENT_RAM_SIG;
415 atomic_set(&prz->buffer->start, 0); 424 persistent_ram_zap(prz);
416 atomic_set(&prz->buffer->size, 0);
417 425
418 return 0; 426 return 0;
419} 427}
@@ -448,7 +456,6 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start,
448 goto err; 456 goto err;
449 457
450 persistent_ram_post_init(prz, ecc); 458 persistent_ram_post_init(prz, ecc);
451 persistent_ram_update_header_ecc(prz);
452 459
453 return prz; 460 return prz;
454err: 461err:
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 7ed7fd4dba49..3b823d49a85a 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -69,12 +69,14 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start,
69 size_t size, 69 size_t size,
70 bool ecc); 70 bool ecc);
71void persistent_ram_free(struct persistent_ram_zone *prz); 71void persistent_ram_free(struct persistent_ram_zone *prz);
72void persistent_ram_zap(struct persistent_ram_zone *prz);
72struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, 73struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev,
73 bool ecc); 74 bool ecc);
74 75
75int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, 76int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
76 unsigned int count); 77 unsigned int count);
77 78
79void persistent_ram_save_old(struct persistent_ram_zone *prz);
78size_t persistent_ram_old_size(struct persistent_ram_zone *prz); 80size_t persistent_ram_old_size(struct persistent_ram_zone *prz);
79void *persistent_ram_old(struct persistent_ram_zone *prz); 81void *persistent_ram_old(struct persistent_ram_zone *prz);
80void persistent_ram_free_old(struct persistent_ram_zone *prz); 82void persistent_ram_free_old(struct persistent_ram_zone *prz);