Release 4.12 drivers/acpi/nvs.c
  
  
  
/*
 * nvs.c - Routines for saving and restoring ACPI NVS memory region
 *
 * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
 *
 * This file is released under the GPLv2.
 */
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include "internal.h"
/* ACPI NVS regions, APEI may use it */
struct nvs_region {
	
__u64 phys_start;
	
__u64 size;
	
struct list_head node;
};
static LIST_HEAD(nvs_region_list);
#ifdef CONFIG_ACPI_SLEEP
static int suspend_nvs_register(unsigned long start, unsigned long size);
#else
static inline int suspend_nvs_register(unsigned long a, unsigned long b)
{
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Huang Ying | 18 | 100.00% | 1 | 100.00% | 
| Total | 18 | 100.00% | 1 | 100.00% | 
#endif
int acpi_nvs_register(__u64 start, __u64 size)
{
	struct nvs_region *region;
	region = kmalloc(sizeof(*region), GFP_KERNEL);
	if (!region)
		return -ENOMEM;
	region->phys_start = start;
	region->size = size;
	list_add_tail(®ion->node, &nvs_region_list);
	return suspend_nvs_register(start, size);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Huang Ying | 69 | 100.00% | 1 | 100.00% | 
| Total | 69 | 100.00% | 1 | 100.00% | 
int acpi_nvs_for_each_region(int (*func)(__u64 start, __u64 size, void *data),
			     void *data)
{
	int rc;
	struct nvs_region *region;
	list_for_each_entry(region, &nvs_region_list, node) {
		rc = func(region->phys_start, region->size, data);
		if (rc)
			return rc;
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Huang Ying | 69 | 100.00% | 1 | 100.00% | 
| Total | 69 | 100.00% | 1 | 100.00% | 
#ifdef CONFIG_ACPI_SLEEP
/*
 * Platforms, like ACPI, may want us to save some memory used by them during
 * suspend 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;
	
bool unmap;
	
struct list_head node;
};
static LIST_HEAD(nvs_list);
/**
 *      suspend_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.
 */
static int suspend_nvs_register(unsigned long start, unsigned long size)
{
	struct nvs_page *entry, *next;
	pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n",
		start, start + size - 1, size);
	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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 141 | 89.24% | 1 | 20.00% | 
| Rafael J. Wysocki | 8 | 5.06% | 1 | 20.00% | 
| Björn Helgaas | 7 | 4.43% | 1 | 20.00% | 
| Huang Ying | 1 | 0.63% | 1 | 20.00% | 
| Matthew Garrett | 1 | 0.63% | 1 | 20.00% | 
| Total | 158 | 100.00% | 5 | 100.00% | 
/**
 *      suspend_nvs_free - free data pages allocated for saving NVS regions
 */
void suspend_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) {
				if (entry->unmap) {
					iounmap(entry->kaddr);
					entry->unmap = false;
				} else {
					acpi_os_unmap_iomem(entry->kaddr,
							    entry->size);
				}
				entry->kaddr = NULL;
			}
		}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 64 | 68.09% | 1 | 20.00% | 
| Rafael J. Wysocki | 28 | 29.79% | 2 | 40.00% | 
| Matthew Garrett | 1 | 1.06% | 1 | 20.00% | 
| Lv Zheng | 1 | 1.06% | 1 | 20.00% | 
| Total | 94 | 100.00% | 5 | 100.00% | 
/**
 *      suspend_nvs_alloc - allocate memory necessary for saving NVS regions
 */
int suspend_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) {
			suspend_nvs_free();
			return -ENOMEM;
		}
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 52 | 96.30% | 1 | 50.00% | 
| Matthew Garrett | 2 | 3.70% | 1 | 50.00% | 
| Total | 54 | 100.00% | 2 | 100.00% | 
/**
 *      suspend_nvs_save - save NVS memory regions
 */
int suspend_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) {
			unsigned long phys = entry->phys_start;
			unsigned int size = entry->size;
			entry->kaddr = acpi_os_get_iomem(phys, size);
			if (!entry->kaddr) {
				entry->kaddr = acpi_os_ioremap(phys, size);
				entry->unmap = !!entry->kaddr;
			}
			if (!entry->kaddr) {
				suspend_nvs_free();
				return -ENOMEM;
			}
			memcpy(entry->data, entry->kaddr, entry->size);
		}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 59 | 47.20% | 1 | 25.00% | 
| Rafael J. Wysocki | 45 | 36.00% | 1 | 25.00% | 
| Jiri Slaby | 20 | 16.00% | 1 | 25.00% | 
| Matthew Garrett | 1 | 0.80% | 1 | 25.00% | 
| Total | 125 | 100.00% | 4 | 100.00% | 
/**
 *      suspend_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 suspend_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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 46 | 97.87% | 1 | 50.00% | 
| Matthew Garrett | 1 | 2.13% | 1 | 50.00% | 
| Total | 47 | 100.00% | 2 | 100.00% | 
#endif
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cornelia Huck | 407 | 54.78% | 1 | 9.09% | 
| Huang Ying | 204 | 27.46% | 1 | 9.09% | 
| Rafael J. Wysocki | 86 | 11.57% | 3 | 27.27% | 
| Jiri Slaby | 20 | 2.69% | 1 | 9.09% | 
| Matthew Garrett | 12 | 1.62% | 1 | 9.09% | 
| Björn Helgaas | 7 | 0.94% | 1 | 9.09% | 
| Rashika Kheria | 3 | 0.40% | 1 | 9.09% | 
| Tejun Heo | 3 | 0.40% | 1 | 9.09% | 
| Lv Zheng | 1 | 0.13% | 1 | 9.09% | 
| Total | 743 | 100.00% | 11 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.