summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_lpss.c8
-rw-r--r--drivers/acpi/acpi_platform.c4
-rw-r--r--drivers/acpi/resource.c17
-rw-r--r--drivers/dma/acpi-dma.c10
-rw-r--r--include/linux/acpi.h12
-rw-r--r--include/linux/resource_ext.h77
-rw-r--r--kernel/resource.c25
7 files changed, 120 insertions, 33 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 4f3febf8a589..dfd1b8095dad 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -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;
}
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 6ba8beb6b9d2..1284138e42ab 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -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);
}
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 3ea0d17eb951..4752b9939987 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -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.
*
diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c
index de361a156b34..5a635646e05c 100644
--- a/drivers/dma/acpi-dma.c
+++ b/drivers/dma/acpi-dma.c
@@ -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);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e818decb631f..e53822148b6a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -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 *),
diff --git a/include/linux/resource_ext.h b/include/linux/resource_ext.h
new file mode 100644
index 000000000000..e2bf63d881d4
--- /dev/null
+++ b/include/linux/resource_ext.h
@@ -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 */
diff --git a/kernel/resource.c b/kernel/resource.c
index 0bcebffc4e77..19f2357dfda3 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -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"))