Skip to contentSkip to conversation

powerpc/asm/cacheflush: Cleanup cacheflush function params

PATCH In review Matt Brown 5 participants 7 messages Jul 20, 2017 – Jul 31, 2017 3 messages not in the archive

Subsystems (16)
DRM drivers USB DRM misc PowerPC +12 more subsystems
lore
Share & tools
lore

Matt Brown

author
#0 lore raw

PATCH 1/1 powerpc/asm/cacheflush: Cleanup cacheflush function params

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

---
 arch/powerpc/include/asm/cacheflush.h        | 47 +++++++++++++++++--------
 arch/powerpc/kernel/misc_64.S                | 52 ----------------------------
 arch/powerpc/mm/dma-noncoherent.c            | 15 ++++----
 arch/powerpc/platforms/512x/mpc512x_shared.c | 10 +++---
 arch/powerpc/platforms/85xx/smp.c            |  6 ++--
 arch/powerpc/sysdev/dart_iommu.c             |  5 +--
 drivers/ata/pata_bf54x.c                     |  3 +-
 drivers/char/agp/uninorth-agp.c              |  6 ++--
 drivers/gpu/drm/drm_cache.c                  |  3 +-
 drivers/macintosh/smu.c                      | 15 ++++----
 drivers/mmc/host/bfin_sdh.c                  |  3 +-
 drivers/mtd/nand/bf5xx_nand.c                |  6 ++--
 drivers/soc/fsl/qbman/dpaa_sys.h             |  2 +-
 drivers/soc/fsl/qbman/qman_ccsr.c            |  3 +-
 drivers/spi/spi-bfin5xx.c                    | 10 +++---
 drivers/tty/serial/mpsc.c                    | 46 ++++++++----------------
 drivers/usb/musb/blackfin.c                  |  6 ++--
 17 files changed, 86 insertions(+), 152 deletions(-)
arch/powerpc/include/asm/cacheflush.h +32 -15
index 11843e3..b8f04c3 100644
@@ -51,13 +51,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
  * Write any modified data cache blocks out to memory and invalidate them.
  * Does not invalidate the corresponding instruction cache blocks.
  */
-static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+static inline void flush_dcache_range(void *start, unsigned long size)
 {
-	void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-	unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+	void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_BYTES - 1);
 	unsigned long i;
 
-	for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
 		dcbf(addr);
 	mb();	/* sync */
 }
@@ -67,13 +67,13 @@ static inline void flush_dcache_range(unsigned long start, unsigned long stop)
  * Does not invalidate the corresponding cache lines (especially for
  * any corresponding instruction cache).
  */
-static inline void clean_dcache_range(unsigned long start, unsigned long stop)
+static inline void clean_dcache_range(void *start, unsigned long size)
 {
-	void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-	unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+	void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_BYTES  - 1);
 	unsigned long i;
 
-	for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
 		dcbst(addr);
 	mb();	/* sync */
 }
@@ -83,22 +83,39 @@ static inline void clean_dcache_range(unsigned long start, unsigned long stop)
  * to invalidate the cache so the PPC core doesn't get stale data
  * from the CPM (no cache snooping here :-).
  */
-static inline void invalidate_dcache_range(unsigned long start,
-					   unsigned long stop)
+static inline void invalidate_dcache_range(void *start, unsigned long size)
 {
-	void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-	unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+	void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_SHIFT - 1);
 	unsigned long i;
 
-	for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
 		dcbi(addr);
 	mb();	/* sync */
 }
 
 #endif /* CONFIG_PPC32 */
 #ifdef CONFIG_PPC64
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
+static inline void flush_dcache_range(void *start, unsigned long size)
+{
+	void *addr = (void *)((u64)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_BYTES - 1);
+	unsigned long i;
+
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+		dcbf(addr);
+	mb();	/* sync */
+}
+static inline void flush_inval_dcache_range(void *start, unsigned long size)
+{
+	void *addr = (void *)((u64)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_BYTES - 1);
+	unsigned long i;
+
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+		dcbi(addr);
+	mb();	/* sync */
+}
 #endif
 
 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \
arch/powerpc/kernel/misc_64.S +0 -52

58 lines not on this page · raw message

