All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@avionic-design.de>
To: linux-tegra@vger.kernel.org
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
	Jason Gunthorpe <jgunthorpe@obsidianresearch.com>,
	Russell King <linux@arm.linux.org.uk>,
	Arnd Bergmann <arnd@arndb.de>,
	Stephen Warren <swarren@wwwdotorg.org>,
	linux-pci@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
	linux-kernel@vger.kernel.org,
	Rob Herring <rob.herring@calxeda.com>,
	Grant Likely <grant.likely@secretlab.ca>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Andrew Murray <andrew.murray@arm.com>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/14] lib: Add I/O map cache implementation
Date: Wed,  9 Jan 2013 21:43:05 +0100	[thread overview]
Message-ID: <1357764194-12677-6-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1357764194-12677-1-git-send-email-thierry.reding@avionic-design.de>

The I/O map cache is used to map large regions of physical memory in
smaller chunks to avoid running out of vmalloc()/ioremap() space.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 include/linux/io.h |  12 +++
 lib/ioremap.c      | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 278 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 069e407..c5d296c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -76,4 +76,16 @@ void devm_ioremap_release(struct device *dev, void *res);
 #define arch_has_dev_port()     (1)
 #endif
 
+struct iomap_cache;
+struct resource;
+
+struct iomap_cache *iomap_cache_create(const struct resource *region);
+void iomap_cache_free(struct iomap_cache *cache);
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset);
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr);
+
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region);
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache);
+
 #endif /* _LINUX_IO_H */
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 0c9216c..8a13d97 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -5,11 +5,16 @@
  *
  * (C) Copyright 1995 1996 Linus Torvalds
  */
+
+#include <linux/device.h>
+#include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/export.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 
@@ -92,3 +97,264 @@ int ioremap_page_range(unsigned long addr,
 	return err;
 }
 EXPORT_SYMBOL_GPL(ioremap_page_range);
+
+/**
+ * struct iomap_cache_page - page in an I/O map cache
+ * @region: subregion mapped by the page
+ * @list: chain in cache list
+ * @virt: virtual address of mapped region
+ */
+struct iomap_cache_page {
+	struct resource *region;
+	struct list_head list;
+	void __iomem *virt;
+};
+
+static struct iomap_cache_page *iomap_cache_page_create(void)
+{
+	struct iomap_cache_page *page;
+
+	page = kzalloc(sizeof(*page), GFP_KERNEL);
+	if (!page)
+		return NULL;
+
+	INIT_LIST_HEAD(&page->list);
+
+	return page;
+}
+
+static void iomap_cache_page_unmap(struct iomap_cache_page *page)
+{
+	release_resource(page->region);
+	page->region = NULL;
+
+	iounmap(page->virt);
+	page->virt = NULL;
+}
+
+static void iomap_cache_page_free(struct iomap_cache_page *page)
+{
+	iomap_cache_page_unmap(page);
+	list_del(&page->list);
+	kfree(page);
+}
+
+/**
+ * struct iomap_cache - cache of I/O mapped pages
+ * @region: region mapped by the cache
+ * @pages: list of pages in the cache
+ * @num_pages: number of pages in the cache
+ * @max_pages: maximum number of pages that the cache can map simultaneously
+ */
+struct iomap_cache {
+	struct resource region;
+	struct list_head pages;
+	unsigned int num_pages;
+	unsigned int max_pages;
+};
+
+/**
+ * iomap_cache_create() - create an I/O map cache
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ */
+struct iomap_cache *iomap_cache_create(const struct resource *region)
+{
+	struct iomap_cache *cache;
+
+	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
+	if (!cache)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(&cache->region, region, sizeof(*region));
+	INIT_LIST_HEAD(&cache->pages);
+	cache->num_pages = 0;
+	cache->max_pages = 1;
+
+	return cache;
+}
+
+/**
+ * iomap_cache_free() - free an I/O map cache
+ * @cache: I/O map cache
+ */
+void iomap_cache_free(struct iomap_cache *cache)
+{
+	struct iomap_cache_page *page, *tmp;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry_safe(page, tmp, &cache->pages, list)
+		iomap_cache_page_free(page);
+
+	kfree(cache);
+}
+
+/**
+ * iomap_cache_map() - map a given offset in the cache's region
+ * @cache: I/O map cache
+ * @offset: offset into the cache's region of the address to map
+ *
+ * Returns the virtual address of mapped offset into the cache's region or
+ * NULL if the offset is outside of the region or if not enough memory is
+ * available to map the page.
+ */
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset)
+{
+	struct iomap_cache_page *page;
+	struct resource *region;
+	unsigned long phys;
+
+	if (!cache || offset >= resource_size(&cache->region))
+		return NULL;
+
+	phys = cache->region.start + (offset & PAGE_MASK);
+
+	list_for_each_entry(page, &cache->pages, list) {
+		resource_size_t start, end;
+
+		if (!page->region || !page->virt)
+			continue;
+
+		start = page->region->start - cache->region.start;
+		end = page->region->end - cache->region.start;
+
+		/* address is within an already mapped page */
+		if (offset >= start && offset <= end) {
+			/* move page to end of the LRU list */
+			list_del_init(&page->list);
+			list_add_tail(&page->list, &cache->pages);
+			goto out;
+		}
+	}
+
+	/* find an unmapped page */
+	list_for_each_entry(page, &cache->pages, list) {
+		if (!page->region || !page->virt) {
+			list_del_init(&page->list);
+			break;
+		}
+	}
+
+	/* no unmapped page found */
+	if (&page->list == &cache->pages) {
+		/* add a new page if more space is available */
+		if (cache->num_pages < cache->max_pages) {
+			page = iomap_cache_page_create();
+			if (!page)
+				return NULL;
+
+			cache->num_pages++;
+		} else {
+			/*
+			 * If all pages are in use and there's no space left
+			 * for a new one, evict the first page in the list.
+			 */
+			page = list_first_entry(&cache->pages,
+						struct iomap_cache_page,
+						list);
+			iomap_cache_page_unmap(page);
+			list_del_init(&page->list);
+		}
+	}
+
+	/* insert page at the end of the LRU list */
+	list_add_tail(&page->list, &cache->pages);
+
+	region = __request_region(&cache->region, phys, PAGE_SIZE, NULL,
+				  cache->region.flags);
+	if (!region)
+		return NULL;
+
+	page->virt = ioremap(region->start, resource_size(region));
+	if (!page->virt) {
+		release_resource(region);
+		return NULL;
+	}
+
+	page->region = region;
+
+out:
+	return page->virt + (offset & ~PAGE_MASK);
+}
+
+/**
+ * iomap_cache_unmap() - remove a mapping from the cache
+ * @cache: I/O map cache
+ * @addr: virtual address of the mapping to remove
+ */
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr)
+{
+	struct iomap_cache_page *page;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry(page, &cache->pages, list) {
+		if (page->virt == addr) {
+			iomap_cache_page_unmap(page);
+			break;
+		}
+	}
+}
+
+static void devm_iomap_cache_release(struct device *dev, void *res)
+{
+	iomap_cache_free(*(struct iomap_cache **)res);
+}
+
+static int devm_iomap_cache_match(struct device *dev, void *res, void *data)
+{
+	struct iomap_cache **p = res;
+
+	if (WARN_ON(!p || !*p))
+		return 0;
+
+	return *p == data;
+}
+
+/**
+ * devm_iomap_cache_create() - create an I/O map cache
+ * @dev: device to attach this I/O map cache to
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ *
+ * This function is a device-managed version of iomap_cache_create() which
+ * will automatically be freed when the device disappears.
+ */
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region)
+{
+	struct iomap_cache **ptr, *cache;
+
+	ptr = devres_alloc(devm_iomap_cache_release, sizeof(**ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	cache = iomap_cache_create(region);
+	if (IS_ERR(cache)) {
+		devres_free(ptr);
+		return cache;
+	}
+
+	*ptr = cache;
+	devres_add(dev, ptr);
+
+	return cache;
+}
+
+/**
+ * devm_iomap_cache_free() - free an I/O map cache
+ * @dev: device that this I/O map cached was attached to
+ * @cache: I/O map cache
+ */
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache)
+{
+	WARN_ON(devres_release(dev, devm_iomap_cache_release,
+			       devm_iomap_cache_match, cache));
+}
-- 
1.8.1

WARNING: multiple messages have this Message-ID (diff)
From: Thierry Reding <thierry.reding@avionic-design.de>
To: linux-tegra@vger.kernel.org
Cc: Grant Likely <grant.likely@secretlab.ca>,
	Rob Herring <rob.herring@calxeda.com>,
	Russell King <linux@arm.linux.org.uk>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Andrew Murray <andrew.murray@arm.com>,
	Jason Gunthorpe <jgunthorpe@obsidianresearch.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
	devicetree-discuss@lists.ozlabs.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org
Subject: [PATCH 05/14] lib: Add I/O map cache implementation
Date: Wed,  9 Jan 2013 21:43:05 +0100	[thread overview]
Message-ID: <1357764194-12677-6-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1357764194-12677-1-git-send-email-thierry.reding@avionic-design.de>

The I/O map cache is used to map large regions of physical memory in
smaller chunks to avoid running out of vmalloc()/ioremap() space.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 include/linux/io.h |  12 +++
 lib/ioremap.c      | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 278 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 069e407..c5d296c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -76,4 +76,16 @@ void devm_ioremap_release(struct device *dev, void *res);
 #define arch_has_dev_port()     (1)
 #endif
 
+struct iomap_cache;
+struct resource;
+
+struct iomap_cache *iomap_cache_create(const struct resource *region);
+void iomap_cache_free(struct iomap_cache *cache);
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset);
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr);
+
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region);
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache);
+
 #endif /* _LINUX_IO_H */
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 0c9216c..8a13d97 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -5,11 +5,16 @@
  *
  * (C) Copyright 1995 1996 Linus Torvalds
  */
+
+#include <linux/device.h>
+#include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/export.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 
@@ -92,3 +97,264 @@ int ioremap_page_range(unsigned long addr,
 	return err;
 }
 EXPORT_SYMBOL_GPL(ioremap_page_range);
+
+/**
+ * struct iomap_cache_page - page in an I/O map cache
+ * @region: subregion mapped by the page
+ * @list: chain in cache list
+ * @virt: virtual address of mapped region
+ */
+struct iomap_cache_page {
+	struct resource *region;
+	struct list_head list;
+	void __iomem *virt;
+};
+
+static struct iomap_cache_page *iomap_cache_page_create(void)
+{
+	struct iomap_cache_page *page;
+
+	page = kzalloc(sizeof(*page), GFP_KERNEL);
+	if (!page)
+		return NULL;
+
+	INIT_LIST_HEAD(&page->list);
+
+	return page;
+}
+
+static void iomap_cache_page_unmap(struct iomap_cache_page *page)
+{
+	release_resource(page->region);
+	page->region = NULL;
+
+	iounmap(page->virt);
+	page->virt = NULL;
+}
+
+static void iomap_cache_page_free(struct iomap_cache_page *page)
+{
+	iomap_cache_page_unmap(page);
+	list_del(&page->list);
+	kfree(page);
+}
+
+/**
+ * struct iomap_cache - cache of I/O mapped pages
+ * @region: region mapped by the cache
+ * @pages: list of pages in the cache
+ * @num_pages: number of pages in the cache
+ * @max_pages: maximum number of pages that the cache can map simultaneously
+ */
+struct iomap_cache {
+	struct resource region;
+	struct list_head pages;
+	unsigned int num_pages;
+	unsigned int max_pages;
+};
+
+/**
+ * iomap_cache_create() - create an I/O map cache
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ */
+struct iomap_cache *iomap_cache_create(const struct resource *region)
+{
+	struct iomap_cache *cache;
+
+	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
+	if (!cache)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(&cache->region, region, sizeof(*region));
+	INIT_LIST_HEAD(&cache->pages);
+	cache->num_pages = 0;
+	cache->max_pages = 1;
+
+	return cache;
+}
+
+/**
+ * iomap_cache_free() - free an I/O map cache
+ * @cache: I/O map cache
+ */
+void iomap_cache_free(struct iomap_cache *cache)
+{
+	struct iomap_cache_page *page, *tmp;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry_safe(page, tmp, &cache->pages, list)
+		iomap_cache_page_free(page);
+
+	kfree(cache);
+}
+
+/**
+ * iomap_cache_map() - map a given offset in the cache's region
+ * @cache: I/O map cache
+ * @offset: offset into the cache's region of the address to map
+ *
+ * Returns the virtual address of mapped offset into the cache's region or
+ * NULL if the offset is outside of the region or if not enough memory is
+ * available to map the page.
+ */
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset)
+{
+	struct iomap_cache_page *page;
+	struct resource *region;
+	unsigned long phys;
+
+	if (!cache || offset >= resource_size(&cache->region))
+		return NULL;
+
+	phys = cache->region.start + (offset & PAGE_MASK);
+
+	list_for_each_entry(page, &cache->pages, list) {
+		resource_size_t start, end;
+
+		if (!page->region || !page->virt)
+			continue;
+
+		start = page->region->start - cache->region.start;
+		end = page->region->end - cache->region.start;
+
+		/* address is within an already mapped page */
+		if (offset >= start && offset <= end) {
+			/* move page to end of the LRU list */
+			list_del_init(&page->list);
+			list_add_tail(&page->list, &cache->pages);
+			goto out;
+		}
+	}
+
+	/* find an unmapped page */
+	list_for_each_entry(page, &cache->pages, list) {
+		if (!page->region || !page->virt) {
+			list_del_init(&page->list);
+			break;
+		}
+	}
+
+	/* no unmapped page found */
+	if (&page->list == &cache->pages) {
+		/* add a new page if more space is available */
+		if (cache->num_pages < cache->max_pages) {
+			page = iomap_cache_page_create();
+			if (!page)
+				return NULL;
+
+			cache->num_pages++;
+		} else {
+			/*
+			 * If all pages are in use and there's no space left
+			 * for a new one, evict the first page in the list.
+			 */
+			page = list_first_entry(&cache->pages,
+						struct iomap_cache_page,
+						list);
+			iomap_cache_page_unmap(page);
+			list_del_init(&page->list);
+		}
+	}
+
+	/* insert page at the end of the LRU list */
+	list_add_tail(&page->list, &cache->pages);
+
+	region = __request_region(&cache->region, phys, PAGE_SIZE, NULL,
+				  cache->region.flags);
+	if (!region)
+		return NULL;
+
+	page->virt = ioremap(region->start, resource_size(region));
+	if (!page->virt) {
+		release_resource(region);
+		return NULL;
+	}
+
+	page->region = region;
+
+out:
+	return page->virt + (offset & ~PAGE_MASK);
+}
+
+/**
+ * iomap_cache_unmap() - remove a mapping from the cache
+ * @cache: I/O map cache
+ * @addr: virtual address of the mapping to remove
+ */
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr)
+{
+	struct iomap_cache_page *page;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry(page, &cache->pages, list) {
+		if (page->virt == addr) {
+			iomap_cache_page_unmap(page);
+			break;
+		}
+	}
+}
+
+static void devm_iomap_cache_release(struct device *dev, void *res)
+{
+	iomap_cache_free(*(struct iomap_cache **)res);
+}
+
+static int devm_iomap_cache_match(struct device *dev, void *res, void *data)
+{
+	struct iomap_cache **p = res;
+
+	if (WARN_ON(!p || !*p))
+		return 0;
+
+	return *p == data;
+}
+
+/**
+ * devm_iomap_cache_create() - create an I/O map cache
+ * @dev: device to attach this I/O map cache to
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ *
+ * This function is a device-managed version of iomap_cache_create() which
+ * will automatically be freed when the device disappears.
+ */
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region)
+{
+	struct iomap_cache **ptr, *cache;
+
+	ptr = devres_alloc(devm_iomap_cache_release, sizeof(**ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	cache = iomap_cache_create(region);
+	if (IS_ERR(cache)) {
+		devres_free(ptr);
+		return cache;
+	}
+
+	*ptr = cache;
+	devres_add(dev, ptr);
+
+	return cache;
+}
+
+/**
+ * devm_iomap_cache_free() - free an I/O map cache
+ * @dev: device that this I/O map cached was attached to
+ * @cache: I/O map cache
+ */
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache)
+{
+	WARN_ON(devres_release(dev, devm_iomap_cache_release,
+			       devm_iomap_cache_match, cache));
+}
-- 
1.8.1


WARNING: multiple messages have this Message-ID (diff)
From: thierry.reding@avionic-design.de (Thierry Reding)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/14] lib: Add I/O map cache implementation
Date: Wed,  9 Jan 2013 21:43:05 +0100	[thread overview]
Message-ID: <1357764194-12677-6-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1357764194-12677-1-git-send-email-thierry.reding@avionic-design.de>

The I/O map cache is used to map large regions of physical memory in
smaller chunks to avoid running out of vmalloc()/ioremap() space.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 include/linux/io.h |  12 +++
 lib/ioremap.c      | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 278 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 069e407..c5d296c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -76,4 +76,16 @@ void devm_ioremap_release(struct device *dev, void *res);
 #define arch_has_dev_port()     (1)
 #endif
 
+struct iomap_cache;
+struct resource;
+
+struct iomap_cache *iomap_cache_create(const struct resource *region);
+void iomap_cache_free(struct iomap_cache *cache);
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset);
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr);
+
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region);
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache);
+
 #endif /* _LINUX_IO_H */
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 0c9216c..8a13d97 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -5,11 +5,16 @@
  *
  * (C) Copyright 1995 1996 Linus Torvalds
  */
+
+#include <linux/device.h>
+#include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/export.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 
@@ -92,3 +97,264 @@ int ioremap_page_range(unsigned long addr,
 	return err;
 }
 EXPORT_SYMBOL_GPL(ioremap_page_range);
+
+/**
+ * struct iomap_cache_page - page in an I/O map cache
+ * @region: subregion mapped by the page
+ * @list: chain in cache list
+ * @virt: virtual address of mapped region
+ */
+struct iomap_cache_page {
+	struct resource *region;
+	struct list_head list;
+	void __iomem *virt;
+};
+
+static struct iomap_cache_page *iomap_cache_page_create(void)
+{
+	struct iomap_cache_page *page;
+
+	page = kzalloc(sizeof(*page), GFP_KERNEL);
+	if (!page)
+		return NULL;
+
+	INIT_LIST_HEAD(&page->list);
+
+	return page;
+}
+
+static void iomap_cache_page_unmap(struct iomap_cache_page *page)
+{
+	release_resource(page->region);
+	page->region = NULL;
+
+	iounmap(page->virt);
+	page->virt = NULL;
+}
+
+static void iomap_cache_page_free(struct iomap_cache_page *page)
+{
+	iomap_cache_page_unmap(page);
+	list_del(&page->list);
+	kfree(page);
+}
+
+/**
+ * struct iomap_cache - cache of I/O mapped pages
+ * @region: region mapped by the cache
+ * @pages: list of pages in the cache
+ * @num_pages: number of pages in the cache
+ * @max_pages: maximum number of pages that the cache can map simultaneously
+ */
+struct iomap_cache {
+	struct resource region;
+	struct list_head pages;
+	unsigned int num_pages;
+	unsigned int max_pages;
+};
+
+/**
+ * iomap_cache_create() - create an I/O map cache
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ */
+struct iomap_cache *iomap_cache_create(const struct resource *region)
+{
+	struct iomap_cache *cache;
+
+	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
+	if (!cache)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(&cache->region, region, sizeof(*region));
+	INIT_LIST_HEAD(&cache->pages);
+	cache->num_pages = 0;
+	cache->max_pages = 1;
+
+	return cache;
+}
+
+/**
+ * iomap_cache_free() - free an I/O map cache
+ * @cache: I/O map cache
+ */
+void iomap_cache_free(struct iomap_cache *cache)
+{
+	struct iomap_cache_page *page, *tmp;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry_safe(page, tmp, &cache->pages, list)
+		iomap_cache_page_free(page);
+
+	kfree(cache);
+}
+
+/**
+ * iomap_cache_map() - map a given offset in the cache's region
+ * @cache: I/O map cache
+ * @offset: offset into the cache's region of the address to map
+ *
+ * Returns the virtual address of mapped offset into the cache's region or
+ * NULL if the offset is outside of the region or if not enough memory is
+ * available to map the page.
+ */
+void __iomem *iomap_cache_map(struct iomap_cache *cache, unsigned long offset)
+{
+	struct iomap_cache_page *page;
+	struct resource *region;
+	unsigned long phys;
+
+	if (!cache || offset >= resource_size(&cache->region))
+		return NULL;
+
+	phys = cache->region.start + (offset & PAGE_MASK);
+
+	list_for_each_entry(page, &cache->pages, list) {
+		resource_size_t start, end;
+
+		if (!page->region || !page->virt)
+			continue;
+
+		start = page->region->start - cache->region.start;
+		end = page->region->end - cache->region.start;
+
+		/* address is within an already mapped page */
+		if (offset >= start && offset <= end) {
+			/* move page to end of the LRU list */
+			list_del_init(&page->list);
+			list_add_tail(&page->list, &cache->pages);
+			goto out;
+		}
+	}
+
+	/* find an unmapped page */
+	list_for_each_entry(page, &cache->pages, list) {
+		if (!page->region || !page->virt) {
+			list_del_init(&page->list);
+			break;
+		}
+	}
+
+	/* no unmapped page found */
+	if (&page->list == &cache->pages) {
+		/* add a new page if more space is available */
+		if (cache->num_pages < cache->max_pages) {
+			page = iomap_cache_page_create();
+			if (!page)
+				return NULL;
+
+			cache->num_pages++;
+		} else {
+			/*
+			 * If all pages are in use and there's no space left
+			 * for a new one, evict the first page in the list.
+			 */
+			page = list_first_entry(&cache->pages,
+						struct iomap_cache_page,
+						list);
+			iomap_cache_page_unmap(page);
+			list_del_init(&page->list);
+		}
+	}
+
+	/* insert page at the end of the LRU list */
+	list_add_tail(&page->list, &cache->pages);
+
+	region = __request_region(&cache->region, phys, PAGE_SIZE, NULL,
+				  cache->region.flags);
+	if (!region)
+		return NULL;
+
+	page->virt = ioremap(region->start, resource_size(region));
+	if (!page->virt) {
+		release_resource(region);
+		return NULL;
+	}
+
+	page->region = region;
+
+out:
+	return page->virt + (offset & ~PAGE_MASK);
+}
+
+/**
+ * iomap_cache_unmap() - remove a mapping from the cache
+ * @cache: I/O map cache
+ * @addr: virtual address of the mapping to remove
+ */
+void iomap_cache_unmap(struct iomap_cache *cache, void __iomem *addr)
+{
+	struct iomap_cache_page *page;
+
+	if (!cache)
+		return;
+
+	list_for_each_entry(page, &cache->pages, list) {
+		if (page->virt == addr) {
+			iomap_cache_page_unmap(page);
+			break;
+		}
+	}
+}
+
+static void devm_iomap_cache_release(struct device *dev, void *res)
+{
+	iomap_cache_free(*(struct iomap_cache **)res);
+}
+
+static int devm_iomap_cache_match(struct device *dev, void *res, void *data)
+{
+	struct iomap_cache **p = res;
+
+	if (WARN_ON(!p || !*p))
+		return 0;
+
+	return *p == data;
+}
+
+/**
+ * devm_iomap_cache_create() - create an I/O map cache
+ * @dev: device to attach this I/O map cache to
+ * @region: memory region to map
+ *
+ * Returns a new I/O map cache that can be used to map the given region on a
+ * page by page basis. On failure, a negative error code is returned.
+ *
+ * This function is a device-managed version of iomap_cache_create() which
+ * will automatically be freed when the device disappears.
+ */
+struct iomap_cache *devm_iomap_cache_create(struct device *dev,
+					    const struct resource *region)
+{
+	struct iomap_cache **ptr, *cache;
+
+	ptr = devres_alloc(devm_iomap_cache_release, sizeof(**ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	cache = iomap_cache_create(region);
+	if (IS_ERR(cache)) {
+		devres_free(ptr);
+		return cache;
+	}
+
+	*ptr = cache;
+	devres_add(dev, ptr);
+
+	return cache;
+}
+
+/**
+ * devm_iomap_cache_free() - free an I/O map cache
+ * @dev: device that this I/O map cached was attached to
+ * @cache: I/O map cache
+ */
+void devm_iomap_cache_free(struct device *dev, struct iomap_cache *cache)
+{
+	WARN_ON(devres_release(dev, devm_iomap_cache_release,
+			       devm_iomap_cache_match, cache));
+}
-- 
1.8.1

  parent reply	other threads:[~2013-01-09 20:43 UTC|newest]

Thread overview: 267+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-09 20:43 [PATCH 00/14] Rewrite Tegra PCIe driver Thierry Reding
2013-01-09 20:43 ` Thierry Reding
2013-01-09 20:43 ` [PATCH 02/14] of/pci: Add of_pci_get_devfn() function Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-3-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-11  0:09     ` Stephen Warren
2013-01-11  0:09       ` Stephen Warren
2013-01-11  0:09       ` Stephen Warren
2013-01-11  4:06       ` Thierry Reding
2013-01-11  4:06         ` Thierry Reding
2013-01-09 20:43 ` Thierry Reding [this message]
2013-01-09 20:43   ` [PATCH 05/14] lib: Add I/O map cache implementation Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-6-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-09 21:19     ` Arnd Bergmann
2013-01-09 21:19       ` Arnd Bergmann
2013-01-09 21:19       ` Arnd Bergmann
2013-01-09 21:54       ` Thierry Reding
2013-01-09 21:54         ` Thierry Reding
     [not found]         ` <20130109215428.GA13648-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-09 22:10           ` Arnd Bergmann
2013-01-09 22:10             ` Arnd Bergmann
2013-01-09 22:10             ` Arnd Bergmann
     [not found]             ` <201301092210.49452.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-09 23:12               ` Stephen Warren
2013-01-09 23:12                 ` Stephen Warren
2013-01-09 23:12                 ` Stephen Warren
2013-01-09 23:17                 ` Jason Gunthorpe
2013-01-09 23:17                   ` Jason Gunthorpe
     [not found]                   ` <20130109231758.GA27065-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2013-01-10  7:19                     ` Thierry Reding
2013-01-10  7:19                       ` Thierry Reding
2013-01-10  7:19                       ` Thierry Reding
     [not found]                       ` <20130110071937.GG15212-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-10  9:17                         ` Arnd Bergmann
2013-01-10  9:17                           ` Arnd Bergmann
2013-01-10  9:17                           ` Arnd Bergmann
     [not found]                           ` <201301100917.19577.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-10 10:25                             ` Thierry Reding
2013-01-10 10:25                               ` Thierry Reding
2013-01-10 10:25                               ` Thierry Reding
     [not found]                               ` <20130110102544.GA5546-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-10 18:20                                 ` Jason Gunthorpe
2013-01-10 18:20                                   ` Jason Gunthorpe
2013-01-10 18:20                                   ` Jason Gunthorpe
     [not found]                                   ` <20130110182007.GA28004-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2013-01-10 18:55                                     ` Thierry Reding
2013-01-10 18:55                                       ` Thierry Reding
2013-01-10 18:55                                       ` Thierry Reding
2013-01-10 19:03                                       ` Thierry Reding
2013-01-10 19:03                                         ` Thierry Reding
2013-01-10 19:24                                         ` Jason Gunthorpe
2013-01-10 19:24                                           ` Jason Gunthorpe
     [not found]                                           ` <20130110192417.GA18478-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2013-01-10 20:20                                             ` Thierry Reding
2013-01-10 20:20                                               ` Thierry Reding
2013-01-10 20:20                                               ` Thierry Reding
     [not found]                                               ` <20130110202007.GA26139-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-10 21:06                                                 ` Jason Gunthorpe
2013-01-10 21:06                                                   ` Jason Gunthorpe
2013-01-10 21:06                                                   ` Jason Gunthorpe
2013-01-16 10:18                                             ` Thierry Reding
2013-01-16 10:18                                               ` Thierry Reding
2013-01-16 10:18                                               ` Thierry Reding
     [not found]                                               ` <20130116101822.GA17706-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-16 11:25                                                 ` Russell King - ARM Linux
2013-01-16 11:25                                                   ` Russell King - ARM Linux
2013-01-16 11:25                                                   ` Russell King - ARM Linux
     [not found]                                                   ` <20130116112556.GR23505-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2013-01-16 11:52                                                     ` Thierry Reding
2013-01-16 11:52                                                       ` Thierry Reding
2013-01-16 11:52                                                       ` Thierry Reding
2013-01-10 18:26                                 ` Arnd Bergmann
2013-01-10 18:26                                   ` Arnd Bergmann
2013-01-10 18:26                                   ` Arnd Bergmann
     [not found]                                   ` <201301101826.56248.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-10 18:57                                     ` Thierry Reding
2013-01-10 18:57                                       ` Thierry Reding
2013-01-10 18:57                                       ` Thierry Reding
2013-01-10  7:10               ` Thierry Reding
2013-01-10  7:10                 ` Thierry Reding
2013-01-10  7:10                 ` Thierry Reding
2013-01-09 21:28     ` Russell King - ARM Linux
2013-01-09 21:28       ` Russell King - ARM Linux
2013-01-09 21:28       ` Russell King - ARM Linux
     [not found]       ` <20130109212847.GT3931-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2013-01-09 21:57         ` Thierry Reding
2013-01-09 21:57           ` Thierry Reding
2013-01-09 21:57           ` Thierry Reding
     [not found] ` <1357764194-12677-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-09 20:43   ` [PATCH 01/14] of/pci: Provide support for parsing PCI DT ranges property Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-11  0:06     ` Stephen Warren
2013-01-11  0:06       ` Stephen Warren
     [not found]       ` <50EF5798.6040405-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-01-11  4:02         ` Thierry Reding
2013-01-11  4:02           ` Thierry Reding
2013-01-11  4:02           ` Thierry Reding
2013-01-09 20:43   ` [PATCH 03/14] of/pci: Add of_pci_get_bus() function Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43   ` [PATCH 04/14] of/pci: Add of_pci_parse_bus_range() function Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43   ` [PATCH 06/14] ARM: pci: Keep pci_common_init() around after init Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
     [not found]     ` <1357764194-12677-7-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-02-05 20:41       ` Thierry Reding
2013-02-05 20:41         ` Thierry Reding
2013-02-05 20:41         ` Thierry Reding
     [not found]         ` <20130205204147.GA29726-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2013-02-06 16:30           ` Russell King - ARM Linux
2013-02-06 16:30             ` Russell King - ARM Linux
2013-02-06 16:30             ` Russell King - ARM Linux
     [not found]             ` <20130206163041.GG17833-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2013-02-06 19:35               ` Thierry Reding
2013-02-06 19:35                 ` Thierry Reding
2013-02-06 19:35                 ` Thierry Reding
2013-02-06  8:36       ` Thomas Petazzoni
2013-02-06  8:36         ` Thomas Petazzoni
2013-02-06  8:36         ` Thomas Petazzoni
2013-02-06 16:38       ` Linus Walleij
2013-02-06 16:38         ` Linus Walleij
2013-02-06 16:38         ` Linus Walleij
2013-02-07  0:54         ` Arnd Bergmann
2013-02-07  0:54           ` Arnd Bergmann
2013-02-06 17:07           ` Linus Walleij
2013-02-06 17:07             ` Linus Walleij
2013-02-06 17:07             ` Linus Walleij
2013-02-07  1:20             ` Arnd Bergmann
2013-02-07  1:20               ` Arnd Bergmann
2013-02-07  1:20               ` Arnd Bergmann
2013-01-09 20:43   ` [PATCH 07/14] ARM: pci: Allow passing per-controller private data Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43   ` [PATCH 08/14] ARM: tegra: Move tegra_pcie_xclk_clamp() to PMC Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43   ` [PATCH 11/14] ARM: tegra: tamonten: Add PCIe support Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
     [not found]     ` <1357764194-12677-12-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-09 21:23       ` Arnd Bergmann
2013-01-09 21:23         ` Arnd Bergmann
2013-01-09 21:23         ` Arnd Bergmann
     [not found]         ` <201301092123.37491.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-10 20:21           ` Thierry Reding
2013-01-10 20:21             ` Thierry Reding
2013-01-10 20:21             ` Thierry Reding
2013-01-09 20:43   ` [PATCH 14/14] ARM: tegra: trimslice: Initialize PCIe from DT Thierry Reding
2013-01-09 20:43     ` Thierry Reding
2013-01-09 20:43     ` Thierry Reding
     [not found]     ` <1357764194-12677-15-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-10 23:56       ` Stephen Warren
2013-01-10 23:56         ` Stephen Warren
2013-01-10 23:56         ` Stephen Warren
     [not found]         ` <50EF5537.6080602-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-01-11 18:48           ` Thierry Reding
2013-01-11 18:48             ` Thierry Reding
2013-01-11 18:48             ` Thierry Reding
2013-01-09 21:25   ` [PATCH 00/14] Rewrite Tegra PCIe driver Thomas Petazzoni
2013-01-09 21:25     ` Thomas Petazzoni
2013-01-09 21:25     ` Thomas Petazzoni
2013-01-10  6:55     ` Thierry Reding
2013-01-10  6:55       ` Thierry Reding
2013-01-10  6:55       ` Thierry Reding
2013-01-10  8:34       ` Thomas Petazzoni
2013-01-10  8:34         ` Thomas Petazzoni
2013-03-06 18:16   ` Murali Karicheri
2013-01-09 20:43 ` [PATCH 09/14] ARM: tegra: Move pmc.h to include/mach Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-10-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-11  0:15     ` Stephen Warren
2013-01-11  0:15       ` Stephen Warren
2013-01-11  0:15       ` Stephen Warren
     [not found]       ` <50EF598B.2030307-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-01-11  4:08         ` Thierry Reding
2013-01-11  4:08           ` Thierry Reding
2013-01-11  4:08           ` Thierry Reding
2013-01-09 20:43 ` [PATCH 10/14] PCI: tegra: Move PCIe driver to drivers/pci/host Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-11-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-09 21:22     ` Arnd Bergmann
2013-01-09 21:22       ` Arnd Bergmann
2013-01-09 21:22       ` Arnd Bergmann
     [not found]       ` <201301092122.08011.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-09 21:58         ` Thierry Reding
2013-01-09 21:58           ` Thierry Reding
2013-01-09 21:58           ` Thierry Reding
2013-01-09 22:03           ` Arnd Bergmann
2013-01-09 22:03             ` Arnd Bergmann
2013-01-11  0:48     ` Stephen Warren
2013-01-11  0:48       ` Stephen Warren
2013-01-11  0:48       ` Stephen Warren
     [not found]       ` <50EF616E.7040609-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-01-11  3:52         ` Thierry Reding
2013-01-11  3:52           ` Thierry Reding
2013-01-11  3:52           ` Thierry Reding
2013-01-11 20:34           ` Stephen Warren
2013-01-11 20:34             ` Stephen Warren
2013-02-13 23:11     ` Thomas Petazzoni
2013-02-13 23:11       ` Thomas Petazzoni
2013-02-13 23:11       ` Thomas Petazzoni
2013-01-10 23:54   ` Stephen Warren
2013-01-10 23:54     ` Stephen Warren
2013-01-11  3:40     ` Thierry Reding
2013-01-11  3:40       ` Thierry Reding
     [not found]       ` <20130111034015.GA28094-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-11 15:36         ` Arnd Bergmann
2013-01-11 15:36           ` Arnd Bergmann
2013-01-11 15:36           ` Arnd Bergmann
     [not found]           ` <201301111536.14799.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-11 15:45             ` Thierry Reding
2013-01-11 15:45               ` Thierry Reding
2013-01-11 15:45               ` Thierry Reding
     [not found]               ` <20130111154516.GA25335-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-12 12:36                 ` Thierry Reding
2013-01-12 12:36                   ` Thierry Reding
2013-01-12 12:36                   ` Thierry Reding
2013-01-12 21:12                   ` Arnd Bergmann
2013-01-12 21:12                     ` Arnd Bergmann
2013-01-13  9:58                     ` Thierry Reding
2013-01-13  9:58                       ` Thierry Reding
     [not found]                       ` <20130113095806.GA31966-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-14  9:57                         ` Andrew Murray
2013-01-14  9:57                           ` Andrew Murray
2013-01-14  9:57                           ` Andrew Murray
2013-01-14  9:57                           ` Andrew Murray
     [not found]                           ` <20130114095706.GA23467-5wv7dgnIgG8@public.gmane.org>
2013-01-15 12:08                             ` Thierry Reding
2013-01-15 12:08                               ` Thierry Reding
2013-01-15 12:08                               ` Thierry Reding
2013-01-15 12:08                               ` Thierry Reding
2013-01-15 12:44                               ` Arnd Bergmann
2013-01-15 12:44                                 ` Arnd Bergmann
2013-01-15 12:44                                 ` Arnd Bergmann
     [not found]                                 ` <201301151244.12767.arnd-r2nGTMty4D4@public.gmane.org>
2013-01-15 15:40                                   ` Andrew Murray
2013-01-15 15:40                                     ` Andrew Murray
2013-01-15 15:40                                     ` Andrew Murray
2013-01-15 15:40                                     ` Andrew Murray
     [not found]                                     ` <20130115154038.GA11241-5wv7dgnIgG8@public.gmane.org>
2013-01-15 21:14                                       ` Thierry Reding
2013-01-15 21:14                                         ` Thierry Reding
2013-01-15 21:14                                         ` Thierry Reding
2013-01-15 21:14                                         ` Thierry Reding
2013-01-16 14:00                                         ` Arnd Bergmann
2013-01-16 14:00                                           ` Arnd Bergmann
2013-01-16 14:00                                           ` Arnd Bergmann
2013-01-16 16:17                                           ` Andrew Murray
2013-01-16 16:17                                             ` Andrew Murray
2013-01-16 16:17                                             ` Andrew Murray
2013-01-16 18:31                                             ` Thierry Reding
2013-01-16 18:31                                               ` Thierry Reding
2013-01-16 18:31                                               ` Thierry Reding
2013-01-17 15:42                                               ` Andrew Murray
2013-01-17 15:42                                                 ` Andrew Murray
2013-01-17 15:42                                                 ` Andrew Murray
     [not found]                                                 ` <20130117154236.GA25943-5wv7dgnIgG8@public.gmane.org>
2013-01-17 16:05                                                   ` Thierry Reding
2013-01-17 16:05                                                     ` Thierry Reding
2013-01-17 16:05                                                     ` Thierry Reding
2013-01-17 16:05                                                     ` Thierry Reding
2013-01-17 16:22                                                     ` Andrew Murray
2013-01-17 16:22                                                       ` Andrew Murray
2013-01-17 16:22                                                       ` Andrew Murray
     [not found]                                                       ` <20130117162218.GA29016-5wv7dgnIgG8@public.gmane.org>
2013-01-17 20:30                                                         ` Thierry Reding
2013-01-17 20:30                                                           ` Thierry Reding
2013-01-17 20:30                                                           ` Thierry Reding
2013-01-17 20:30                                                           ` Thierry Reding
2013-01-18  9:18                                                           ` Andrew Murray
2013-01-18  9:18                                                             ` Andrew Murray
2013-01-18  9:18                                                             ` Andrew Murray
2013-01-22 19:29                                                         ` Jason Gunthorpe
2013-01-22 19:29                                                           ` Jason Gunthorpe
2013-01-22 19:29                                                           ` Jason Gunthorpe
2013-01-22 19:29                                                           ` Jason Gunthorpe
2013-01-29 13:31                                                           ` Andrew Murray
2013-01-29 13:31                                                             ` Andrew Murray
2013-01-29 13:31                                                             ` Andrew Murray
2013-01-18  9:56   ` Andrew Murray
2013-01-18  9:56     ` Andrew Murray
2013-01-18  9:56     ` Andrew Murray
     [not found]     ` <20130118095620.GA7552-5wv7dgnIgG8@public.gmane.org>
2013-01-18 10:09       ` Thierry Reding
2013-01-18 10:09         ` Thierry Reding
2013-01-18 10:09         ` Thierry Reding
2013-01-18 10:09         ` Thierry Reding
2013-01-09 20:43 ` [PATCH 12/14] ARM: tegra: tec: Add PCIe support Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-13-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-11  0:22     ` Stephen Warren
2013-01-11  0:22       ` Stephen Warren
2013-01-11  0:22       ` Stephen Warren
2013-01-11  4:34       ` Thierry Reding
2013-01-11  4:34         ` Thierry Reding
2013-01-09 20:43 ` [PATCH 13/14] ARM: tegra: harmony: Initialize PCIe from DT Thierry Reding
2013-01-09 20:43   ` Thierry Reding
2013-01-09 20:43   ` Thierry Reding
     [not found]   ` <1357764194-12677-14-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2013-01-10 23:58     ` Stephen Warren
2013-01-10 23:58       ` Stephen Warren
2013-01-10 23:58       ` Stephen Warren
2013-01-28 18:15 ` [PATCH 00/14] Rewrite Tegra PCIe driver Bjorn Helgaas
2013-01-28 18:15   ` Bjorn Helgaas

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=1357764194-12677-6-git-send-email-thierry.reding@avionic-design.de \
    --to=thierry.reding@avionic-design.de \
    --cc=andrew.murray@arm.com \
    --cc=arnd@arndb.de \
    --cc=bhelgaas@google.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=grant.likely@secretlab.ca \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=rob.herring@calxeda.com \
    --cc=swarren@wwwdotorg.org \
    --cc=thomas.petazzoni@free-electrons.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.