resources: Move struct resource_list_entry from ACPI into resource core

Currently ACPI, PCI and pnp all implement the same resource list
management with different data structure. We need to transfer from
one data structure into another when passing resources from one
subsystem into another subsystem. So move struct resource_list_entry
from ACPI into resource core and rename it as resource_entry,
then it could be reused by different subystems and avoid the data
structure conversion.

Introduce dedicated header file resource_ext.h instead of embedding
it into ioport.h to avoid header file inclusion order issues.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Jiang Liu 2015-02-05 13:44:43 +08:00 committed by Rafael J. Wysocki
parent 62d1141ff3
commit 90e9782061
7 changed files with 120 additions and 33 deletions

View file

@ -313,7 +313,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
{
struct lpss_device_desc *dev_desc;
struct lpss_private_data *pdata;
struct resource_list_entry *rentry;
struct resource_entry *rentry;
struct list_head resource_list;
struct platform_device *pdev;
int ret;
@ -333,12 +333,12 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
goto err_out;
list_for_each_entry(rentry, &resource_list, node)
if (resource_type(&rentry->res) == IORESOURCE_MEM) {
if (resource_type(rentry->res) == IORESOURCE_MEM) {
if (dev_desc->prv_size_override)
pdata->mmio_size = dev_desc->prv_size_override;
else
pdata->mmio_size = resource_size(&rentry->res);
pdata->mmio_base = ioremap(rentry->res.start,
pdata->mmio_size = resource_size(rentry->res);
pdata->mmio_base = ioremap(rentry->res->start,
pdata->mmio_size);
break;
}

View file

@ -45,7 +45,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
struct platform_device *pdev = NULL;
struct acpi_device *acpi_parent;
struct platform_device_info pdevinfo;
struct resource_list_entry *rentry;
struct resource_entry *rentry;
struct list_head resource_list;
struct resource *resources = NULL;
int count;
@ -71,7 +71,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
}
count = 0;
list_for_each_entry(rentry, &resource_list, node)
resources[count++] = rentry->res;
resources[count++] = *rentry->res;
acpi_dev_free_resource_list(&resource_list);
}

View file

@ -444,12 +444,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
*/
void acpi_dev_free_resource_list(struct list_head *list)
{
struct resource_list_entry *rentry, *re;
list_for_each_entry_safe(rentry, re, list, node) {
list_del(&rentry->node);
kfree(rentry);
}
resource_list_free(list);
}
EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
@ -464,16 +459,16 @@ struct res_proc_context {
static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
struct res_proc_context *c)
{
struct resource_list_entry *rentry;
struct resource_entry *rentry;
rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
rentry = resource_list_create_entry(NULL, 0);
if (!rentry) {
c->error = -ENOMEM;
return AE_NO_MEMORY;
}
rentry->res = win->res;
*rentry->res = win->res;
rentry->offset = win->offset;
list_add_tail(&rentry->node, c->list);
resource_list_add_tail(rentry, c->list);
c->count++;
return AE_OK;
}
@ -534,7 +529,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
* returned as the final error code.
*
* The resultant struct resource objects are put on the list pointed to by
* @list, that must be empty initially, as members of struct resource_list_entry
* @list, that must be empty initially, as members of struct resource_entry
* objects. Callers of this routine should use %acpi_dev_free_resource_list() to
* free that list.
*

View file

@ -43,7 +43,7 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
{
const struct acpi_csrt_shared_info *si;
struct list_head resource_list;
struct resource_list_entry *rentry;
struct resource_entry *rentry;
resource_size_t mem = 0, irq = 0;
int ret;
@ -56,10 +56,10 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
return 0;
list_for_each_entry(rentry, &resource_list, node) {
if (resource_type(&rentry->res) == IORESOURCE_MEM)
mem = rentry->res.start;
else if (resource_type(&rentry->res) == IORESOURCE_IRQ)
irq = rentry->res.start;
if (resource_type(rentry->res) == IORESOURCE_MEM)
mem = rentry->res->start;
else if (resource_type(rentry->res) == IORESOURCE_IRQ)
irq = rentry->res->start;
}
acpi_dev_free_resource_list(&resource_list);

View file

@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/ioport.h> /* for struct resource */
#include <linux/resource_ext.h>
#include <linux/device.h>
#include <linux/property.h>
@ -285,11 +286,6 @@ extern int pnpacpi_disabled;
#define PXM_INVAL (-1)
struct resource_win {
struct resource res;
resource_size_t offset;
};
bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
bool acpi_dev_resource_address_space(struct acpi_resource *ares,
@ -300,12 +296,6 @@ unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
struct resource *res);
struct resource_list_entry {
struct list_head node;
struct resource res;
resource_size_t offset;
};
void acpi_dev_free_resource_list(struct list_head *list);
int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
int (*preproc)(struct acpi_resource *, void *),

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2015, Intel Corporation
* Author: Jiang Liu <jiang.liu@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _LINUX_RESOURCE_EXT_H
#define _LINUX_RESOURCE_EXT_H
#include <linux/types.h>
#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/slab.h>
/* Represent resource window for bridge devices */
struct resource_win {
struct resource res; /* In master (CPU) address space */
resource_size_t offset; /* Translation offset for bridge */
};
/*
* Common resource list management data structure and interfaces to support
* ACPI, PNP and PCI host bridge etc.
*/
struct resource_entry {
struct list_head node;
struct resource *res; /* In master (CPU) address space */
resource_size_t offset; /* Translation offset for bridge */
struct resource __res; /* Default storage for res */
};
extern struct resource_entry *
resource_list_create_entry(struct resource *res, size_t extra_size);
extern void resource_list_free(struct list_head *head);
static inline void resource_list_add(struct resource_entry *entry,
struct list_head *head)
{
list_add(&entry->node, head);
}
static inline void resource_list_add_tail(struct resource_entry *entry,
struct list_head *head)
{
list_add_tail(&entry->node, head);
}
static inline void resource_list_del(struct resource_entry *entry)
{
list_del(&entry->node);
}
static inline void resource_list_free_entry(struct resource_entry *entry)
{
kfree(entry);
}
static inline void
resource_list_destroy_entry(struct resource_entry *entry)
{
resource_list_del(entry);
resource_list_free_entry(entry);
}
#define resource_list_for_each_entry(entry, list) \
list_for_each_entry((entry), (list), node)
#define resource_list_for_each_entry_safe(entry, tmp, list) \
list_for_each_entry_safe((entry), (tmp), (list), node)
#endif /* _LINUX_RESOURCE_EXT_H */

View file

@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/resource_ext.h>
#include <asm/io.h>
@ -1529,6 +1530,30 @@ int iomem_is_exclusive(u64 addr)
return err;
}
struct resource_entry *resource_list_create_entry(struct resource *res,
size_t extra_size)
{
struct resource_entry *entry;
entry = kzalloc(sizeof(*entry) + extra_size, GFP_KERNEL);
if (entry) {
INIT_LIST_HEAD(&entry->node);
entry->res = res ? res : &entry->__res;
}
return entry;
}
EXPORT_SYMBOL(resource_list_create_entry);
void resource_list_free(struct list_head *head)
{
struct resource_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, head, node)
resource_list_destroy_entry(entry);
}
EXPORT_SYMBOL(resource_list_free);
static int __init strict_iomem(char *str)
{
if (strstr(str, "relaxed"))