arch/powerpc/mm/dma-noncoherent.c +6 -9
index 3825284..5fd3171 100644
@@ -204,9 +204,9 @@ __dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t
 	 * kernel direct-mapped region for device DMA.
 	 */
 	{
-		unsigned long kaddr = (unsigned long)page_address(page);
+		void *kaddr = page_address(page);
 		memset(page_address(page), 0, size);
-		flush_dcache_range(kaddr, kaddr + size);
+		flush_dcache_range(kaddr, size);
 	}
 
 	/*
@@ -316,9 +316,6 @@ EXPORT_SYMBOL(__dma_free_coherent);
  */
 void __dma_sync(void *vaddr, size_t size, int direction)
 {
-	unsigned long start = (unsigned long)vaddr;
-	unsigned long end   = start + size;
-
 	switch (direction) {
 	case DMA_NONE:
 		BUG();
@@ -328,15 +325,15 @@ void __dma_sync(void *vaddr, size_t size, int direction)
 		 * the potential for discarding uncommitted data from the cache
 		 */
 		if ((start | end) & (L1_CACHE_BYTES - 1))
-			flush_dcache_range(start, end);
+			flush_dcache_range(vaddr, size);
 		else
-			invalidate_dcache_range(start, end);
+			invalidate_dcache_range(vaddr, size);
 		break;
 	case DMA_TO_DEVICE:		/* writeback only */
-		clean_dcache_range(start, end);
+		clean_dcache_range(vaddr, size);
 		break;
 	case DMA_BIDIRECTIONAL:	/* writeback and invalidate */
-		flush_dcache_range(start, end);
+		flush_dcache_range(vaddr, size);
 		break;
 	}
 }
arch/powerpc/platforms/512x/mpc512x_shared.c +5 -5
index 6b4f4cb..0f3a7d9 100644
@@ -225,7 +225,7 @@ static void __init mpc512x_init_diu(void)
 	phys_addr_t desc;
 	void __iomem *vaddr;
 	unsigned long mode, pix_fmt, res, bpp;
-	unsigned long dst;
+	void *dst;
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu");
 	if (!np) {
@@ -254,8 +254,8 @@ static void __init mpc512x_init_diu(void)
 	}
 	memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad));
 	/* flush fb area descriptor */
-	dst = (unsigned long)&diu_shared_fb.ad0;
-	flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1);
+	dst = &diu_shared_fb.ad0;
+	flush_dcache_range(dst, sizeof(struct diu_ad) - 1);
 
 	res = in_be32(&diu_reg->disp_size);
 	pix_fmt = in_le32(vaddr);
@@ -274,8 +274,8 @@ static void __init mpc512x_init_diu(void)
 	}
 	memcpy(&diu_shared_fb.gamma, vaddr, sizeof(diu_shared_fb.gamma));
 	/* flush gamma table */
-	dst = (unsigned long)&diu_shared_fb.gamma;
-	flush_dcache_range(dst, dst + sizeof(diu_shared_fb.gamma) - 1);
+	dst = &diu_shared_fb.gamma;
+	flush_dcache_range(dst, sizeof(diu_shared_fb.gamma) - 1);
 
 	iounmap(vaddr);
 	out_be32(&diu_reg->gamma, virt_to_phys(&diu_shared_fb.gamma));
arch/powerpc/platforms/85xx/smp.c +2 -4
index f51fd35..645edc9 100644
@@ -166,14 +166,12 @@ static void qoriq_cpu_kill(unsigned int cpu)
  */
 static inline void flush_spin_table(void *spin_table)
 {
-	flush_dcache_range((ulong)spin_table,
-		(ulong)spin_table + sizeof(struct epapr_spin_table));
+	flush_dcache_range(spin_table, sizeof(struct epapr_spin_table));
 }
 
 static inline u32 read_spin_table_addr_l(void *spin_table)
 {
-	flush_dcache_range((ulong)spin_table,
-		(ulong)spin_table + sizeof(struct epapr_spin_table));
+	flush_dcache_range(spin_table, sizeof(struct epapr_spin_table));
 	return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
 }
 
arch/powerpc/sysdev/dart_iommu.c +3 -2
index 3573d54..149b6e8 100644
@@ -152,12 +152,13 @@ static void dart_cache_sync(unsigned int *base, unsigned int count)
 	 * comment in Darwin indicating that the memory controller
 	 * can prefetch unmapped memory under some circumstances.
 	 */
+	unsigned long size = (count + 1) * sizeof(unsigned int);
 	unsigned long start = (unsigned long)base;
