* [RFC PATCH v2 1/5] pio-mapping: Add generic support for PIO mapping API
2010-02-11 17:55 [RFC PATCH v2 0/5] PIO drivers and cache coherency Catalin Marinas
@ 2010-02-11 17:55 ` Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 2/5] pio-mapping: Add ARM support for the " Catalin Marinas
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2010-02-11 17:55 UTC (permalink / raw)
To: linux-arch; +Cc: James Bottomley, Russell King
Implement partial support for PIO mapping API similar to the kmap API
used for highmem. These functions are intended to be used by device
drivers doing PIO to page cache pages that may potentially be mapped in
user space and cause cache coherency issues.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Russell King <rmk@arm.linux.org.uk>
---
include/linux/pio-mapping.h | 65 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
create mode 100644 include/linux/pio-mapping.h
diff --git a/include/linux/pio-mapping.h b/include/linux/pio-mapping.h
new file mode 100644
index 0000000..5b216fb
--- /dev/null
+++ b/include/linux/pio-mapping.h
@@ -0,0 +1,65 @@
+/*
+ * include/linux/pio-mapping.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PIO_MAPPING_H
+#define PIO_MAPPING_H
+
+#include <linux/highmem.h>
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_HAVE_ARCH_PIO
+#include <asm/pio-mapping.h>
+#else
+
+static inline void *pio_kmap(struct page *page, enum dma_data_direction dir)
+{
+ return kmap(page);
+}
+
+static inline void pio_kunmap(struct page *page, enum dma_data_direction dir)
+{
+ kunmap(page);
+}
+
+static inline void *pio_kmap_atomic(struct page *page, enum km_type idx,
+ enum dma_data_direction dir)
+{
+ return kmap_atomic(page, idx);
+}
+
+static inline void pio_kunmap_atomic(void *addr, enum km_type idx,
+ enum dma_data_direction dir)
+{
+ kunmap_atomic(addr, idx);
+}
+
+static inline void pio_begin(void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+}
+
+static inline void pio_end(void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+}
+
+#endif /* CONFIG_HAVE_ARCH_PIO */
+
+#endif /* PIO_MAPPING_H */
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC PATCH v2 2/5] pio-mapping: Add ARM support for the PIO mapping API
2010-02-11 17:55 [RFC PATCH v2 0/5] PIO drivers and cache coherency Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 1/5] pio-mapping: Add generic support for PIO mapping API Catalin Marinas
@ 2010-02-11 17:55 ` Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 3/5] pio-mapping: Use the PIO mapping API in libata-sff.c Catalin Marinas
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2010-02-11 17:55 UTC (permalink / raw)
To: linux-arch; +Cc: James Bottomley, Russell King
This patch introduces support for the PIO mapping API on the ARM
architecture. It is currently only meant as an example for discussions
and it can be further optimised.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Russell King <rmk@arm.linux.org.uk>
---
arch/arm/Kconfig | 3 ++
arch/arm/include/asm/pio-mapping.h | 66 ++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/pio-mapping.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4c33ca8..e48adcf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -161,6 +161,9 @@ config ARCH_MTD_XIP
config GENERIC_HARDIRQS_NO__DO_IRQ
def_bool y
+config HAVE_ARCH_PIO
+ def_bool y
+
if OPROFILE
config OPROFILE_ARMV6
diff --git a/arch/arm/include/asm/pio-mapping.h b/arch/arm/include/asm/pio-mapping.h
new file mode 100644
index 0000000..28d5834
--- /dev/null
+++ b/arch/arm/include/asm/pio-mapping.h
@@ -0,0 +1,66 @@
+/*
+ * include/linux/pio-mapping.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ASM_PIO_MAPPING_H
+#define ASM_PIO_MAPPING_H
+
+#include <asm/cacheflush.h>
+#include <asm/fixmap.h>
+
+static inline void *pio_kmap(struct page *page, enum dma_data_direction dir)
+{
+ return kmap(page);
+}
+
+static inline void pio_kunmap(struct page *page, enum dma_data_direction dir)
+{
+ if (dir == DMA_FROM_DEVICE)
+ flush_dcache_page(page);
+ kunmap(page);
+}
+
+static inline void *pio_kmap_atomic(struct page *page, enum km_type idx,
+ enum dma_data_direction dir)
+{
+ return kmap_atomic(page, idx);
+}
+
+static inline void pio_kunmap_atomic(void *addr, enum km_type idx,
+ enum dma_data_direction dir)
+{
+ /* address higher than FIXADDR_START are flushed in kunmap_atomic */
+ if (dir == DMA_FROM_DEVICE && addr < (void *)FIXADDR_START)
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_atomic(addr, idx);
+}
+
+static inline void pio_begin(void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+}
+
+static inline void pio_end(void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+ if (dir == DMA_FROM_DEVICE)
+ __cpuc_flush_dcache_area(addr, size);
+}
+
+#endif /* ASM_PIO_MAPPING_H */
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC PATCH v2 3/5] pio-mapping: Use the PIO mapping API in libata-sff.c
2010-02-11 17:55 [RFC PATCH v2 0/5] PIO drivers and cache coherency Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 1/5] pio-mapping: Add generic support for PIO mapping API Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 2/5] pio-mapping: Add ARM support for the " Catalin Marinas
@ 2010-02-11 17:55 ` Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 4/5] pio-mapping: Use the PIO mapping API in the ISP1760 HCD driver Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 5/5] pio-mapping: Use the PIO mapping API in the MMCI PL18x driver Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2010-02-11 17:55 UTC (permalink / raw)
To: linux-arch; +Cc: James Bottomley, Russell King
This patch shows an example of PIO API usage for non-highmem pages. It
currently only modifies the !highmem case. While it is indicated to no
longer differentiate between these, there is a benefit for the !highmem
case to use the non-atomic kmap API.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Russell King <rmk@arm.linux.org.uk>
---
drivers/ata/libata-sff.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 741065c..02a3be9 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/libata.h>
#include <linux/highmem.h>
+#include <linux/pio-mapping.h>
#include "libata.h"
@@ -888,9 +889,13 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
kunmap_atomic(buf, KM_IRQ0);
local_irq_restore(flags);
} else {
- buf = page_address(page);
+ enum dma_data_direction dir = do_write ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+ buf = pio_kmap(page, dir);
ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
do_write);
+ pio_kunmap(page, dir);
}
qc->curbytes += qc->sect_size;
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC PATCH v2 4/5] pio-mapping: Use the PIO mapping API in the ISP1760 HCD driver
2010-02-11 17:55 [RFC PATCH v2 0/5] PIO drivers and cache coherency Catalin Marinas
` (2 preceding siblings ...)
2010-02-11 17:55 ` [RFC PATCH v2 3/5] pio-mapping: Use the PIO mapping API in libata-sff.c Catalin Marinas
@ 2010-02-11 17:55 ` Catalin Marinas
2010-02-11 17:55 ` [RFC PATCH v2 5/5] pio-mapping: Use the PIO mapping API in the MMCI PL18x driver Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2010-02-11 17:55 UTC (permalink / raw)
To: linux-arch; +Cc: James Bottomley, Russell King
This patch provides another example of PIO API usage. In this case,
there is no struct page information in the HCD driver and the
pio_begin()/pio_end() functions are used.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Russell King <rmk@arm.linux.org.uk>
---
drivers/usb/host/isp1760-hcd.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 27b8f7c..402f676 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -17,6 +17,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/pio-mapping.h>
#include <asm/unaligned.h>
#include "../core/hcd.h"
@@ -904,6 +905,9 @@ __acquires(priv->lock)
status = 0;
}
+ pio_end(urb->transfer_buffer, urb->transfer_buffer_length,
+ usb_pipein(urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
/* complete() can reenter this HCD */
usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
spin_unlock(&priv->lock);
@@ -1538,6 +1542,9 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv,
*/
buf = urb->transfer_buffer;
+ pio_begin(buf, urb->transfer_buffer_length,
+ usb_pipein(urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
if (is_input)
token |= IN_PID;
else
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC PATCH v2 5/5] pio-mapping: Use the PIO mapping API in the MMCI PL18x driver
2010-02-11 17:55 [RFC PATCH v2 0/5] PIO drivers and cache coherency Catalin Marinas
` (3 preceding siblings ...)
2010-02-11 17:55 ` [RFC PATCH v2 4/5] pio-mapping: Use the PIO mapping API in the ISP1760 HCD driver Catalin Marinas
@ 2010-02-11 17:55 ` Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2010-02-11 17:55 UTC (permalink / raw)
To: linux-arch; +Cc: James Bottomley, Russell King
This driver currently uses kmap + flush_dcache_page. This patch changes
the code to the pio_kmap/pio_kunmap without the additional
flush_dcache_page call.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Russell King <rmk@arm.linux.org.uk>
---
drivers/mmc/host/mmci.c | 17 ++++++++---------
drivers/mmc/host/mmci.h | 13 +++++++++----
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 90d168a..a72aa80 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -313,6 +313,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
unsigned long flags;
unsigned int remain, len;
char *buffer;
+ enum dma_data_direction dir = DMA_NONE;
/*
* For write, we only need to test the half-empty flag
@@ -324,10 +325,15 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
break;
+ if (status & MCI_RXACTIVE)
+ dir = DMA_FROM_DEVICE;
+ if (status & MCI_TXACTIVE)
+ dir = DMA_TO_DEVICE;
+
/*
* Map the current scatter buffer.
*/
- buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;
+ buffer = mmci_kmap_atomic(host, &flags, dir) + host->sg_off;
remain = host->sg_ptr->length - host->sg_off;
len = 0;
@@ -339,7 +345,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
/*
* Unmap the buffer.
*/
- mmci_kunmap_atomic(host, buffer, &flags);
+ mmci_kunmap_atomic(host, buffer, &flags, dir);
host->sg_off += len;
host->size -= len;
@@ -348,13 +354,6 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
if (remain)
break;
- /*
- * If we were reading, and we have completed this
- * page, ensure that the data cache is coherent.
- */
- if (status & MCI_RXACTIVE)
- flush_dcache_page(sg_page(host->sg_ptr));
-
if (!mmci_next_sg(host))
break;
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 1ceb9a9..0f19e18 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -7,6 +7,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+
+#include <linux/pio-mapping.h>
+
#define MMCIPOWER 0x000
#define MCI_PWR_OFF 0x00
#define MCI_PWR_UP 0x02
@@ -195,16 +198,18 @@ static inline int mmci_next_sg(struct mmci_host *host)
return --host->sg_len;
}
-static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flags)
+static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flags,
+ enum dma_data_direction dir)
{
struct scatterlist *sg = host->sg_ptr;
local_irq_save(*flags);
- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ return pio_kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ, dir) + sg->offset;
}
-static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
+static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags,
+ enum dma_data_direction dir)
{
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+ pio_kunmap_atomic(buffer, KM_BIO_SRC_IRQ, dir);
local_irq_restore(*flags);
}
^ permalink raw reply related [flat|nested] 6+ messages in thread