From: "Albrecht Dreß" <albrecht.dress@arcor.de>
To: grant.likely@secretlab.ca, dwmw2@infradead.org
Cc: Linux PPC Development <linuxppc-dev@ozlabs.org>
Subject: [PATCH] powerpc/mpc52xx/mtd: fix mtd-ram access for 16-bit Local Plus Bus
Date: Tue, 09 Jun 2009 21:46:14 +0200 [thread overview]
Message-ID: <1244576781.3455.0@antares> (raw)
[-- Attachment #1: Type: text/plain, Size: 4539 bytes --]
Hi all,
this patch adds support for RAM chips connected to the Local Plus Bus
of a MPC5200B in 16-bit mode. As no single byte write accesses are
allowed by the bus in this mode, a byte write has to be split into a
word read - modify - write sequence (mpc52xx_memcpy2lpb16, as
fix/extension for memcpy_toio; note that memcpy_fromio *does* work just
fine). It has been tested in conjunction with Wolfram Sang's mtd-ram
[1] and Sascha Hauer's jffs unaligned access [2] patches on 2.6.29.1,
with a Renesas static RAM connected in 16-bit "Large Flash" mode.
[1]
<http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-June/072794.html>
[2] <http://article.gmane.org/gmane.linux.drivers.mtd/21521>
Signed-off-by: Albrecht Dreß <albrecht.dress@arcor.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linuxppc-dev@ozlabs.org
---
diff -u
linux-2.6.29.1.orig/arch/powerpc/platforms/52xx/mpc52xx_common.c
linux-2.6.29.1/arch/powerpc/platforms/52xx/mpc52xx_common.c
--- linux-2.6.29.1.orig/arch/powerpc/platforms/52xx/mpc52xx_common.c
2009-04-02 22:55:27.000000000 +0200
+++ linux-2.6.29.1/arch/powerpc/platforms/52xx/mpc52xx_common.c
2009-06-09 21:16:22.000000000 +0200
@@ -225,3 +225,59 @@
while (1);
}
+
+/**
+ * mpc52xx_memcpy2lpb16: copy data to the Local Plus Bus in 16-bit
mode which
+ * doesn't allow byte accesses
+ */
+void
+mpc52xx_memcpy2lpb16(volatile void __iomem *dest, const void *src,
+ unsigned long n)
+{
+ void *vdest = (void __force *) dest;
+
+ __asm__ __volatile__ ("sync" : : : "memory");
+
+ if (((unsigned long) vdest & 1) != 0) {
+ u8 buf[2];
+
+ *(u16 *)buf = *((volatile u16 *)(vdest - 1));
+ buf[1] = *((u8 *)src);
+ *((volatile u16 *)(vdest - 1)) = *(u16 *)buf;
+ src++;
+ vdest++;
+ n--;
+ }
+
+ /* looks weird, but helps the optimiser... */
+ if (n >= 4) {
+ unsigned long chunks = n >> 2;
+ volatile u32 * _dst = (volatile u32 *)(vdest - 4);
+ volatile u32 * _src = (volatile u32 *)(src - 4);
+
+ vdest += chunks << 2;
+ src += chunks << 2;
+ do {
+ *++_dst = *++_src;
+ } while (--chunks);
+ n &= 3;
+ }
+
+ if (n >= 2) {
+ *((volatile u16 *)vdest) = *((volatile u16 *)src);
+ src += 2;
+ vdest += 2;
+ n -= 2;
+ }
+
+ if (n > 0) {
+ u8 buf[2];
+
+ *(u16 *)buf = *((volatile u16 *)vdest);
+ buf[0] = *((u8 *)src);
+ *((volatile u16 *)vdest) = *(u16 *)buf;
+ }
+
+ __asm__ __volatile__ ("sync" : : : "memory");
+}
+EXPORT_SYMBOL(mpc52xx_memcpy2lpb16);
diff -u linux-2.6.29.1.orig/arch/powerpc/include/asm/mpc52xx.h
linux-2.6.29.1/arch/powerpc/include/asm/mpc52xx.h
--- linux-2.6.29.1.orig/arch/powerpc/include/asm/mpc52xx.h
2009-04-02 22:55:27.000000000 +0200
+++ linux-2.6.29.1/arch/powerpc/include/asm/mpc52xx.h 2009-06-09
21:14:31.000000000 +0200
@@ -274,6 +274,8 @@
extern void mpc52xx_map_common_devices(void);
extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
extern void mpc52xx_restart(char *cmd);
+extern void mpc52xx_memcpy2lpb16(volatile void __iomem *dest, const
void *src,
+ unsigned long n);
/* mpc52xx_pic.c */
extern void mpc52xx_init_irq(void);
diff -u linux-2.6.29.1.orig/include/linux/mtd/map.h
linux-2.6.29.1/include/linux/mtd/map.h
--- linux-2.6.29.1.orig/include/linux/mtd/map.h 2009-04-02
22:55:27.000000000 +0200
+++ linux-2.6.29.1/include/linux/mtd/map.h 2009-06-08
14:28:05.000000000 +0200
@@ -13,6 +13,9 @@
#include <asm/unaligned.h>
#include <asm/system.h>
#include <asm/io.h>
+#ifdef CONFIG_PPC_MPC52xx
+#include <asm/mpc52xx.h>
+#endif
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
#define map_bankwidth(map) 1
@@ -417,6 +420,11 @@
static inline void inline_map_copy_to(struct map_info *map, unsigned
long to, const void *from, ssize_t len)
{
+#ifdef CONFIG_PPC_MPC52xx
+ if (map->bankwidth == 2)
+ mpc52xx_memcpy2lpb16(map->virt + to, from, len);
+ else
+#endif
memcpy_toio(map->virt + to, from, len);
}
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2009-06-09 19:46 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-09 19:46 Albrecht Dreß [this message]
2009-06-11 16:27 ` [PATCH] powerpc/mpc52xx/mtd: fix mtd-ram access for 16-bit Local Plus Bus Grant Likely
2009-06-11 16:55 ` Wolfram Sang
2009-06-11 17:28 ` Grant Likely
2009-06-13 16:45 ` Albrecht Dreß
2009-06-13 17:09 ` Grant Likely
2009-06-13 17:09 ` Grant Likely
2009-09-04 8:51 ` David Woodhouse
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=1244576781.3455.0@antares \
--to=albrecht.dress@arcor.de \
--cc=dwmw2@infradead.org \
--cc=grant.likely@secretlab.ca \
--cc=linuxppc-dev@ozlabs.org \
/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.