-	unsigned long end = start + (count + 1) * sizeof(unsigned int);
+	unsigned long end = start + size;
 	unsigned int tmp;
 
 	/* Perform a standard cache flush */
-	flush_inval_dcache_range(start, end);
+	flush_inval_dcache_range(base, size);
 
 	/*
 	 * Perform the sequence described in the CPC925 manual to
drivers/ata/pata_bf54x.c +1 -2
index 0e55a8d..485e070 100644
@@ -866,8 +866,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc)
 	/* Set the last descriptor to stop mode */
 	dma_desc_cpu[qc->n_elem - 1].cfg &= ~(DMAFLOW | NDSIZE);
 
-	flush_dcache_range((unsigned int)dma_desc_cpu,
-		(unsigned int)dma_desc_cpu +
+	flush_dcache_range(dma_desc_cpu,
 			qc->n_elem * sizeof(struct dma_desc_array));
 
 	/* Enable ATA DMA operation*/
drivers/char/agp/uninorth-agp.c +2 -4
index fdced54..e46eae2 100644
@@ -186,8 +186,7 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, int ty
 		else
 			gp[i] =	cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) |
 					    0x1UL);
-		flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])),
-				   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
+		flush_dcache_range(__va(page_to_phys(mem->pages[i])), 0x1000);
 	}
 	mb();
 	uninorth_tlbflush(mem);
@@ -416,8 +415,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 
 	bridge->gatt_table_real = (u32 *) table;
 	/* Need to clear out any dirty data still sitting in caches */
-	flush_dcache_range((unsigned long)table,
-			   (unsigned long)table_end + 1);
+	flush_dcache_range(table,  (unsigned long)(table_end - table) + 1);
 	bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0, PAGE_KERNEL_NCG);
 
 	if (bridge->gatt_table == NULL)
drivers/gpu/drm/drm_cache.c +1 -2
index 3bd76e9..5b8062f 100644
@@ -100,8 +100,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
 			continue;
 
 		page_virtual = kmap_atomic(page);
-		flush_dcache_range((unsigned long)page_virtual,
-				   (unsigned long)page_virtual + PAGE_SIZE);
+		flush_dcache_range(page_virtual, PAGE_SIZE);
 		kunmap_atomic(page_virtual);
 	}
 #else
drivers/macintosh/smu.c +8 -7
index 1ac6642..e92507d 100644
@@ -111,8 +111,9 @@ static void smu_i2c_retry(unsigned long data);
 
 static void smu_start_cmd(void)
 {
-	unsigned long faddr, fend;
 	struct smu_cmd *cmd;
+	unsigned long flen;
+	void *faddr;
 
 	if (list_empty(&smu->cmd_list))
 		return;
@@ -132,9 +133,9 @@ static void smu_start_cmd(void)
 	memcpy(smu->cmd_buf->data, cmd->data_buf, cmd->data_len);
 
 	/* Flush command and data to RAM */
-	faddr = (unsigned long)smu->cmd_buf;
-	fend = faddr + smu->cmd_buf->length + 2;
-	flush_inval_dcache_range(faddr, fend);
+	faddr = smu->cmd_buf;
+	flen = smu->cmd_buf->length + 2;
+	flush_inval_dcache_range(faddr, flen);
 
 
 	/* We also disable NAP mode for the duration of the command
@@ -186,8 +187,8 @@ static irqreturn_t smu_db_intr(int irq, void *arg)
 		goto bail;
 
 	if (rc == 0) {
-		unsigned long faddr;
 		int reply_len;
+		void *faddr;
 		u8 ack;
 
 		/* CPU might have brought back the cache line, so we need
@@ -195,8 +196,8 @@ static irqreturn_t smu_db_intr(int irq, void *arg)
 		 * flush the entire buffer for now as we haven't read the
 		 * reply length (it's only 2 cache lines anyway)
 		 */
-		faddr = (unsigned long)smu->cmd_buf;
-		flush_inval_dcache_range(faddr, faddr + 256);
+		faddr = smu->cmd_buf;
+		flush_inval_dcache_range(faddr, 256);
 
 		/* Now check ack */
 		ack = (~cmd->cmd) & 0xff;
drivers/mmc/host/bfin_sdh.c +1 -2
index 526231e..479a5cc 100644
@@ -175,8 +175,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
 				host->sg_cpu[i].x_modify);
 		}
 	}
-	flush_dcache_range((unsigned int)host->sg_cpu,
-		(unsigned int)host->sg_cpu +
+	flush_dcache_range(host->sg_cpu,
 			host->dma_len * sizeof(struct dma_desc_array));
 	/* Set the last descriptor to stop mode */
 	host->sg_cpu[host->dma_len - 1].cfg &= ~(DMAFLOW | NDSIZE);
drivers/mtd/nand/bf5xx_nand.c +2 -4
index 3962f55..6f485a4 100644
@@ -492,11 +492,9 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
 	 * can be introduced to your driver.
 	 */
 	if (is_read)
-		invalidate_dcache_range((unsigned int)buf,
-				(unsigned int)(buf + chip->ecc.size));
+		invalidate_dcache_range(buf, chip->ecc.size);
 	else
-		flush_dcache_range((unsigned int)buf,
-				(unsigned int)(buf + chip->ecc.size));
+		flush_dcache_range(buf, chip->ecc.size);
 
 	/*
 	 * This register must be written before each page is
drivers/soc/fsl/qbman/dpaa_sys.h +1 -1
index 2ce394a..e49a961 100644
@@ -56,7 +56,7 @@
 static inline void dpaa_flush(void *p)
 {
 #ifdef CONFIG_PPC
-	flush_dcache_range((unsigned long)p, (unsigned long)p+64);
+	flush_dcache_range(p, 64);
 #elif defined(CONFIG_ARM32)
 	__cpuc_flush_dcache_area(p, 64);
 #elif defined(CONFIG_ARM64)
drivers/soc/fsl/qbman/qman_ccsr.c +1 -2
index 90bc40c..ba10979 100644
@@ -450,8 +450,7 @@ static int zero_priv_mem(struct device *dev, struct device_node *node,
 		return -ENOMEM;
 
 	memset_io(tmpp, 0, sz);
-	flush_dcache_range((unsigned long)tmpp,
-			   (unsigned long)tmpp + sz);
+	flush_dcache_range(tmpp, sz);
 	iounmap(tmpp);
 
 	return 0;
drivers/spi/spi-bfin5xx.c +4 -6
index 249c7a3..7e90746 100644
@@ -730,9 +730,8 @@ static void bfin_spi_pump_transfers(unsigned long data)
 
 			/* invalidate caches, if needed */
 			if (bfin_addr_dcacheable((unsigned long) drv_data->rx))
-				invalidate_dcache_range((unsigned long) drv_data->rx,
-							(unsigned long) (drv_data->rx +
-							drv_data->len_in_bytes));
+				invalidate_dcache_range(drv_data->rx,
+							drv_data->len_in_bytes);
 
 			dma_config |= WNR;
 			dma_start_addr = (unsigned long)drv_data->rx;
@@ -743,9 +742,8 @@ static void bfin_spi_pump_transfers(unsigned long data)
 
 			/* flush caches, if needed */
 			if (bfin_addr_dcacheable((unsigned long) drv_data->tx))
-				flush_dcache_range((unsigned long) drv_data->tx,
-						(unsigned long) (drv_data->tx +
-						drv_data->len_in_bytes));
+				flush_dcache_range(drv_data->tx,
+						drv_data->len_in_bytes);
 
 			dma_start_addr = (unsigned long)drv_data->tx;
 			cr |= BIT_CTL_TIMOD_DMA_TX;
drivers/tty/serial/mpsc.c +15 -31

136 lines not on this page · raw message

drivers/usb/musb/blackfin.c +2 -4
index 4418574..092a011 100644
@@ -90,8 +90,7 @@ static void bfin_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
 	if (!ANOMALY_05000380 && epnum != 0) {
 		u16 dma_reg;
 
-		flush_dcache_range((unsigned long)src,
-			(unsigned long)(src + len));
+		flush_dcache_range(src, len);
 
 		/* Setup DMA address register */
 		dma_reg = (u32)src;
@@ -144,8 +143,7 @@ static void bfin_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 	if (ANOMALY_05000467 && epnum != 0) {
 		u16 dma_reg;
 
-		invalidate_dcache_range((unsigned long)dst,
-			(unsigned long)(dst + len));
+		invalidate_dcache_range(dst, len);
 
 		/* Setup DMA address register */
 		dma_reg = (u32)dst;
Signature · 1 line
2.9.3
#1 lore raw
Quoted 8 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

Quoted 8 lines

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

 drivers/spi/spi-bfin5xx.c                    | 10 +++---
 drivers/usb/musb/blackfin.c                  |  6 ++--

These are used on blackfin, so changing them without changing the blackfin cache ops will break the build.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

A message that is not in the archive (sent off-list or not yet received): 20170720062850.2195-1-matthew.brown.dev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#3 lore raw

Hi Matt,

Thanks for tackling this mess.

Quoted 23 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

---
 arch/powerpc/include/asm/cacheflush.h        | 47 +++++++++++++++++--------
 arch/powerpc/kernel/misc_64.S                | 52 ----------------------------
 arch/powerpc/mm/dma-noncoherent.c            | 15 ++++----
 arch/powerpc/platforms/512x/mpc512x_shared.c | 10 +++---
 arch/powerpc/platforms/85xx/smp.c            |  6 ++--
 arch/powerpc/sysdev/dart_iommu.c             |  5 +--
 drivers/ata/pata_bf54x.c                     |  3 +-
 drivers/char/agp/uninorth-agp.c              |  6 ++--
 drivers/gpu/drm/drm_cache.c                  |  3 +-
Quoted 8 lines
 drivers/macintosh/smu.c                      | 15 ++++----
 drivers/mmc/host/bfin_sdh.c                  |  3 +-
 drivers/mtd/nand/bf5xx_nand.c                |  6 ++--
 drivers/soc/fsl/qbman/dpaa_sys.h             |  2 +-
 drivers/soc/fsl/qbman/qman_ccsr.c            |  3 +-
 drivers/spi/spi-bfin5xx.c                    | 10 +++---
 drivers/tty/serial/mpsc.c                    | 46 ++++++++----------------
 drivers/usb/musb/blackfin.c                  |  6 ++--

I think you want to trim that to powerpc only drivers for now at least.

Quoted 5 lines
arch/powerpc/include/asm/cacheflush.h +0 -0
index 11843e3..b8f04c3 100644

arch/powerpc/include/asm/cacheflush.h static inline void __flush_dcache_icache_phys(unsigned long physaddr) · line 56

Quoted 9 lines
arch/powerpc/include/asm/cacheflush.h +2 -3
@@ -51,13 +51,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
  * Write any modified data cache blocks out to memory and invalidate them.
  * Does not invalidate the corresponding instruction cache blocks.
  */
-static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+static inline void flush_dcache_range(void *start, unsigned long size)
 {
-	void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-	unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+	void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));

unsigned long would be nicer than u32.

And ALIGN_DOWN() should work here I think.

arch/powerpc/include/asm/cacheflush.h static inline void __flush_dcache_icache_phys(unsigned long physaddr) · line 57

Quoted 1 line
arch/powerpc/include/asm/cacheflush.h +1 -0
+	unsigned long len = size + (L1_CACHE_BYTES - 1);

And ALIGN?

Quoted 24 lines
arch/powerpc/include/asm/cacheflush.h +4 -7
@@ -83,22 +83,39 @@ static inline void clean_dcache_range(unsigned long start, unsigned long stop)
  * to invalidate the cache so the PPC core doesn't get stale data
  * from the CPM (no cache snooping here :-).
  */
-static inline void invalidate_dcache_range(unsigned long start,
-					   unsigned long stop)
+static inline void invalidate_dcache_range(void *start, unsigned long size)
 {
-	void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-	unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+	void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_SHIFT - 1);
 	unsigned long i;
 
-	for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
 		dcbi(addr);
 	mb();	/* sync */
 }
 
 #endif /* CONFIG_PPC32 */
 #ifdef CONFIG_PPC64
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);

arch/powerpc/include/asm/cacheflush.h static inline void clean_dcache_range(unsigned long start, unsigned long stop) · line 108

Quoted 10 lines
arch/powerpc/include/asm/cacheflush.h +10 -0
+static inline void flush_dcache_range(void *start, unsigned long size)
+{
+	void *addr = (void *)((u64)start & ~(L1_CACHE_BYTES - 1));
+	unsigned long len = size + (L1_CACHE_BYTES - 1);
+	unsigned long i;
+
+	for (i = 0; i < len >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+		dcbf(addr);
+	mb();	/* sync */
+}

I'd probably prefer a precursor patch to do the asm -> C conversion, but I guess that's a pain because then you have to implement both the old and new logic in C.

Also L1_CACHE_SHIFT is not necessarily == DCACHEL1BLOCKSIZE.

Finally it would be good to see what code the compiler generates out of this, and see how it compares to the asm version. Not because it's particularly performance critical (hopefully) but just so we know.

arch/powerpc/platforms/512x/mpc512x_shared.c static void __init mpc512x_init_diu(void) · line 257

Quoted 11 lines
arch/powerpc/platforms/512x/mpc512x_shared.c +1 -2
index 6b4f4cb..0f3a7d9 100644
@@ -254,8 +254,8 @@ static void __init mpc512x_init_diu(void)
 	}
 	memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad));
 	/* flush fb area descriptor */
-	dst = (unsigned long)&diu_shared_fb.ad0;
-	flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1);
+	dst = &diu_shared_fb.ad0;

Do you even need dst anymore?

arch/powerpc/platforms/512x/mpc512x_shared.c static void __init mpc512x_init_diu(void) · line 258

Quoted 1 line
arch/powerpc/platforms/512x/mpc512x_shared.c +1 -0
+	flush_dcache_range(dst, sizeof(struct diu_ad) - 1);

^
You shouldn't be subtracting 1 any more.

cheers
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw
Quoted 13 lines · Michael Ellerman
Quoted 11 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

Quoted 14 lines

arch/powerpc/include/asm/cacheflush.h static inline void __flush_dcache_icache_phys(unsigned long physaddr) · line 56

Quoted 12 lines
arch/powerpc/include/asm/cacheflush.h +2 -3
@@ -51,13 +51,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
  * Write any modified data cache blocks out to memory and invalidate them.
  * Does not invalidate the corresponding instruction cache blocks.
  */
-static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+static inline void flush_dcache_range(void *start, unsigned long size)
 {
-     void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-     unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+     void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));

unsigned long would be nicer than u32.

Indeed. That would make this work on ppc64, too.
After which ppc64 has an identical copy (u64 = unsigned long on ppc64) below?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

A message that is not in the archive (sent off-list or not yet received): CAMuHMdXU-R8kBs_xp7XDK0pnC5fakpghchuEPD8jtEcHLmgyHg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#6 lore raw
Quoted 29 lines · Geert Uytterhoeven
Quoted 13 lines · Michael Ellerman
Quoted 11 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

Quoted 14 lines

arch/powerpc/include/asm/cacheflush.h static inline void __flush_dcache_icache_phys(unsigned long physaddr) · line 56

Quoted 12 lines
arch/powerpc/include/asm/cacheflush.h +2 -3
@@ -51,13 +51,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
  * Write any modified data cache blocks out to memory and invalidate them.
  * Does not invalidate the corresponding instruction cache blocks.
  */
-static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+static inline void flush_dcache_range(void *start, unsigned long size)
 {
-     void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-     unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+     void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));

unsigned long would be nicer than u32.

Quoted 2 lines

Indeed. That would make this work on ppc64, too.
After which ppc64 has an identical copy (u64 = unsigned long on ppc64) below?

That was Matt's homework to notice that ;)

cheers
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 87h8y7gt2z.fsf-W0DJWXSxmBNbyGPkN3NxC2scP1bn1w/[email protected]

#8 lore raw

I've realised that changing the arguments for the cacheflush functions is much more work than its worth, due to other archs using these functions.
The next patch will just translate the asm cacheflush functions to c, keeping the existing parameters.
So this won't have any effect on the drivers.

Thanks,
Matt Brown

Quoted 31 lines · Michael Ellerman
Quoted 29 lines · Geert Uytterhoeven
Quoted 27 lines · Michael Ellerman
Quoted 15 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

arch/powerpc/include/asm/cacheflush.h static inline void __flush_dcache_icache_phys(unsigned long physaddr) · line 56

Quoted 9 lines
arch/powerpc/include/asm/cacheflush.h +2 -3
@@ -51,13 +51,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
  * Write any modified data cache blocks out to memory and invalidate them.
  * Does not invalidate the corresponding instruction cache blocks.
  */
-static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+static inline void flush_dcache_range(void *start, unsigned long size)
 {
-     void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
-     unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+     void *addr = (void *)((u32)start & ~(L1_CACHE_BYTES - 1));

unsigned long would be nicer than u32.

Quoted 6 lines
Quoted 2 lines

Indeed. That would make this work on ppc64, too.
After which ppc64 has an identical copy (u64 = unsigned long on ppc64) below?

That was Matt's homework to notice that ;)

cheers

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw
In reply to Matt Brown
Quoted 33 lines · Matt Brown

The cacheflush prototypes currently use start and stop values and each call requires typecasting the address to an unsigned long. This patch changes the cacheflush prototypes to follow the x86 style of using a base and size values, with base being a void pointer.

All callers of the cacheflush functions, including drivers, have been modified to conform to the new prototypes.

The 64 bit cacheflush functions which were implemented in assembly code (flush_dcache_range, flush_inval_dcache_range) have been translated into C for readability and coherence.

---
  arch/powerpc/include/asm/cacheflush.h        | 47 +++++++++++++++++--------
  arch/powerpc/kernel/misc_64.S                | 52 ----------------------------
  arch/powerpc/mm/dma-noncoherent.c            | 15 ++++----
  arch/powerpc/platforms/512x/mpc512x_shared.c | 10 +++---
  arch/powerpc/platforms/85xx/smp.c            |  6 ++--
  arch/powerpc/sysdev/dart_iommu.c             |  5 +--
  drivers/ata/pata_bf54x.c                     |  3 +-
  drivers/char/agp/uninorth-agp.c              |  6 ++--
  drivers/gpu/drm/drm_cache.c                  |  3 +-
  drivers/macintosh/smu.c                      | 15 ++++----
  drivers/mmc/host/bfin_sdh.c                  |  3 +-
  drivers/mtd/nand/bf5xx_nand.c                |  6 ++--
  drivers/soc/fsl/qbman/dpaa_sys.h             |  2 +-
  drivers/soc/fsl/qbman/qman_ccsr.c            |  3 +-
  drivers/spi/spi-bfin5xx.c                    | 10 +++---
  drivers/tty/serial/mpsc.c                    | 46 ++++++++----------------
  drivers/usb/musb/blackfin.c                  |  6 ++--
  17 files changed, 86 insertions(+), 152 deletions(-)

[...]

Quoted 27 lines
arch/powerpc/mm/dma-noncoherent.c +2 -5
index 3825284..5fd3171 100644
@@ -204,9 +204,9 @@ __dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t
  	 * kernel direct-mapped region for device DMA.
  	 */
  	{
-		unsigned long kaddr = (unsigned long)page_address(page);
+		void *kaddr = page_address(page);
  		memset(page_address(page), 0, size);
-		flush_dcache_range(kaddr, kaddr + size);
+		flush_dcache_range(kaddr, size);
  	}
 
  	/*
@@ -316,9 +316,6 @@ EXPORT_SYMBOL(__dma_free_coherent);
   */
  void __dma_sync(void *vaddr, size_t size, int direction)
  {
-	unsigned long start = (unsigned long)vaddr;
-	unsigned long end   = start + size;
-
  	switch (direction) {
  	case DMA_NONE:
  		BUG();

arch/powerpc/mm/dma-noncoherent.c void __dma_sync(void *vaddr, size_t size, int direction) · line 327

Quoted 3 lines
arch/powerpc/mm/dma-noncoherent.c +0 -0
@@ -328,15 +325,15 @@ void __dma_sync(void *vaddr, size_t size, int direction)
  		 * the potential for discarding uncommitted data from the cache
  		 */
  		if ((start | end) & (L1_CACHE_BYTES - 1))

How can the above compile when 'start' and 'end' are removed ? Shouldn't it be replaced by

if ((vaddr | size) & (L1_CACHE_BYTES - 1))

Quoted 6 lines
arch/powerpc/mm/dma-noncoherent.c +2 -2
-			flush_dcache_range(start, end);
+			flush_dcache_range(vaddr, size);
  		else
-			invalidate_dcache_range(start, end);
+			invalidate_dcache_range(vaddr, size);
  		break;

arch/powerpc/mm/dma-noncoherent.c void __dma_sync(void *vaddr, size_t size, int direction) · line 339

Quoted 10 lines
arch/powerpc/mm/dma-noncoherent.c +2 -2
  	case DMA_TO_DEVICE:		/* writeback only */
-		clean_dcache_range(start, end);
+		clean_dcache_range(vaddr, size);
  		break;
  	case DMA_BIDIRECTIONAL:	/* writeback and invalidate */
-		flush_dcache_range(start, end);
+		flush_dcache_range(vaddr, size);
  		break;
  	}
  }

[...]

Christophe

_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel