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
next prev parent reply other threads:[~2009-06-09 23:09 UTC|newest]
Thread overview: 115+ 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 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 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 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:05 ` Pavel Machek
2009-06-11 22:29 ` Rafael J. Wysocki
2009-06-11 22:29 ` Rafael J. Wysocki
2009-06-11 23:22 ` Pavel Machek
2009-06-11 23:22 ` Pavel Machek
2009-06-11 23:28 ` Pavel Machek
2009-06-11 23:28 ` Pavel Machek
2009-06-11 21:46 ` Rafael J. Wysocki
2009-06-11 21:11 ` Pavel Machek
2009-06-11 13:32 ` Heiko Carstens
2009-06-09 23:09 ` Rafael J. Wysocki
2009-06-09 8:40 ` Cornelia Huck
2009-06-08 18:48 ` [patch 01/38] " Rafael J. Wysocki
2009-06-08 15:36 ` Cornelia Huck
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 02/38] dasd: forward internal errors to dasd_sleep_on caller Martin Schwidefsky
2009-06-04 16:18 ` 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 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 04/38] device irq power management Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 05/38] s390: hibernation support for s390 Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-08 6:44 ` Pavel Machek
2009-06-08 6:44 ` Pavel Machek
2009-06-09 13:34 ` Hans-Joachim Picht
2009-06-09 13:34 ` Hans-Joachim Picht
2009-06-09 19:59 ` Pavel Machek
2009-06-09 19:59 ` Pavel Machek
2009-06-10 9:48 ` Hans-Joachim Picht
2009-06-10 9:48 ` Hans-Joachim Picht
2009-06-12 6:37 ` Martin Schwidefsky
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 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 07/38] pm: ccwgroup " Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 08/38] pm: css " Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 09/38] pm: io subchannel driver " Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 10/38] pm: chsc " Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 11/38] pm: dasd " Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:18 ` [patch 12/38] pm: add kernel_page_present Martin Schwidefsky
2009-06-04 16:18 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 13/38] pm: xpram driver power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 14/38] cio: force console function Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 15/38] pm: con3215 power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 16/38] pm: lcs driver " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 17/38] pm: qeth " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 18/38] pm: ctcm " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 19/38] pm: claw " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 20/38] pm: zfcp " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 21/38] pm: vmwatchdog " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 22/38] pm: appldata " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 23/38] pm: vmur driver " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 24/38] pm: vmlogrdr " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 25/38] pm: tape " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 26/38] pm: power management support for SCLP drivers Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 27/38] iucv: establish reboot notifier Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 28/38] pm: iucv power management callbacks Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 29/38] pm: netiucv " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 30/38] PM: af_iucv " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 31/38] pm: hvc_iucv " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 32/38] pm: smsgiucv " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 33/38] pm: con3270 " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 34/38] pm: memory hotplug " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 35/38] pm: monwriter " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 36/38] pm: monreader " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 37/38] pm: dcssblk " Martin Schwidefsky
2009-06-04 16:19 ` Martin Schwidefsky
2009-06-04 16:19 ` [patch 38/38] pm: ap bus " Martin Schwidefsky
2009-06-04 16:19 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.