public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Pavel Machek <pavel@ucw.cz>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org,
	linux-pm@lists.linux-foundation.org,
	Heiko Carstens <heiko.carstens@de.ibm.com>
Subject: Re: [PATCH v2] pm: Move nvs routines into a seperate file.
Date: Wed, 10 Jun 2009 01:09:19 +0200	[thread overview]
Message-ID: <200906100109.20470.rjw@sisk.pl> (raw)
In-Reply-To: <20090609104003.50830165@gondolin>

On Tuesday 09 June 2009, Cornelia Huck wrote:
> The *_nvs_* routines in swsusp.c make use of the io*map()
> functions, which are only provided for HAS_IOMEM, thus
> breaking compilation if HAS_IOMEM is not set. Fix this
> by moving the *_nvs_* routines into hibernation_nvs.c, which
> is only compiled if HAS_IOMEM is set.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Thanks, I added the GPLv2 line to the header comment and changed the name
of the file to hibernate_nvs.c (to match the other changes in the works).

I'll carry out some compilation testing on it and put it into the tree shortly.

Best,
Rafael

> ---
>  include/linux/suspend.h        |   18 +++--
>  kernel/power/Kconfig           |    4 +
>  kernel/power/Makefile          |    1 
>  kernel/power/hibernation_nvs.c |  135 +++++++++++++++++++++++++++++++++++++++++
>  kernel/power/swsusp.c          |  122 -------------------------------------
>  5 files changed, 151 insertions(+), 129 deletions(-)
> 
> --- /dev/null
> +++ linux-suspend/kernel/power/hibernation_nvs.c
> @@ -0,0 +1,135 @@
> +/*
> + * linux/kernel/power/hibernation_nvs.c
> + *
> + * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
> + *
> + * Routines for NVS memory handling
> + */
> +
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/mm.h>
> +#include <linux/suspend.h>
> +
> +/*
> + * Platforms, like ACPI, may want us to save some memory used by them during
> + * hibernation and to restore the contents of this memory during the subsequent
> + * resume.  The code below implements a mechanism allowing us to do that.
> + */
> +
> +struct nvs_page {
> +	unsigned long phys_start;
> +	unsigned int size;
> +	void *kaddr;
> +	void *data;
> +	struct list_head node;
> +};
> +
> +static LIST_HEAD(nvs_list);
> +
> +/**
> + *	hibernate_nvs_register - register platform NVS memory region to save
> + *	@start - physical address of the region
> + *	@size - size of the region
> + *
> + *	The NVS region need not be page-aligned (both ends) and we arrange
> + *	things so that the data from page-aligned addresses in this region will
> + *	be copied into separate RAM pages.
> + */
> +int hibernate_nvs_register(unsigned long start, unsigned long size)
> +{
> +	struct nvs_page *entry, *next;
> +
> +	while (size > 0) {
> +		unsigned int nr_bytes;
> +
> +		entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
> +		if (!entry)
> +			goto Error;
> +
> +		list_add_tail(&entry->node, &nvs_list);
> +		entry->phys_start = start;
> +		nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
> +		entry->size = (size < nr_bytes) ? size : nr_bytes;
> +
> +		start += entry->size;
> +		size -= entry->size;
> +	}
> +	return 0;
> +
> + Error:
> +	list_for_each_entry_safe(entry, next, &nvs_list, node) {
> +		list_del(&entry->node);
> +		kfree(entry);
> +	}
> +	return -ENOMEM;
> +}
> +
> +/**
> + *	hibernate_nvs_free - free data pages allocated for saving NVS regions
> + */
> +void hibernate_nvs_free(void)
> +{
> +	struct nvs_page *entry;
> +
> +	list_for_each_entry(entry, &nvs_list, node)
> +		if (entry->data) {
> +			free_page((unsigned long)entry->data);
> +			entry->data = NULL;
> +			if (entry->kaddr) {
> +				iounmap(entry->kaddr);
> +				entry->kaddr = NULL;
> +			}
> +		}
> +}
> +
> +/**
> + *	hibernate_nvs_alloc - allocate memory necessary for saving NVS regions
> + */
> +int hibernate_nvs_alloc(void)
> +{
> +	struct nvs_page *entry;
> +
> +	list_for_each_entry(entry, &nvs_list, node) {
> +		entry->data = (void *)__get_free_page(GFP_KERNEL);
> +		if (!entry->data) {
> +			hibernate_nvs_free();
> +			return -ENOMEM;
> +		}
> +	}
> +	return 0;
> +}
> +
> +/**
> + *	hibernate_nvs_save - save NVS memory regions
> + */
> +void hibernate_nvs_save(void)
> +{
> +	struct nvs_page *entry;
> +
> +	printk(KERN_INFO "PM: Saving platform NVS memory\n");
> +
> +	list_for_each_entry(entry, &nvs_list, node)
> +		if (entry->data) {
> +			entry->kaddr = ioremap(entry->phys_start, entry->size);
> +			memcpy(entry->data, entry->kaddr, entry->size);
> +		}
> +}
> +
> +/**
> + *	hibernate_nvs_restore - restore NVS memory regions
> + *
> + *	This function is going to be called with interrupts disabled, so it
> + *	cannot iounmap the virtual addresses used to access the NVS region.
> + */
> +void hibernate_nvs_restore(void)
> +{
> +	struct nvs_page *entry;
> +
> +	printk(KERN_INFO "PM: Restoring platform NVS memory\n");
> +
> +	list_for_each_entry(entry, &nvs_list, node)
> +		if (entry->data)
> +			memcpy(entry->kaddr, entry->data, entry->size);
> +}
> --- linux-suspend.orig/kernel/power/swsusp.c
> +++ linux-suspend/kernel/power/swsusp.c
> @@ -186,125 +186,3 @@ void swsusp_show_speed(struct timeval *s
>  			centisecs / 100, centisecs % 100,
>  			kps / 1000, (kps % 1000) / 10);
>  }
> -
> -/*
> - * Platforms, like ACPI, may want us to save some memory used by them during
> - * hibernation and to restore the contents of this memory during the subsequent
> - * resume.  The code below implements a mechanism allowing us to do that.
> - */
> -
> -struct nvs_page {
> -	unsigned long phys_start;
> -	unsigned int size;
> -	void *kaddr;
> -	void *data;
> -	struct list_head node;
> -};
> -
> -static LIST_HEAD(nvs_list);
> -
> -/**
> - *	hibernate_nvs_register - register platform NVS memory region to save
> - *	@start - physical address of the region
> - *	@size - size of the region
> - *
> - *	The NVS region need not be page-aligned (both ends) and we arrange
> - *	things so that the data from page-aligned addresses in this region will
> - *	be copied into separate RAM pages.
> - */
> -int hibernate_nvs_register(unsigned long start, unsigned long size)
> -{
> -	struct nvs_page *entry, *next;
> -
> -	while (size > 0) {
> -		unsigned int nr_bytes;
> -
> -		entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
> -		if (!entry)
> -			goto Error;
> -
> -		list_add_tail(&entry->node, &nvs_list);
> -		entry->phys_start = start;
> -		nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
> -		entry->size = (size < nr_bytes) ? size : nr_bytes;
> -
> -		start += entry->size;
> -		size -= entry->size;
> -	}
> -	return 0;
> -
> - Error:
> -	list_for_each_entry_safe(entry, next, &nvs_list, node) {
> -		list_del(&entry->node);
> -		kfree(entry);
> -	}
> -	return -ENOMEM;
> -}
> -
> -/**
> - *	hibernate_nvs_free - free data pages allocated for saving NVS regions
> - */
> -void hibernate_nvs_free(void)
> -{
> -	struct nvs_page *entry;
> -
> -	list_for_each_entry(entry, &nvs_list, node)
> -		if (entry->data) {
> -			free_page((unsigned long)entry->data);
> -			entry->data = NULL;
> -			if (entry->kaddr) {
> -				iounmap(entry->kaddr);
> -				entry->kaddr = NULL;
> -			}
> -		}
> -}
> -
> -/**
> - *	hibernate_nvs_alloc - allocate memory necessary for saving NVS regions
> - */
> -int hibernate_nvs_alloc(void)
> -{
> -	struct nvs_page *entry;
> -
> -	list_for_each_entry(entry, &nvs_list, node) {
> -		entry->data = (void *)__get_free_page(GFP_KERNEL);
> -		if (!entry->data) {
> -			hibernate_nvs_free();
> -			return -ENOMEM;
> -		}
> -	}
> -	return 0;
> -}
> -
> -/**
> - *	hibernate_nvs_save - save NVS memory regions
> - */
> -void hibernate_nvs_save(void)
> -{
> -	struct nvs_page *entry;
> -
> -	printk(KERN_INFO "PM: Saving platform NVS memory\n");
> -
> -	list_for_each_entry(entry, &nvs_list, node)
> -		if (entry->data) {
> -			entry->kaddr = ioremap(entry->phys_start, entry->size);
> -			memcpy(entry->data, entry->kaddr, entry->size);
> -		}
> -}
> -
> -/**
> - *	hibernate_nvs_restore - restore NVS memory regions
> - *
> - *	This function is going to be called with interrupts disabled, so it
> - *	cannot iounmap the virtual addresses used to access the NVS region.
> - */
> -void hibernate_nvs_restore(void)
> -{
> -	struct nvs_page *entry;
> -
> -	printk(KERN_INFO "PM: Restoring platform NVS memory\n");
> -
> -	list_for_each_entry(entry, &nvs_list, node)
> -		if (entry->data)
> -			memcpy(entry->kaddr, entry->data, entry->size);
> -}
> --- linux-suspend.orig/kernel/power/Kconfig
> +++ linux-suspend/kernel/power/Kconfig
> @@ -116,9 +116,13 @@ config SUSPEND_FREEZER
>  
>  	  Turning OFF this setting is NOT recommended! If in doubt, say Y.
>  
> +config HIBERNATION_NVS
> +	bool
> +
>  config HIBERNATION
>  	bool "Hibernation (aka 'suspend to disk')"
>  	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
> +	select HIBERNATION_NVS if HAS_IOMEM
>  	---help---
>  	  Enable the suspend to disk (STD) functionality, which is usually
>  	  called "hibernation" in user interfaces.  STD checkpoints the
> --- linux-suspend.orig/kernel/power/Makefile
> +++ linux-suspend/kernel/power/Makefile
> @@ -7,5 +7,6 @@ obj-$(CONFIG_PM)		+= main.o
>  obj-$(CONFIG_PM_SLEEP)		+= console.o
>  obj-$(CONFIG_FREEZER)		+= process.o
>  obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
> +obj-$(CONFIG_HIBERNATION_NVS)	+= hibernation_nvs.o
>  
>  obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
> --- linux-suspend.orig/include/linux/suspend.h
> +++ linux-suspend/include/linux/suspend.h
> @@ -245,11 +245,6 @@ extern unsigned long get_safe_page(gfp_t
>  
>  extern void hibernation_set_ops(struct platform_hibernation_ops *ops);
>  extern int hibernate(void);
> -extern int hibernate_nvs_register(unsigned long start, unsigned long size);
> -extern int hibernate_nvs_alloc(void);
> -extern void hibernate_nvs_free(void);
> -extern void hibernate_nvs_save(void);
> -extern void hibernate_nvs_restore(void);
>  extern bool system_entering_hibernation(void);
>  #else /* CONFIG_HIBERNATION */
>  static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
> @@ -258,6 +253,16 @@ static inline void swsusp_unset_page_fre
>  
>  static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {}
>  static inline int hibernate(void) { return -ENOSYS; }
> +static inline bool system_entering_hibernation(void) { return false; }
> +#endif /* CONFIG_HIBERNATION */
> +
> +#ifdef CONFIG_HIBERNATION_NVS
> +extern int hibernate_nvs_register(unsigned long start, unsigned long size);
> +extern int hibernate_nvs_alloc(void);
> +extern void hibernate_nvs_free(void);
> +extern void hibernate_nvs_save(void);
> +extern void hibernate_nvs_restore(void);
> +#else /* CONFIG_HIBERNATION_NVS */
>  static inline int hibernate_nvs_register(unsigned long a, unsigned long b)
>  {
>  	return 0;
> @@ -266,8 +271,7 @@ static inline int hibernate_nvs_alloc(vo
>  static inline void hibernate_nvs_free(void) {}
>  static inline void hibernate_nvs_save(void) {}
>  static inline void hibernate_nvs_restore(void) {}
> -static inline bool system_entering_hibernation(void) { return false; }
> -#endif /* CONFIG_HIBERNATION */
> +#endif /* CONFIG_HIBERNATION_NVS */
>  
>  #ifdef CONFIG_PM_SLEEP
>  void save_processor_state(void);
> 
> 


-- 
Everyone knows that debugging is twice as hard as writing a program
in the first place.  So if you're as clever as you can be when you write it,
how will you ever debug it? --- Brian Kernighan

  parent reply	other threads:[~2009-06-09 23:09 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04 16:18 [patch 00/38] power management / hibernate support for s390 Martin Schwidefsky
2009-06-04 16:18 ` [patch 01/38] pm: Move nvs routines into a seperate file Martin Schwidefsky
2009-06-08  6:35   ` Pavel Machek
2009-06-08 15:36     ` Cornelia Huck
2009-06-08 18:48       ` Rafael J. Wysocki
2009-06-09  8:40         ` [PATCH v2] " Cornelia Huck
2009-06-09 19:58           ` Pavel Machek
2009-06-09 23:09           ` Rafael J. Wysocki [this message]
2009-06-11 13:32             ` Heiko Carstens
2009-06-11 19:58               ` Rafael J. Wysocki
2009-06-11 21:11               ` Pavel Machek
2009-06-11 21:46                 ` Rafael J. Wysocki
2009-06-11 22:05                   ` Pavel Machek
2009-06-11 22:29                     ` Rafael J. Wysocki
2009-06-11 23:22                       ` Pavel Machek
2009-06-11 23:28                         ` Pavel Machek
2009-06-04 16:18 ` [patch 02/38] dasd: forward internal errors to dasd_sleep_on caller Martin Schwidefsky
2009-06-04 16:18 ` [patch 03/38] iucv: provide second per-cpu IUCV command parameter block Martin Schwidefsky
2009-06-04 16:18 ` [patch 04/38] device irq power management Martin Schwidefsky
2009-06-04 16:18 ` [patch 05/38] s390: hibernation support for s390 Martin Schwidefsky
2009-06-08  6:44   ` Pavel Machek
2009-06-09 13:34     ` Hans-Joachim Picht
2009-06-09 19:59       ` Pavel Machek
2009-06-10  9:48         ` Hans-Joachim Picht
2009-06-12  6:37     ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 06/38] pm: ccw bus power management callbacks Martin Schwidefsky
2009-06-04 16:18 ` [patch 07/38] pm: ccwgroup " Martin Schwidefsky
2009-06-04 16:18 ` [patch 08/38] pm: css " Martin Schwidefsky
2009-06-04 16:18 ` [patch 09/38] pm: io subchannel driver " Martin Schwidefsky
2009-06-04 16:18 ` [patch 10/38] pm: chsc " Martin Schwidefsky
2009-06-04 16:18 ` [patch 11/38] pm: dasd " Martin Schwidefsky
2009-06-04 16:18 ` [patch 12/38] pm: add kernel_page_present Martin Schwidefsky
2009-06-04 16:19 ` [patch 13/38] pm: xpram driver power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` [patch 14/38] cio: force console function Martin Schwidefsky
2009-06-04 16:19 ` [patch 15/38] pm: con3215 power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` [patch 16/38] pm: lcs driver " Martin Schwidefsky
2009-06-04 16:19 ` [patch 17/38] pm: qeth " Martin Schwidefsky
2009-06-04 16:19 ` [patch 18/38] pm: ctcm " Martin Schwidefsky
2009-06-04 16:19 ` [patch 19/38] pm: claw " Martin Schwidefsky
2009-06-04 16:19 ` [patch 20/38] pm: zfcp " Martin Schwidefsky
2009-06-04 16:19 ` [patch 21/38] pm: vmwatchdog " Martin Schwidefsky
2009-06-04 16:19 ` [patch 22/38] pm: appldata " Martin Schwidefsky
2009-06-04 16:19 ` [patch 23/38] pm: vmur driver " Martin Schwidefsky
2009-06-04 16:19 ` [patch 24/38] pm: vmlogrdr " Martin Schwidefsky
2009-06-04 16:19 ` [patch 25/38] pm: tape " Martin Schwidefsky
2009-06-04 16:19 ` [patch 26/38] pm: power management support for SCLP drivers Martin Schwidefsky
2009-06-04 16:19 ` [patch 27/38] iucv: establish reboot notifier Martin Schwidefsky
2009-06-04 16:19 ` [patch 28/38] pm: iucv power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` [patch 29/38] pm: netiucv " Martin Schwidefsky
2009-06-04 16:19 ` [patch 30/38] PM: af_iucv " Martin Schwidefsky
2009-06-04 16:19 ` [patch 31/38] pm: hvc_iucv " Martin Schwidefsky
2009-06-04 16:19 ` [patch 32/38] pm: smsgiucv " Martin Schwidefsky
2009-06-04 16:19 ` [patch 33/38] pm: con3270 " Martin Schwidefsky
2009-06-04 16:19 ` [patch 34/38] pm: memory hotplug " Martin Schwidefsky
2009-06-04 16:19 ` [patch 35/38] pm: monwriter " Martin Schwidefsky
2009-06-04 16:19 ` [patch 36/38] pm: monreader " Martin Schwidefsky
2009-06-04 16:19 ` [patch 37/38] pm: dcssblk " Martin Schwidefsky
2009-06-04 16:19 ` [patch 38/38] pm: ap bus " Martin Schwidefsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200906100109.20470.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=cornelia.huck@de.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=schwidefsky@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox