From: Kevin Cernekee <cernekee@gmail.com>
To: Ralf Baechle <ralf@linux-mips.org>
Cc: <dediao@cisco.com>, <dvomlehn@cisco.com>, <sshtylyov@mvista.com>,
<linux-mips@linux-mips.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v2 1/3] MIPS: HIGHMEM DMA on noncoherent MIPS32 processors
Date: Wed, 8 Sep 2010 16:02:12 -0700 [thread overview]
Message-ID: <064bb0722da5d8c271c2bd9fe0a521cc@localhost> (raw)
[v2: Formatting changes only.]
The MIPS DMA coherency functions do not work properly (i.e. kernel oops)
when HIGHMEM pages are passed in as arguments. This patch uses the PPC
approach of calling kmap_atomic() with IRQs disabled to temporarily map
high pages, in order to flush them out to memory.
Signed-off-by: Dezhong Diao <dediao@cisco.com>
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
arch/mips/mm/dma-default.c | 159 ++++++++++++++++++++++----------------------
1 files changed, 80 insertions(+), 79 deletions(-)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 469d401..79dfb9c 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -15,18 +15,18 @@
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/gfp.h>
+#include <linux/highmem.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <dma-coherence.h>
-static inline unsigned long dma_addr_to_virt(struct device *dev,
+static inline struct page *dma_addr_to_page(struct device *dev,
dma_addr_t dma_addr)
{
- unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
-
- return (unsigned long)phys_to_virt(addr);
+ return pfn_to_page(
+ plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT);
}
/*
@@ -153,20 +153,20 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
EXPORT_SYMBOL(dma_free_coherent);
-static inline void __dma_sync(unsigned long addr, size_t size,
+static inline void __dma_sync_virtual(void *addr, size_t size,
enum dma_data_direction direction)
{
switch (direction) {
case DMA_TO_DEVICE:
- dma_cache_wback(addr, size);
+ dma_cache_wback((unsigned long)addr, size);
break;
case DMA_FROM_DEVICE:
- dma_cache_inv(addr, size);
+ dma_cache_inv((unsigned long)addr, size);
break;
case DMA_BIDIRECTIONAL:
- dma_cache_wback_inv(addr, size);
+ dma_cache_wback_inv((unsigned long)addr, size);
break;
default:
@@ -174,13 +174,53 @@ static inline void __dma_sync(unsigned long addr, size_t size,
}
}
+/*
+ * A single sg entry may refer to multiple physically contiguous
+ * pages. But we still need to process highmem pages individually.
+ * If highmem is not configured then the bulk of this loop gets
+ * optimized out.
+ */
+static inline void __dma_sync(struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+ size_t left = size;
+
+ BUG_ON(direction == DMA_NONE);
+
+ do {
+ size_t len = left;
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+ void *addr;
+
+ if (offset + len > PAGE_SIZE) {
+ if (offset >= PAGE_SIZE) {
+ page += offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
+ }
+ len = PAGE_SIZE - offset;
+ }
+
+ local_irq_save(flags);
+ addr = kmap_atomic(page, KM_SYNC_DCACHE);
+ __dma_sync_virtual(addr + offset, len, direction);
+ kunmap_atomic(addr, KM_SYNC_DCACHE);
+ local_irq_restore(flags);
+ } else
+ __dma_sync_virtual(page_address(page) + offset,
+ size, direction);
+ offset = 0;
+ page++;
+ left -= len;
+ } while (left);
+}
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
- unsigned long addr = (unsigned long) ptr;
-
if (!plat_device_is_coherent(dev))
- __dma_sync(addr, size, direction);
+ __dma_sync_virtual(ptr, size, direction);
return plat_map_dma_mem(dev, ptr, size);
}
@@ -191,8 +231,8 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync(dma_addr_to_virt(dev, dma_addr), size,
- direction);
+ __dma_sync(dma_addr_to_page(dev, dma_addr),
+ dma_addr & ~PAGE_MASK, size, direction);
plat_unmap_dma_mem(dev, dma_addr, size, direction);
}
@@ -204,16 +244,12 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
{
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nents; i++, sg++) {
- unsigned long addr;
-
- addr = (unsigned long) sg_virt(sg);
- if (!plat_device_is_coherent(dev) && addr)
- __dma_sync(addr, sg->length, direction);
- sg->dma_address = plat_map_dma_mem(dev,
- (void *)addr, sg->length);
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
+ sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
+ sg->offset;
}
return nents;
@@ -224,14 +260,8 @@ EXPORT_SYMBOL(dma_map_sg);
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = (unsigned long) page_address(page) + offset;
- __dma_sync(addr, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(page, offset, size, direction);
return plat_map_dma_mem_page(dev, page) + offset;
}
@@ -241,18 +271,13 @@ EXPORT_SYMBOL(dma_map_page);
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
{
- unsigned long addr;
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nhwentries; i++, sg++) {
if (!plat_device_is_coherent(dev) &&
- direction != DMA_TO_DEVICE) {
- addr = (unsigned long) sg_virt(sg);
- if (addr)
- __dma_sync(addr, sg->length, direction);
- }
+ direction != DMA_TO_DEVICE)
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
}
}
@@ -262,14 +287,9 @@ EXPORT_SYMBOL(dma_unmap_sg);
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (cpu_is_noncoherent_r10000(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr, size, direction);
- }
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle),
+ dma_handle & ~PAGE_MASK, size, direction);
}
EXPORT_SYMBOL(dma_sync_single_for_cpu);
@@ -277,15 +297,10 @@ EXPORT_SYMBOL(dma_sync_single_for_cpu);
void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
plat_extra_sync_for_device(dev);
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle),
+ dma_handle & ~PAGE_MASK, size, direction);
}
EXPORT_SYMBOL(dma_sync_single_for_device);
@@ -293,14 +308,9 @@ EXPORT_SYMBOL(dma_sync_single_for_device);
void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (cpu_is_noncoherent_r10000(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle), offset, size,
+ direction);
}
EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
@@ -308,15 +318,10 @@ EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
plat_extra_sync_for_device(dev);
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle), offset, size,
+ direction);
}
EXPORT_SYMBOL(dma_sync_single_range_for_device);
@@ -326,13 +331,11 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync((unsigned long)page_address(sg_page(sg)),
- sg->length, direction);
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
}
}
@@ -343,13 +346,11 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (!plat_device_is_coherent(dev))
- __dma_sync((unsigned long)page_address(sg_page(sg)),
- sg->length, direction);
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
}
}
@@ -376,7 +377,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev))
- __dma_sync((unsigned long)vaddr, size, direction);
+ __dma_sync_virtual(vaddr, size, direction);
}
EXPORT_SYMBOL(dma_cache_sync);
--
1.7.0.4
WARNING: multiple messages have this Message-ID (diff)
From: Kevin Cernekee <cernekee@gmail.com>
To: Ralf Baechle <ralf@linux-mips.org>
Cc: dediao@cisco.com, dvomlehn@cisco.com, sshtylyov@mvista.com,
linux-mips@linux-mips.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 1/3] MIPS: HIGHMEM DMA on noncoherent MIPS32 processors
Date: Wed, 8 Sep 2010 16:02:12 -0700 [thread overview]
Message-ID: <064bb0722da5d8c271c2bd9fe0a521cc@localhost> (raw)
Message-ID: <20100908230212.LAWaKMtrtH3l8lbDuLjELdplOIXokK5KMBgYQ1giBKA@z> (raw)
[v2: Formatting changes only.]
The MIPS DMA coherency functions do not work properly (i.e. kernel oops)
when HIGHMEM pages are passed in as arguments. This patch uses the PPC
approach of calling kmap_atomic() with IRQs disabled to temporarily map
high pages, in order to flush them out to memory.
Signed-off-by: Dezhong Diao <dediao@cisco.com>
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
arch/mips/mm/dma-default.c | 159 ++++++++++++++++++++++----------------------
1 files changed, 80 insertions(+), 79 deletions(-)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 469d401..79dfb9c 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -15,18 +15,18 @@
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/gfp.h>
+#include <linux/highmem.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <dma-coherence.h>
-static inline unsigned long dma_addr_to_virt(struct device *dev,
+static inline struct page *dma_addr_to_page(struct device *dev,
dma_addr_t dma_addr)
{
- unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
-
- return (unsigned long)phys_to_virt(addr);
+ return pfn_to_page(
+ plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT);
}
/*
@@ -153,20 +153,20 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
EXPORT_SYMBOL(dma_free_coherent);
-static inline void __dma_sync(unsigned long addr, size_t size,
+static inline void __dma_sync_virtual(void *addr, size_t size,
enum dma_data_direction direction)
{
switch (direction) {
case DMA_TO_DEVICE:
- dma_cache_wback(addr, size);
+ dma_cache_wback((unsigned long)addr, size);
break;
case DMA_FROM_DEVICE:
- dma_cache_inv(addr, size);
+ dma_cache_inv((unsigned long)addr, size);
break;
case DMA_BIDIRECTIONAL:
- dma_cache_wback_inv(addr, size);
+ dma_cache_wback_inv((unsigned long)addr, size);
break;
default:
@@ -174,13 +174,53 @@ static inline void __dma_sync(unsigned long addr, size_t size,
}
}
+/*
+ * A single sg entry may refer to multiple physically contiguous
+ * pages. But we still need to process highmem pages individually.
+ * If highmem is not configured then the bulk of this loop gets
+ * optimized out.
+ */
+static inline void __dma_sync(struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+ size_t left = size;
+
+ BUG_ON(direction == DMA_NONE);
+
+ do {
+ size_t len = left;
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+ void *addr;
+
+ if (offset + len > PAGE_SIZE) {
+ if (offset >= PAGE_SIZE) {
+ page += offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
+ }
+ len = PAGE_SIZE - offset;
+ }
+
+ local_irq_save(flags);
+ addr = kmap_atomic(page, KM_SYNC_DCACHE);
+ __dma_sync_virtual(addr + offset, len, direction);
+ kunmap_atomic(addr, KM_SYNC_DCACHE);
+ local_irq_restore(flags);
+ } else
+ __dma_sync_virtual(page_address(page) + offset,
+ size, direction);
+ offset = 0;
+ page++;
+ left -= len;
+ } while (left);
+}
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
- unsigned long addr = (unsigned long) ptr;
-
if (!plat_device_is_coherent(dev))
- __dma_sync(addr, size, direction);
+ __dma_sync_virtual(ptr, size, direction);
return plat_map_dma_mem(dev, ptr, size);
}
@@ -191,8 +231,8 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync(dma_addr_to_virt(dev, dma_addr), size,
- direction);
+ __dma_sync(dma_addr_to_page(dev, dma_addr),
+ dma_addr & ~PAGE_MASK, size, direction);
plat_unmap_dma_mem(dev, dma_addr, size, direction);
}
@@ -204,16 +244,12 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
{
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nents; i++, sg++) {
- unsigned long addr;
-
- addr = (unsigned long) sg_virt(sg);
- if (!plat_device_is_coherent(dev) && addr)
- __dma_sync(addr, sg->length, direction);
- sg->dma_address = plat_map_dma_mem(dev,
- (void *)addr, sg->length);
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
+ sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
+ sg->offset;
}
return nents;
@@ -224,14 +260,8 @@ EXPORT_SYMBOL(dma_map_sg);
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = (unsigned long) page_address(page) + offset;
- __dma_sync(addr, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(page, offset, size, direction);
return plat_map_dma_mem_page(dev, page) + offset;
}
@@ -241,18 +271,13 @@ EXPORT_SYMBOL(dma_map_page);
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
{
- unsigned long addr;
int i;
- BUG_ON(direction == DMA_NONE);
-
for (i = 0; i < nhwentries; i++, sg++) {
if (!plat_device_is_coherent(dev) &&
- direction != DMA_TO_DEVICE) {
- addr = (unsigned long) sg_virt(sg);
- if (addr)
- __dma_sync(addr, sg->length, direction);
- }
+ direction != DMA_TO_DEVICE)
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
}
}
@@ -262,14 +287,9 @@ EXPORT_SYMBOL(dma_unmap_sg);
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (cpu_is_noncoherent_r10000(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr, size, direction);
- }
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle),
+ dma_handle & ~PAGE_MASK, size, direction);
}
EXPORT_SYMBOL(dma_sync_single_for_cpu);
@@ -277,15 +297,10 @@ EXPORT_SYMBOL(dma_sync_single_for_cpu);
void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
plat_extra_sync_for_device(dev);
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle),
+ dma_handle & ~PAGE_MASK, size, direction);
}
EXPORT_SYMBOL(dma_sync_single_for_device);
@@ -293,14 +308,9 @@ EXPORT_SYMBOL(dma_sync_single_for_device);
void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
- if (cpu_is_noncoherent_r10000(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle), offset, size,
+ direction);
}
EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
@@ -308,15 +318,10 @@ EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size, enum dma_data_direction direction)
{
- BUG_ON(direction == DMA_NONE);
-
plat_extra_sync_for_device(dev);
- if (!plat_device_is_coherent(dev)) {
- unsigned long addr;
-
- addr = dma_addr_to_virt(dev, dma_handle);
- __dma_sync(addr + offset, size, direction);
- }
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(dma_addr_to_page(dev, dma_handle), offset, size,
+ direction);
}
EXPORT_SYMBOL(dma_sync_single_range_for_device);
@@ -326,13 +331,11 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync((unsigned long)page_address(sg_page(sg)),
- sg->length, direction);
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
}
}
@@ -343,13 +346,11 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
{
int i;
- BUG_ON(direction == DMA_NONE);
-
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (!plat_device_is_coherent(dev))
- __dma_sync((unsigned long)page_address(sg_page(sg)),
- sg->length, direction);
+ __dma_sync(sg_page(sg), sg->offset, sg->length,
+ direction);
}
}
@@ -376,7 +377,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev))
- __dma_sync((unsigned long)vaddr, size, direction);
+ __dma_sync_virtual(vaddr, size, direction);
}
EXPORT_SYMBOL(dma_cache_sync);
--
1.7.0.4
next reply other threads:[~2010-09-08 23:11 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-08 23:02 Kevin Cernekee [this message]
2010-09-08 23:02 ` [PATCH v2 1/3] MIPS: HIGHMEM DMA on noncoherent MIPS32 processors Kevin Cernekee
2010-09-08 23:02 ` [PATCH 2/3] MIPS: Allow UserLocal on MIPS_R1 processors Kevin Cernekee
2010-09-08 23:02 ` Kevin Cernekee
2010-09-09 9:53 ` Ralf Baechle
2010-09-08 23:02 ` [PATCH 3/3] MIPS: DMA: Add plat_extra_sync_for_cpu() Kevin Cernekee
2010-09-08 23:02 ` Kevin Cernekee
2010-09-09 9:34 ` Sergei Shtylyov
2010-09-09 12:39 ` Kevin Cernekee
2011-05-19 13:30 ` Ralf Baechle
2010-09-09 17:10 ` David Daney
2010-09-09 17:34 ` Thomas Bogendoerfer
2010-09-09 18:35 ` Kevin Cernekee
2010-09-09 18:58 ` David Daney
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=064bb0722da5d8c271c2bd9fe0a521cc@localhost \
--to=cernekee@gmail.com \
--cc=dediao@cisco.com \
--cc=dvomlehn@cisco.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
--cc=sshtylyov@mvista.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.