mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 14:34:27 -05:00 
			
		
		
		
	brcm47xx: update flash drivers
SVN-Revision: 31126
This commit is contained in:
		
							parent
							
								
									f96ffe2c96
								
							
						
					
					
						commit
						13b6ec1d05
					
				@ -1,16 +1,3 @@
 | 
			
		||||
From b7d9f9cd6a8e463c1061ea29ed3e614403625024 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 14:51:47 +0200
 | 
			
		||||
Subject: [PATCH 12/26] bcma: move parallel flash into a union
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/bcm47xx/nvram.c                   |    3 +
 | 
			
		||||
 drivers/bcma/driver_mips.c                  |    1 +
 | 
			
		||||
 include/linux/bcma/bcma_driver_chipcommon.h |   73 ++++++++++++++++++++++++++-
 | 
			
		||||
 3 files changed, 76 insertions(+), 1 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
@@ -50,6 +50,9 @@ static void early_nvram_init(void)
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,3 @@
 | 
			
		||||
From a62940e988526c881966a8c72cc28c95fca89f3c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 14:53:07 +0200
 | 
			
		||||
Subject: [PATCH 13/26] bcma: add serial flash support to bcma
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 drivers/bcma/Kconfig                        |    5 +
 | 
			
		||||
 drivers/bcma/Makefile                       |    1 +
 | 
			
		||||
 drivers/bcma/bcma_private.h                 |    5 +
 | 
			
		||||
 drivers/bcma/driver_chipcommon_sflash.c     |  555 +++++++++++++++++++++++++++
 | 
			
		||||
 drivers/bcma/driver_mips.c                  |    8 +-
 | 
			
		||||
 include/linux/bcma/bcma_driver_chipcommon.h |   24 ++
 | 
			
		||||
 6 files changed, 597 insertions(+), 1 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/bcma/driver_chipcommon_sflash.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/bcma/Kconfig
 | 
			
		||||
+++ b/drivers/bcma/Kconfig
 | 
			
		||||
@@ -38,6 +38,11 @@ config BCMA_HOST_SOC
 | 
			
		||||
@ -54,11 +37,12 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 extern int __init bcma_host_pci_init(void);
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/bcma/driver_chipcommon_sflash.c
 | 
			
		||||
@@ -0,0 +1,555 @@
 | 
			
		||||
@@ -0,0 +1,398 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Broadcom SiliconBackplane chipcommon serial flash interface
 | 
			
		||||
+ *
 | 
			
		||||
+ * Copyright 2011, Jonas Gorski <jonas.gorski@gmail.com>
 | 
			
		||||
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+ * Copyright 2010, Broadcom Corporation
 | 
			
		||||
+ *
 | 
			
		||||
+ * Licensed under the GNU/GPL. See COPYING for details.
 | 
			
		||||
@ -84,7 +68,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+static inline void bcma_sflash_write_u8(struct bcma_drv_cc *cc,
 | 
			
		||||
+					      u32 offset, u8 byte)
 | 
			
		||||
+					u32 offset, u8 byte)
 | 
			
		||||
+{
 | 
			
		||||
+	bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset);
 | 
			
		||||
+	bcma_cc_write32(cc, BCMA_CC_FLASHDATA, byte);
 | 
			
		||||
@ -244,8 +228,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Read len bytes starting at offset into buf. Returns number of bytes read. */
 | 
			
		||||
+int bcma_sflash_read(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			   u8 *buf)
 | 
			
		||||
+int bcma_sflash_read(struct bcma_drv_cc *cc, u32 offset, u32 len, u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 *from, *to;
 | 
			
		||||
+	u32 cnt, i;
 | 
			
		||||
@ -263,11 +246,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	else
 | 
			
		||||
+		cnt = len;
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+	if (cc->core->id.rev == 12)
 | 
			
		||||
+		from = (u8 *)KSEG1ADDR(BCMA_FLASH2 + offset);
 | 
			
		||||
+	else
 | 
			
		||||
+		from = (u8 *)KSEG0ADDR(BCMA_FLASH2 + offset);
 | 
			
		||||
+	from = (u8 *)KSEG0ADDR(BCMA_FLASH2 + offset);
 | 
			
		||||
+
 | 
			
		||||
+	to = (u8 *)buf;
 | 
			
		||||
+
 | 
			
		||||
@ -316,92 +295,43 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+static int sflash_st_write(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			   const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_bus *bus = cc->core->bus;
 | 
			
		||||
+	int ret = 0;
 | 
			
		||||
+	bool is4712b0 = (bus->chipinfo.id == 0x4712) && (bus->chipinfo.rev == 3);
 | 
			
		||||
+	u32 mask;
 | 
			
		||||
+
 | 
			
		||||
+	int written = 1;
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable writes */
 | 
			
		||||
+	bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_WREN);
 | 
			
		||||
+	if (is4712b0) {
 | 
			
		||||
+		mask = 1 << 14;
 | 
			
		||||
+		bcma_sflash_write_u8(cc, offset, *buf++);
 | 
			
		||||
+		/* Set chip select */
 | 
			
		||||
+		bcma_cc_set32(cc, BCMA_CC_GPIOOUT, mask);
 | 
			
		||||
+		/* Issue a page program with the first byte */
 | 
			
		||||
+		bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_PP);
 | 
			
		||||
+		ret = 1;
 | 
			
		||||
+	bcma_sflash_write_u8(cc, offset, *buf++);
 | 
			
		||||
+	/* Issue a page program with CSA bit set */
 | 
			
		||||
+	bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_CSA | BCMA_CC_FLASHCTL_ST_PP);
 | 
			
		||||
+	offset++;
 | 
			
		||||
+	len--;
 | 
			
		||||
+	while (len > 0) {
 | 
			
		||||
+		if ((offset & 255) == 0) {
 | 
			
		||||
+			/* Page boundary, poll droping cs and return */
 | 
			
		||||
+			bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0);
 | 
			
		||||
+			udelay(1);
 | 
			
		||||
+			if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+				/* Flash rejected command */
 | 
			
		||||
+				return -EAGAIN;
 | 
			
		||||
+			}
 | 
			
		||||
+			return written;
 | 
			
		||||
+		} else {
 | 
			
		||||
+			/* Write single byte */
 | 
			
		||||
+			bcma_sflash_cmd(cc,
 | 
			
		||||
+					BCMA_CC_FLASHCTL_ST_CSA |
 | 
			
		||||
+					*buf++);
 | 
			
		||||
+		}
 | 
			
		||||
+		written++;
 | 
			
		||||
+		offset++;
 | 
			
		||||
+		len--;
 | 
			
		||||
+		while (len > 0) {
 | 
			
		||||
+			if ((offset & 255) == 0) {
 | 
			
		||||
+				/* Page boundary, drop cs and return */
 | 
			
		||||
+				bcma_cc_mask32(cc, BCMA_CC_GPIOOUT, ~mask);
 | 
			
		||||
+				udelay(1);
 | 
			
		||||
+				if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+					/* Flash rejected command */
 | 
			
		||||
+					return -EAGAIN;
 | 
			
		||||
+				}
 | 
			
		||||
+				return ret;
 | 
			
		||||
+			} else {
 | 
			
		||||
+				/* Write single byte */
 | 
			
		||||
+				bcma_sflash_cmd(cc, *buf++);
 | 
			
		||||
+			}
 | 
			
		||||
+			ret++;
 | 
			
		||||
+			offset++;
 | 
			
		||||
+			len--;
 | 
			
		||||
+		}
 | 
			
		||||
+		/* All done, drop cs */
 | 
			
		||||
+		bcma_cc_mask32(cc, BCMA_CC_GPIOOUT, ~mask);
 | 
			
		||||
+		udelay(1);
 | 
			
		||||
+		if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+			/* Flash rejected command */
 | 
			
		||||
+			return -EAGAIN;
 | 
			
		||||
+		}
 | 
			
		||||
+	} else if (cc->core->id.rev >= 20) {
 | 
			
		||||
+		bcma_sflash_write_u8(cc, offset, *buf++);
 | 
			
		||||
+		/* Issue a page program with CSA bit set */
 | 
			
		||||
+		bcma_sflash_cmd(cc,
 | 
			
		||||
+				BCMA_CC_FLASHCTL_ST_CSA |
 | 
			
		||||
+				BCMA_CC_FLASHCTL_ST_PP);
 | 
			
		||||
+		ret = 1;
 | 
			
		||||
+		offset++;
 | 
			
		||||
+		len--;
 | 
			
		||||
+		while (len > 0) {
 | 
			
		||||
+			if ((offset & 255) == 0) {
 | 
			
		||||
+				/* Page boundary, poll droping cs and return */
 | 
			
		||||
+				bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0);
 | 
			
		||||
+				udelay(1);
 | 
			
		||||
+				if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+					/* Flash rejected command */
 | 
			
		||||
+					return -EAGAIN;
 | 
			
		||||
+				}
 | 
			
		||||
+				return ret;
 | 
			
		||||
+			} else {
 | 
			
		||||
+				/* Write single byte */
 | 
			
		||||
+				bcma_sflash_cmd(cc,
 | 
			
		||||
+						BCMA_CC_FLASHCTL_ST_CSA |
 | 
			
		||||
+						*buf++);
 | 
			
		||||
+			}
 | 
			
		||||
+			ret++;
 | 
			
		||||
+			offset++;
 | 
			
		||||
+			len--;
 | 
			
		||||
+		}
 | 
			
		||||
+		/* All done, drop cs & poll */
 | 
			
		||||
+		bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0);
 | 
			
		||||
+		udelay(1);
 | 
			
		||||
+		if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+			/* Flash rejected command */
 | 
			
		||||
+			return -EAGAIN;
 | 
			
		||||
+		}
 | 
			
		||||
+	} else {
 | 
			
		||||
+		ret = 1;
 | 
			
		||||
+		bcma_sflash_write_u8(cc, offset, *buf);
 | 
			
		||||
+		/* Page program */
 | 
			
		||||
+		bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_PP);
 | 
			
		||||
+	}
 | 
			
		||||
+	return ret;
 | 
			
		||||
+	/* All done, drop cs & poll */
 | 
			
		||||
+	bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0);
 | 
			
		||||
+	udelay(1);
 | 
			
		||||
+	if (!bcma_sflash_poll(cc, offset)) {
 | 
			
		||||
+		/* Flash rejected command */
 | 
			
		||||
+		return -EAGAIN;
 | 
			
		||||
+	}
 | 
			
		||||
+	return written;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int sflash_at_write(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
@ -410,6 +340,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	struct bcma_sflash *sfl = &cc->sflash;
 | 
			
		||||
+	u32 page, byte, mask;
 | 
			
		||||
+	int ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	mask = sfl->blocksize - 1;
 | 
			
		||||
+	page = (offset & ~mask) << 1;
 | 
			
		||||
+	byte = offset & mask;
 | 
			
		||||
@ -428,8 +359,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	/* Write into buffer 1 */
 | 
			
		||||
+	for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
 | 
			
		||||
+		bcma_sflash_write_u8(cc, byte++, *buf++);
 | 
			
		||||
+		bcma_sflash_cmd(cc,
 | 
			
		||||
+				BCMA_CC_FLASHCTL_AT_BUF1_WRITE);
 | 
			
		||||
+		bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_WRITE);
 | 
			
		||||
+	}
 | 
			
		||||
+	/* Write buffer 1 into main memory page */
 | 
			
		||||
+	bcma_cc_write32(cc, BCMA_CC_FLASHADDR, page);
 | 
			
		||||
@ -442,7 +372,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+ * written. Caller should poll for completion.
 | 
			
		||||
+ */
 | 
			
		||||
+int bcma_sflash_write(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			    const u8 *buf)
 | 
			
		||||
+		      const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_sflash *sfl;
 | 
			
		||||
+	int ret = 0, tries = NUM_RETRIES;
 | 
			
		||||
@ -493,7 +423,10 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+		 * with a new command: ST_SSE. The ST_SE command erases 64KB just as
 | 
			
		||||
+		 * before.
 | 
			
		||||
+		 */
 | 
			
		||||
+		bcma_sflash_cmd(cc, (sfl->blocksize < (64 * 1024)) ? BCMA_CC_FLASHCTL_ST_SSE : BCMA_CC_FLASHCTL_ST_SE);
 | 
			
		||||
+		if (sfl->blocksize < (64 * 1024))
 | 
			
		||||
+			bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SSE);
 | 
			
		||||
+		else
 | 
			
		||||
+			bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SE);
 | 
			
		||||
+		return sfl->blocksize;
 | 
			
		||||
+	case BCMA_CC_FLASHT_ATSER:
 | 
			
		||||
+		bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset << 1);
 | 
			
		||||
@ -503,113 +436,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * writes the appropriate range of flash, a NULL buf simply erases
 | 
			
		||||
+ * the region of flash
 | 
			
		||||
+ */
 | 
			
		||||
+int bcma_sflash_commit(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			     const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_sflash *sfl;
 | 
			
		||||
+	u8 *block = NULL, *cur_ptr, *blk_ptr;
 | 
			
		||||
+	u32 blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
 | 
			
		||||
+	u32 blk_offset, blk_len, copied;
 | 
			
		||||
+	int bytes, ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check address range */
 | 
			
		||||
+	if (len <= 0)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	sfl = &cc->sflash;
 | 
			
		||||
+	if ((offset + len) > sfl->size)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	blocksize = sfl->blocksize;
 | 
			
		||||
+	mask = blocksize - 1;
 | 
			
		||||
+
 | 
			
		||||
+	/* Allocate a block of mem */
 | 
			
		||||
+	block = kmalloc(blocksize, GFP_KERNEL);
 | 
			
		||||
+	if (!block)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	while (len) {
 | 
			
		||||
+		/* Align offset */
 | 
			
		||||
+		cur_offset = offset & ~mask;
 | 
			
		||||
+		cur_length = blocksize;
 | 
			
		||||
+		cur_ptr = block;
 | 
			
		||||
+
 | 
			
		||||
+		remainder = blocksize - (offset & mask);
 | 
			
		||||
+		if (len < remainder)
 | 
			
		||||
+			cur_retlen = len;
 | 
			
		||||
+		else
 | 
			
		||||
+			cur_retlen = remainder;
 | 
			
		||||
+
 | 
			
		||||
+		/* buf == NULL means erase only */
 | 
			
		||||
+		if (buf) {
 | 
			
		||||
+			/* Copy existing data into holding block if necessary */
 | 
			
		||||
+			if ((offset & mask) || (len < blocksize)) {
 | 
			
		||||
+				blk_offset = cur_offset;
 | 
			
		||||
+				blk_len = cur_length;
 | 
			
		||||
+				blk_ptr = cur_ptr;
 | 
			
		||||
+
 | 
			
		||||
+				/* Copy entire block */
 | 
			
		||||
+				while (blk_len) {
 | 
			
		||||
+					copied = bcma_sflash_read(cc,
 | 
			
		||||
+							blk_offset,
 | 
			
		||||
+							blk_len, blk_ptr);
 | 
			
		||||
+					blk_offset += copied;
 | 
			
		||||
+					blk_len -= copied;
 | 
			
		||||
+					blk_ptr += copied;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			/* Copy input data into holding block */
 | 
			
		||||
+			memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		/* Erase block */
 | 
			
		||||
+		ret = bcma_sflash_erase(cc, cur_offset);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			goto done;
 | 
			
		||||
+
 | 
			
		||||
+		while (bcma_sflash_poll(cc, cur_offset));
 | 
			
		||||
+
 | 
			
		||||
+		/* buf == NULL means erase only */
 | 
			
		||||
+		if (!buf) {
 | 
			
		||||
+			offset += cur_retlen;
 | 
			
		||||
+			len -= cur_retlen;
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		/* Write holding block */
 | 
			
		||||
+		while (cur_length > 0) {
 | 
			
		||||
+			bytes = bcma_sflash_write(cc, cur_offset,
 | 
			
		||||
+					cur_length, cur_ptr);
 | 
			
		||||
+
 | 
			
		||||
+			if (bytes < 0) {
 | 
			
		||||
+				ret = bytes;
 | 
			
		||||
+				goto done;
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			while (bcma_sflash_poll(cc, cur_offset))
 | 
			
		||||
+				;
 | 
			
		||||
+
 | 
			
		||||
+			cur_offset += bytes;
 | 
			
		||||
+			cur_length -= bytes;
 | 
			
		||||
+			cur_ptr += bytes;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		offset += cur_retlen;
 | 
			
		||||
+		len -= cur_retlen;
 | 
			
		||||
+		buf += cur_retlen;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ret = len;
 | 
			
		||||
+done:
 | 
			
		||||
+	kfree(block);
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
--- a/drivers/bcma/driver_mips.c
 | 
			
		||||
+++ b/drivers/bcma/driver_mips.c
 | 
			
		||||
@@ -185,7 +185,13 @@ static void bcma_core_mips_flash_detect(
 | 
			
		||||
@ -662,7 +488,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	};
 | 
			
		||||
 
 | 
			
		||||
 	int nr_serial_ports;
 | 
			
		||||
@@ -459,4 +471,16 @@ extern void bcma_chipco_chipctl_maskset(
 | 
			
		||||
@@ -459,4 +471,14 @@ extern void bcma_chipco_chipctl_maskset(
 | 
			
		||||
 extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
 | 
			
		||||
 				       u32 offset, u32 mask, u32 set);
 | 
			
		||||
 
 | 
			
		||||
@ -674,8 +500,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+int bcma_sflash_write(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			    const u8 *buf);
 | 
			
		||||
+int bcma_sflash_erase(struct bcma_drv_cc *cc, u32 offset);
 | 
			
		||||
+int bcma_sflash_commit(struct bcma_drv_cc *cc, u32 offset, u32 len,
 | 
			
		||||
+			     const u8 *buf);
 | 
			
		||||
+#endif /* CONFIG_BCMA_SFLASH */
 | 
			
		||||
+
 | 
			
		||||
 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,3 @@
 | 
			
		||||
From e8afde87ecf56beff67c7d5371cabaa4fc018541 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sat, 23 Jul 2011 23:57:06 +0200
 | 
			
		||||
Subject: [PATCH 14/26] ssb: move flash to chipcommon
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/bcm47xx/nvram.c                 |    8 +++---
 | 
			
		||||
 arch/mips/bcm47xx/wgt634u.c               |    8 +++---
 | 
			
		||||
 drivers/ssb/driver_mipscore.c             |   36 +++++++++++++++++++++-------
 | 
			
		||||
 include/linux/ssb/ssb_driver_chipcommon.h |   18 ++++++++++++++
 | 
			
		||||
 include/linux/ssb/ssb_driver_mips.h       |    4 ---
 | 
			
		||||
 5 files changed, 53 insertions(+), 21 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
@@ -27,7 +27,7 @@ static char nvram_buf[NVRAM_SPACE];
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,3 @@
 | 
			
		||||
From 980da78179592a3f5f99168bc5af415835aa8c13 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 24 Jul 2011 20:20:36 +0200
 | 
			
		||||
Subject: [PATCH 15/26] ssb: add serial flash support
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 drivers/ssb/Kconfig                       |    6 +
 | 
			
		||||
 drivers/ssb/Makefile                      |    1 +
 | 
			
		||||
 drivers/ssb/driver_chipcommon_sflash.c    |  556 +++++++++++++++++++++++++++++
 | 
			
		||||
 drivers/ssb/driver_mipscore.c             |    6 +
 | 
			
		||||
 drivers/ssb/ssb_private.h                 |    4 +
 | 
			
		||||
 include/linux/ssb/ssb_driver_chipcommon.h |   30 ++-
 | 
			
		||||
 6 files changed, 601 insertions(+), 2 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/ssb/driver_chipcommon_sflash.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/ssb/Kconfig
 | 
			
		||||
+++ b/drivers/ssb/Kconfig
 | 
			
		||||
@@ -137,6 +137,12 @@ config SSB_DRIVER_MIPS
 | 
			
		||||
@ -42,11 +25,12 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 ssb-$(CONFIG_SSB_DRIVER_PCICORE)	+= driver_pcicore.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/ssb/driver_chipcommon_sflash.c
 | 
			
		||||
@@ -0,0 +1,556 @@
 | 
			
		||||
@@ -0,0 +1,451 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Broadcom SiliconBackplane chipcommon serial flash interface
 | 
			
		||||
+ *
 | 
			
		||||
+ * Copyright 2011, Jonas Gorski <jonas.gorski@gmail.com>
 | 
			
		||||
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+ * Copyright 2010, Broadcom Corporation
 | 
			
		||||
+ *
 | 
			
		||||
+ * Licensed under the GNU/GPL. See COPYING for details.
 | 
			
		||||
@ -73,7 +57,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+static inline void ssb_sflash_write_u8(struct ssb_chipcommon *cc,
 | 
			
		||||
+					      u32 offset, u8 byte)
 | 
			
		||||
+				       u32 offset, u8 byte)
 | 
			
		||||
+{
 | 
			
		||||
+	chipco_write32(cc, SSB_CHIPCO_FLASHADDR, offset);
 | 
			
		||||
+	chipco_write32(cc, SSB_CHIPCO_FLASHDATA, byte);
 | 
			
		||||
@ -233,8 +217,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Read len bytes starting at offset into buf. Returns number of bytes read. */
 | 
			
		||||
+int ssb_sflash_read(struct ssb_chipcommon *cc, u32 offset, u32 len,
 | 
			
		||||
+			   u8 *buf)
 | 
			
		||||
+int ssb_sflash_read(struct ssb_chipcommon *cc, u32 offset, u32 len, u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 *from, *to;
 | 
			
		||||
+	u32 cnt, i;
 | 
			
		||||
@ -310,7 +293,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	bool is4712b0 = (bus->chip_id == 0x4712) && (bus->chip_rev == 3);
 | 
			
		||||
+	u32 mask;
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable writes */
 | 
			
		||||
+	ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_WREN);
 | 
			
		||||
+	if (is4712b0) {
 | 
			
		||||
@ -478,11 +460,14 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	case SSB_CHIPCO_FLASHT_STSER:
 | 
			
		||||
+		ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_WREN);
 | 
			
		||||
+		chipco_write32(cc, SSB_CHIPCO_FLASHADDR, offset);
 | 
			
		||||
+		/* Newer flashes have "sub-sectors" which can be erased independently
 | 
			
		||||
+		 * with a new command: ST_SSE. The ST_SE command erases 64KB just as
 | 
			
		||||
+		 * before.
 | 
			
		||||
+		/* Newer flashes have "sub-sectors" which can be erased
 | 
			
		||||
+		 * independently with a new command: ST_SSE. The ST_SE command
 | 
			
		||||
+		 * erases 64KB just as before.
 | 
			
		||||
+		 */
 | 
			
		||||
+		ssb_sflash_cmd(cc, (sfl->blocksize < (64 * 1024)) ? SSB_CHIPCO_FLASHCTL_ST_SSE : SSB_CHIPCO_FLASHCTL_ST_SE);
 | 
			
		||||
+		if (sfl->blocksize < (64 * 1024))
 | 
			
		||||
+			ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_SSE);
 | 
			
		||||
+		else
 | 
			
		||||
+			ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_SE);
 | 
			
		||||
+		return sfl->blocksize;
 | 
			
		||||
+	case SSB_CHIPCO_FLASHT_ATSER:
 | 
			
		||||
+		chipco_write32(cc, SSB_CHIPCO_FLASHADDR, offset << 1);
 | 
			
		||||
@ -492,113 +477,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * writes the appropriate range of flash, a NULL buf simply erases
 | 
			
		||||
+ * the region of flash
 | 
			
		||||
+ */
 | 
			
		||||
+int ssb_sflash_commit(struct ssb_chipcommon *cc, u32 offset, u32 len,
 | 
			
		||||
+			     const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct ssb_sflash *sfl;
 | 
			
		||||
+	u8 *block = NULL, *cur_ptr, *blk_ptr;
 | 
			
		||||
+	u32 blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
 | 
			
		||||
+	u32 blk_offset, blk_len, copied;
 | 
			
		||||
+	int bytes, ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check address range */
 | 
			
		||||
+	if (len <= 0)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	sfl = &cc->sflash;
 | 
			
		||||
+	if ((offset + len) > sfl->size)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	blocksize = sfl->blocksize;
 | 
			
		||||
+	mask = blocksize - 1;
 | 
			
		||||
+
 | 
			
		||||
+	/* Allocate a block of mem */
 | 
			
		||||
+	block = kmalloc(blocksize, GFP_KERNEL);
 | 
			
		||||
+	if (!block)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	while (len) {
 | 
			
		||||
+		/* Align offset */
 | 
			
		||||
+		cur_offset = offset & ~mask;
 | 
			
		||||
+		cur_length = blocksize;
 | 
			
		||||
+		cur_ptr = block;
 | 
			
		||||
+
 | 
			
		||||
+		remainder = blocksize - (offset & mask);
 | 
			
		||||
+		if (len < remainder)
 | 
			
		||||
+			cur_retlen = len;
 | 
			
		||||
+		else
 | 
			
		||||
+			cur_retlen = remainder;
 | 
			
		||||
+
 | 
			
		||||
+		/* buf == NULL means erase only */
 | 
			
		||||
+		if (buf) {
 | 
			
		||||
+			/* Copy existing data into holding block if necessary */
 | 
			
		||||
+			if ((offset & mask) || (len < blocksize)) {
 | 
			
		||||
+				blk_offset = cur_offset;
 | 
			
		||||
+				blk_len = cur_length;
 | 
			
		||||
+				blk_ptr = cur_ptr;
 | 
			
		||||
+
 | 
			
		||||
+				/* Copy entire block */
 | 
			
		||||
+				while (blk_len) {
 | 
			
		||||
+					copied = ssb_sflash_read(cc,
 | 
			
		||||
+							blk_offset,
 | 
			
		||||
+							blk_len, blk_ptr);
 | 
			
		||||
+					blk_offset += copied;
 | 
			
		||||
+					blk_len -= copied;
 | 
			
		||||
+					blk_ptr += copied;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			/* Copy input data into holding block */
 | 
			
		||||
+			memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		/* Erase block */
 | 
			
		||||
+		ret = ssb_sflash_erase(cc, cur_offset);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			goto done;
 | 
			
		||||
+
 | 
			
		||||
+		while (ssb_sflash_poll(cc, cur_offset));
 | 
			
		||||
+
 | 
			
		||||
+		/* buf == NULL means erase only */
 | 
			
		||||
+		if (!buf) {
 | 
			
		||||
+			offset += cur_retlen;
 | 
			
		||||
+			len -= cur_retlen;
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		/* Write holding block */
 | 
			
		||||
+		while (cur_length > 0) {
 | 
			
		||||
+			bytes = ssb_sflash_write(cc, cur_offset,
 | 
			
		||||
+					cur_length, cur_ptr);
 | 
			
		||||
+
 | 
			
		||||
+			if (bytes < 0) {
 | 
			
		||||
+				ret = bytes;
 | 
			
		||||
+				goto done;
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			while (ssb_sflash_poll(cc, cur_offset))
 | 
			
		||||
+				;
 | 
			
		||||
+
 | 
			
		||||
+			cur_offset += bytes;
 | 
			
		||||
+			cur_length -= bytes;
 | 
			
		||||
+			cur_ptr += bytes;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		offset += cur_retlen;
 | 
			
		||||
+		len -= cur_retlen;
 | 
			
		||||
+		buf += cur_retlen;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ret = len;
 | 
			
		||||
+done:
 | 
			
		||||
+	kfree(block);
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
--- a/drivers/ssb/driver_mipscore.c
 | 
			
		||||
+++ b/drivers/ssb/driver_mipscore.c
 | 
			
		||||
@@ -203,7 +203,13 @@ static void ssb_mips_flash_detect(struct
 | 
			
		||||
@ -676,7 +554,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	};
 | 
			
		||||
 #endif /* CONFIG_SSB_DRIVER_MIPS */
 | 
			
		||||
 };
 | 
			
		||||
@@ -666,6 +680,18 @@ extern int ssb_chipco_serial_init(struct
 | 
			
		||||
@@ -666,6 +680,16 @@ extern int ssb_chipco_serial_init(struct
 | 
			
		||||
 				  struct ssb_serial_port *ports);
 | 
			
		||||
 #endif /* CONFIG_SSB_SERIAL */
 | 
			
		||||
 
 | 
			
		||||
@ -688,8 +566,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+int ssb_sflash_write(struct ssb_chipcommon *cc, u32 offset, u32 len,
 | 
			
		||||
+			    const u8 *buf);
 | 
			
		||||
+int ssb_sflash_erase(struct ssb_chipcommon *cc, u32 offset);
 | 
			
		||||
+int ssb_sflash_commit(struct ssb_chipcommon *cc, u32 offset, u32 len,
 | 
			
		||||
+			     const u8 *buf);
 | 
			
		||||
+#endif /* CONFIG_SSB_SFLASH */
 | 
			
		||||
+
 | 
			
		||||
 /* PMU support */
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,3 @@
 | 
			
		||||
From 4f314ac9edbc80897f158fdb4e1b1de8a2d0d432 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 24 Jul 2011 21:10:49 +0200
 | 
			
		||||
Subject: [PATCH 16/26] brcm47xx: add common interface for sflash
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/bcm47xx/Makefile               |    2 +-
 | 
			
		||||
 arch/mips/bcm47xx/bus.c                  |   94 ++++++++++++++++++++++++++++++
 | 
			
		||||
 arch/mips/bcm47xx/setup.c                |    8 +++
 | 
			
		||||
 arch/mips/include/asm/mach-bcm47xx/bus.h |   37 ++++++++++++
 | 
			
		||||
 4 files changed, 140 insertions(+), 1 deletions(-)
 | 
			
		||||
 create mode 100644 arch/mips/bcm47xx/bus.c
 | 
			
		||||
 create mode 100644 arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/Makefile
 | 
			
		||||
+++ b/arch/mips/bcm47xx/Makefile
 | 
			
		||||
@@ -3,5 +3,5 @@
 | 
			
		||||
@ -25,7 +9,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/arch/mips/bcm47xx/bus.c
 | 
			
		||||
@@ -0,0 +1,94 @@
 | 
			
		||||
@@ -0,0 +1,82 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * BCM947xx nvram variable access
 | 
			
		||||
+ *
 | 
			
		||||
@ -59,11 +43,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	return bcma_sflash_erase(dev->bcc, offset);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int bcm47xx_sflash_bcma_commit(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	return bcma_sflash_commit(dev->bcc, offset, len, buf);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void bcm47xx_sflash_struct_bcma_init(struct bcm47xx_sflash *sflash, struct bcma_drv_cc *bcc)
 | 
			
		||||
+{
 | 
			
		||||
+	sflash->sflash_type = BCM47XX_BUS_TYPE_BCMA;
 | 
			
		||||
@ -73,7 +52,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	sflash->poll = bcm47xx_sflash_bcma_poll;
 | 
			
		||||
+	sflash->write = bcm47xx_sflash_bcma_write;
 | 
			
		||||
+	sflash->erase = bcm47xx_sflash_bcma_erase;
 | 
			
		||||
+	sflash->commit = bcm47xx_sflash_bcma_commit;
 | 
			
		||||
+
 | 
			
		||||
+	sflash->blocksize = bcc->sflash.blocksize;
 | 
			
		||||
+	sflash->numblocks = bcc->sflash.numblocks;
 | 
			
		||||
@ -100,11 +78,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	return ssb_sflash_erase(dev->scc, offset);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int bcm47xx_sflash_ssb_commit(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	return ssb_sflash_commit(dev->scc, offset, len, buf);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void bcm47xx_sflash_struct_ssb_init(struct bcm47xx_sflash *sflash, struct ssb_chipcommon *scc)
 | 
			
		||||
+{
 | 
			
		||||
+	sflash->sflash_type = BCM47XX_BUS_TYPE_SSB;
 | 
			
		||||
@ -114,7 +87,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	sflash->poll = bcm47xx_sflash_ssb_poll;
 | 
			
		||||
+	sflash->write = bcm47xx_sflash_ssb_write;
 | 
			
		||||
+	sflash->erase = bcm47xx_sflash_ssb_erase;
 | 
			
		||||
+	sflash->commit = bcm47xx_sflash_ssb_commit;
 | 
			
		||||
+
 | 
			
		||||
+	sflash->blocksize = scc->sflash.blocksize;
 | 
			
		||||
+	sflash->numblocks = scc->sflash.numblocks;
 | 
			
		||||
@ -153,7 +125,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
@@ -0,0 +1,37 @@
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * BCM947xx nvram variable access
 | 
			
		||||
+ *
 | 
			
		||||
@ -180,7 +152,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	int (*poll)(struct bcm47xx_sflash *dev, u32 offset);
 | 
			
		||||
+	int (*write)(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf);
 | 
			
		||||
+	int (*erase)(struct bcm47xx_sflash *dev, u32 offset);
 | 
			
		||||
+	int (*commit)(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf);
 | 
			
		||||
+
 | 
			
		||||
+	u32 blocksize;		/* Block size */
 | 
			
		||||
+	u32 numblocks;		/* Number of blocks */
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,3 @@
 | 
			
		||||
From d50d2d8e3ab5446f791deff0cb78820989ed93e7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 14:54:11 +0200
 | 
			
		||||
Subject: [PATCH 06/19] mtd: bcm47xx: add bcm47xx part parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 drivers/mtd/Kconfig       |    7 +
 | 
			
		||||
 drivers/mtd/Makefile      |    1 +
 | 
			
		||||
 drivers/mtd/bcm47xxpart.c |  542 +++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 3 files changed, 550 insertions(+), 0 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/mtd/bcm47xxpart.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/mtd/Kconfig
 | 
			
		||||
+++ b/drivers/mtd/Kconfig
 | 
			
		||||
@@ -164,6 +164,13 @@ config MTD_MYLOADER_PARTS
 | 
			
		||||
@ -500,7 +486,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+			/* Place CFE board_data into a partition */
 | 
			
		||||
+			bcm47xx_parts[4].name = "board_data";
 | 
			
		||||
+			bcm47xx_parts[4].offset = bcm47xx_parts[3].offset - custom_data_size;
 | 
			
		||||
+			bcm47xx_parts[4].size   =  custom_data_size;
 | 
			
		||||
+			bcm47xx_parts[4].size   = custom_data_size;
 | 
			
		||||
+			break;
 | 
			
		||||
+
 | 
			
		||||
+		case ROUTER_SIMPLETECH_SIMPLESHARE:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,3 @@
 | 
			
		||||
From 36f8b899174a445a98fe02ed8d1db177525f0c52 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 14:55:18 +0200
 | 
			
		||||
Subject: [PATCH 07/15] mtd: bcm47xx: add parallel flash driver
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 drivers/mtd/maps/Kconfig          |    9 ++
 | 
			
		||||
 drivers/mtd/maps/Makefile         |    1 +
 | 
			
		||||
 drivers/mtd/maps/bcm47xx-pflash.c |  188 +++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 3 files changed, 198 insertions(+), 0 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/mtd/maps/bcm47xx-pflash.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/mtd/maps/Kconfig
 | 
			
		||||
+++ b/drivers/mtd/maps/Kconfig
 | 
			
		||||
@@ -257,6 +257,15 @@ config MTD_LANTIQ
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,3 @@
 | 
			
		||||
From 2e2951220bf63e05449c03a95453680da1029e44 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 14:55:45 +0200
 | 
			
		||||
Subject: [PATCH 08/15] mtd: bcm47xx: add serial flash driver
 | 
			
		||||
 | 
			
		||||
sflash get the sflash ops from platform device
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/include/asm/mach-bcm47xx/bus.h |    3 +
 | 
			
		||||
 drivers/mtd/maps/Kconfig                 |    9 +
 | 
			
		||||
 drivers/mtd/maps/Makefile                |    1 +
 | 
			
		||||
 drivers/mtd/maps/bcm47xx-sflash.c        |  252 ++++++++++++++++++++++++++++++
 | 
			
		||||
 4 files changed, 265 insertions(+), 0 deletions(-)
 | 
			
		||||
 create mode 100644 drivers/mtd/maps/bcm47xx-sflash.c
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
+++ b/arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
@ -24,7 +8,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 #include <bcm47xx.h>
 | 
			
		||||
 
 | 
			
		||||
 struct bcm47xx_sflash {
 | 
			
		||||
@@ -29,6 +30,8 @@ struct bcm47xx_sflash {
 | 
			
		||||
@@ -28,6 +29,8 @@ struct bcm47xx_sflash {
 | 
			
		||||
 	u32 blocksize;		/* Block size */
 | 
			
		||||
 	u32 numblocks;		/* Number of blocks */
 | 
			
		||||
 	u32 size;		/* Total size in bytes */
 | 
			
		||||
@ -60,19 +44,15 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+obj-$(CONFIG_MTD_BCM47XX_SFLASH)+= bcm47xx-sflash.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/mtd/maps/bcm47xx-sflash.c
 | 
			
		||||
@@ -0,0 +1,252 @@
 | 
			
		||||
@@ -0,0 +1,263 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Broadcom SiliconBackplane chipcommon serial flash interface
 | 
			
		||||
+ *
 | 
			
		||||
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+ * Copyright 2006, Broadcom Corporation
 | 
			
		||||
+ * All Rights Reserved.
 | 
			
		||||
+ *
 | 
			
		||||
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
 | 
			
		||||
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
 | 
			
		||||
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 | 
			
		||||
+ *
 | 
			
		||||
+ * $Id$
 | 
			
		||||
+ * Licensed under the GNU/GPL. See COPYING for details.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#define pr_fmt(fmt) "bcm47xx_sflash: " fmt
 | 
			
		||||
@ -93,28 +73,27 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+sflash_mtd_poll(struct bcm47xx_sflash *sflash, unsigned int offset, int timeout)
 | 
			
		||||
+{
 | 
			
		||||
+	unsigned long now = jiffies;
 | 
			
		||||
+	int ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	for (;;) {
 | 
			
		||||
+		if (!sflash->poll(sflash, offset)) {
 | 
			
		||||
+			ret = 0;
 | 
			
		||||
+			break;
 | 
			
		||||
+		}
 | 
			
		||||
+		if (time_after(jiffies, now + timeout)) {
 | 
			
		||||
+			pr_err("timeout while polling\n");
 | 
			
		||||
+			ret = -ETIMEDOUT;
 | 
			
		||||
+			break;
 | 
			
		||||
+			return -ETIMEDOUT;
 | 
			
		||||
+
 | 
			
		||||
+		}
 | 
			
		||||
+		cpu_relax();
 | 
			
		||||
+		udelay(1);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *) mtd->priv;
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *)mtd->priv;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check address range */
 | 
			
		||||
+	if (!len)
 | 
			
		||||
@ -124,7 +103,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	*retlen = 0;
 | 
			
		||||
+
 | 
			
		||||
+	while (len) {
 | 
			
		||||
+		int ret = sflash->read(sflash, from, len, buf);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
@ -142,7 +120,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+static int
 | 
			
		||||
+sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *) mtd->priv;
 | 
			
		||||
+	int bytes;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *)mtd->priv;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check address range */
 | 
			
		||||
+	if (!len)
 | 
			
		||||
@ -153,8 +133,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+
 | 
			
		||||
+	*retlen = 0;
 | 
			
		||||
+	while (len) {
 | 
			
		||||
+		int bytes;
 | 
			
		||||
+		int ret = sflash->write(sflash, to, len, buf);
 | 
			
		||||
+		ret = sflash->write(sflash, to, len, buf);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
@ -228,26 +207,30 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = dev_get_platdata(&pdev->dev);
 | 
			
		||||
+	struct mtd_info *mtd;
 | 
			
		||||
+	struct mtd_erase_region_info *regions;
 | 
			
		||||
+	struct mtd_erase_region_info *eraseregions;
 | 
			
		||||
+	int ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
 | 
			
		||||
+	if (!mtd)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+	if (!mtd){
 | 
			
		||||
+		ret =  -ENOMEM;
 | 
			
		||||
+		goto err_out;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	regions = kzalloc(sizeof(struct mtd_erase_region_info), GFP_KERNEL);
 | 
			
		||||
+	if (!mtd)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+	eraseregions = kzalloc(sizeof(struct mtd_erase_region_info), GFP_KERNEL);
 | 
			
		||||
+	if (!eraseregions) {
 | 
			
		||||
+		ret =  -ENOMEM;
 | 
			
		||||
+		goto err_free_mtd;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	pr_info("found serial flash: blocksize=%dKB, numblocks=%d, size=%dKB\n",
 | 
			
		||||
+		sflash->blocksize/1024, sflash->numblocks, sflash->size / 1024);
 | 
			
		||||
+		sflash->blocksize / 1024, sflash->numblocks, sflash->size / 1024);
 | 
			
		||||
+
 | 
			
		||||
+	/* Setup region info */
 | 
			
		||||
+	regions->offset = 0;
 | 
			
		||||
+	regions->erasesize = sflash->blocksize;
 | 
			
		||||
+	regions->numblocks = sflash->numblocks;
 | 
			
		||||
+	if (regions->erasesize > mtd->erasesize)
 | 
			
		||||
+		mtd->erasesize = regions->erasesize;
 | 
			
		||||
+	eraseregions->offset = 0;
 | 
			
		||||
+	eraseregions->erasesize = sflash->blocksize;
 | 
			
		||||
+	eraseregions->numblocks = sflash->numblocks;
 | 
			
		||||
+	if (eraseregions->erasesize > mtd->erasesize)
 | 
			
		||||
+		mtd->erasesize = eraseregions->erasesize;
 | 
			
		||||
+	mtd->size = sflash->size;
 | 
			
		||||
+	mtd->numeraseregions = 1;
 | 
			
		||||
+
 | 
			
		||||
@ -255,33 +238,45 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	mtd->name = "bcm47xx-sflash";
 | 
			
		||||
+	mtd->type = MTD_NORFLASH;
 | 
			
		||||
+	mtd->flags = MTD_CAP_NORFLASH;
 | 
			
		||||
+	mtd->eraseregions = regions;
 | 
			
		||||
+	mtd->eraseregions = eraseregions;
 | 
			
		||||
+	mtd->erase = sflash_mtd_erase;
 | 
			
		||||
+	mtd->read = sflash_mtd_read;
 | 
			
		||||
+	mtd->write = sflash_mtd_write;
 | 
			
		||||
+	mtd->writesize = 1;
 | 
			
		||||
+	mtd->priv = sflash;
 | 
			
		||||
+	ret = dev_set_drvdata(&pdev->dev, mtd);
 | 
			
		||||
+	mtd->owner = THIS_MODULE;
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
+		pr_err("adding private data failed\n");
 | 
			
		||||
+		goto err_free_eraseregions;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
 | 
			
		||||
+
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
+		pr_err("mtd_device_register failed\n");
 | 
			
		||||
+		return ret;
 | 
			
		||||
+		goto err_free_eraseregions;
 | 
			
		||||
+	}
 | 
			
		||||
+	sflash->mtd = mtd;
 | 
			
		||||
+	return 0;
 | 
			
		||||
+
 | 
			
		||||
+err_free_eraseregions:
 | 
			
		||||
+	kfree(eraseregions);
 | 
			
		||||
+err_free_mtd:
 | 
			
		||||
+	kfree(mtd);
 | 
			
		||||
+err_out:
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int __devexit bcm47xx_sflash_remove(struct platform_device *pdev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcm47xx_sflash *sflash = dev_get_platdata(&pdev->dev);
 | 
			
		||||
+	struct mtd_info *mtd = dev_get_drvdata(&pdev->dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (sflash) {
 | 
			
		||||
+		mtd_device_unregister(sflash->mtd);
 | 
			
		||||
+		map_destroy(sflash->mtd);
 | 
			
		||||
+		kfree(sflash->mtd->eraseregions);
 | 
			
		||||
+		kfree(sflash->mtd);
 | 
			
		||||
+	if (mtd) {
 | 
			
		||||
+		mtd_device_unregister(mtd);
 | 
			
		||||
+		map_destroy(mtd);
 | 
			
		||||
+		kfree(mtd->eraseregions);
 | 
			
		||||
+		kfree(mtd);
 | 
			
		||||
+		dev_set_drvdata(&pdev->dev, NULL);
 | 
			
		||||
+	}
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,21 @@
 | 
			
		||||
From 64f3d068654589d6114048ac5933cd4498706cfc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sun, 17 Jul 2011 15:02:10 +0200
 | 
			
		||||
Subject: [PATCH 20/26] bcm47xx: register flash drivers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/bcm47xx/setup.c |   72 +++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 files changed, 72 insertions(+), 0 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/Kconfig
 | 
			
		||||
+++ b/arch/mips/bcm47xx/Kconfig
 | 
			
		||||
@@ -9,6 +9,7 @@ config BCM47XX_SSB
 | 
			
		||||
 	select SSB_EMBEDDED
 | 
			
		||||
 	select SSB_B43_PCI_BRIDGE if PCI
 | 
			
		||||
 	select SSB_PCICORE_HOSTMODE if PCI
 | 
			
		||||
+	select SSB_SFLASH
 | 
			
		||||
 	default y
 | 
			
		||||
 	help
 | 
			
		||||
 	 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
 | 
			
		||||
@@ -22,6 +23,7 @@ config BCM47XX_BCMA
 | 
			
		||||
 	select BCMA_HOST_SOC
 | 
			
		||||
 	select BCMA_DRIVER_MIPS
 | 
			
		||||
 	select BCMA_DRIVER_PCI_HOSTMODE if PCI
 | 
			
		||||
+	select BCMA_SFLASH
 | 
			
		||||
 	default y
 | 
			
		||||
 	help
 | 
			
		||||
 	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -31,10 +31,12 @@
 | 
			
		||||
@ -24,11 +31,10 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 #include <asm/mach-bcm47xx/nvram.h>
 | 
			
		||||
 
 | 
			
		||||
 union bcm47xx_bus bcm47xx_bus;
 | 
			
		||||
@@ -366,3 +368,73 @@ static int __init bcm47xx_register_bus_c
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 device_initcall(bcm47xx_register_bus_complete);
 | 
			
		||||
+
 | 
			
		||||
@@ -45,6 +47,32 @@ EXPORT_SYMBOL(bcm47xx_bus_type);
 | 
			
		||||
 
 | 
			
		||||
 struct bcm47xx_sflash bcm47xx_sflash;
 | 
			
		||||
 
 | 
			
		||||
+static struct resource bcm47xx_pflash_resource = {
 | 
			
		||||
+	.name	= "bcm47xx_pflash",
 | 
			
		||||
+	.start	= 0,
 | 
			
		||||
@ -54,45 +60,75 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	.resource	= &bcm47xx_sflash_resource,
 | 
			
		||||
+	.num_resources	= 1,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static void bcm47xx_machine_restart(char *command)
 | 
			
		||||
 {
 | 
			
		||||
 	printk(KERN_ALERT "Please stand by while rebooting the system...\n");
 | 
			
		||||
@@ -310,6 +338,24 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
+
 | 
			
		||||
+static int __init bcm47xx_register_flash_ssb(void)
 | 
			
		||||
+{
 | 
			
		||||
+	struct ssb_chipcommon *chipco = &bcm47xx_bus.ssb.chipco;
 | 
			
		||||
+
 | 
			
		||||
+	switch (chipco->flash_type) {
 | 
			
		||||
+	case SSB_PFLASH:
 | 
			
		||||
+		bcm47xx_pflash_resource.start = chipco->pflash.window;
 | 
			
		||||
+		bcm47xx_pflash_resource.end = chipco->pflash.window + chipco->pflash.window_size;
 | 
			
		||||
+		return platform_device_register(&bcm47xx_pflash_dev);
 | 
			
		||||
+	case SSB_SFLASH:
 | 
			
		||||
+		bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
+		return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+	default:
 | 
			
		||||
+		printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
+		return -1;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
@@ -324,6 +370,24 @@ static void __init bcm47xx_register_bcma
 | 
			
		||||
 	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH)
 | 
			
		||||
 		bcm47xx_sflash_struct_bcma_init(&bcm47xx_sflash, &bcm47xx_bus.bcma.bus.drv_cc);
 | 
			
		||||
 }
 | 
			
		||||
+
 | 
			
		||||
+static int __init bcm47xx_register_flash_bcma(void)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_drv_cc *drv_cc = &bcm47xx_bus.bcma.bus.drv_cc;
 | 
			
		||||
+
 | 
			
		||||
+	switch (drv_cc->flash_type) {
 | 
			
		||||
+	case BCMA_PFLASH:
 | 
			
		||||
+		bcm47xx_pflash_resource.start = drv_cc->pflash.window;
 | 
			
		||||
+		bcm47xx_pflash_resource.end = drv_cc->pflash.window + drv_cc->pflash.window_size;
 | 
			
		||||
+		return platform_device_register(&bcm47xx_pflash_dev);
 | 
			
		||||
+	case BCMA_SFLASH:
 | 
			
		||||
+		bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
+		return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+	default:
 | 
			
		||||
+		printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
+		return -1;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 void __init plat_mem_setup(void)
 | 
			
		||||
@@ -366,3 +430,19 @@ static int __init bcm47xx_register_bus_c
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 device_initcall(bcm47xx_register_bus_complete);
 | 
			
		||||
+
 | 
			
		||||
+static int __init bcm47xx_register_flash(void)
 | 
			
		||||
+{
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
+	struct ssb_chipcommon *chipco;
 | 
			
		||||
+#endif
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
+	struct bcma_drv_cc *drv_cc;
 | 
			
		||||
+#endif
 | 
			
		||||
+	switch (bcm47xx_bus_type) {
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
+	case BCM47XX_BUS_TYPE_SSB:
 | 
			
		||||
+		chipco = &bcm47xx_bus.ssb.chipco;
 | 
			
		||||
+		if (chipco->flash_type == SSB_PFLASH) {
 | 
			
		||||
+			bcm47xx_pflash_resource.start = chipco->pflash.window;
 | 
			
		||||
+			bcm47xx_pflash_resource.end = chipco->pflash.window + chipco->pflash.window_size;
 | 
			
		||||
+			return platform_device_register(&bcm47xx_pflash_dev);
 | 
			
		||||
+		} else if (chipco->flash_type == SSB_SFLASH) {
 | 
			
		||||
+			bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
+			return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
+			return -1;
 | 
			
		||||
+		}
 | 
			
		||||
+		return bcm47xx_register_flash_ssb();
 | 
			
		||||
+#endif
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
+	case BCM47XX_BUS_TYPE_BCMA:
 | 
			
		||||
+		drv_cc = &bcm47xx_bus.bcma.bus.drv_cc;
 | 
			
		||||
+		if (drv_cc->flash_type == BCMA_PFLASH) {
 | 
			
		||||
+			bcm47xx_pflash_resource.start = drv_cc->pflash.window;
 | 
			
		||||
+			bcm47xx_pflash_resource.end = drv_cc->pflash.window + drv_cc->pflash.window_size;
 | 
			
		||||
+			return platform_device_register(&bcm47xx_pflash_dev);
 | 
			
		||||
+		} else if (drv_cc->flash_type == BCMA_SFLASH) {
 | 
			
		||||
+			bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
+			return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
+			return -1;
 | 
			
		||||
+		}
 | 
			
		||||
+		return bcm47xx_register_flash_bcma();
 | 
			
		||||
+#endif
 | 
			
		||||
+	}
 | 
			
		||||
+	return -1;
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,3 @@
 | 
			
		||||
From 1d693b2c9d5943cbe938f879041b837cd004737f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
Date: Sat, 23 Jul 2011 18:29:38 +0200
 | 
			
		||||
Subject: [PATCH 25/26] bcm47xx: read nvram from sflash
 | 
			
		||||
 | 
			
		||||
bcm47xx: add sflash support to nvram
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
---
 | 
			
		||||
 arch/mips/bcm47xx/nvram.c |   86 +++++++++++++++++++++++++++++++++++++++++++-
 | 
			
		||||
 1 files changed, 84 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
@@ -20,11 +20,12 @@
 | 
			
		||||
@ -26,7 +14,17 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 {
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
 	struct ssb_chipcommon *ssb_cc;
 | 
			
		||||
@@ -86,7 +87,88 @@ found:
 | 
			
		||||
@@ -50,9 +51,6 @@ static void early_nvram_init(void)
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
 	case BCM47XX_BUS_TYPE_BCMA:
 | 
			
		||||
 		bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
 | 
			
		||||
-		if (bcma_cc->flash_type != BCMA_PFLASH)
 | 
			
		||||
-			return;
 | 
			
		||||
-
 | 
			
		||||
 		base = bcma_cc->pflash.window;
 | 
			
		||||
 		lim = bcma_cc->pflash.window_size;
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -86,7 +84,106 @@ found:
 | 
			
		||||
 	for (i = 0; i < sizeof(struct nvram_header); i += 4)
 | 
			
		||||
 		*dst++ = *src++;
 | 
			
		||||
 	for (; i < header->len && i < NVRAM_SPACE; i += 4)
 | 
			
		||||
@ -81,35 +79,53 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
+static void early_nvram_init_ssb(void)
 | 
			
		||||
+{
 | 
			
		||||
+	int err;
 | 
			
		||||
+
 | 
			
		||||
+	switch (bcm47xx_bus.ssb.chipco.flash_type) {
 | 
			
		||||
+	case SSB_PFLASH:
 | 
			
		||||
+		early_nvram_init_pflash();
 | 
			
		||||
+	case SSB_SFLASH:
 | 
			
		||||
+		err = early_nvram_init_sflash();
 | 
			
		||||
+		if (err < 0)
 | 
			
		||||
+			printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+	default:
 | 
			
		||||
+		printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
+static void early_nvram_init_bcma(void)
 | 
			
		||||
+{
 | 
			
		||||
+	int err;
 | 
			
		||||
+
 | 
			
		||||
+	switch (bcm47xx_bus.bcma.bus.drv_cc.flash_type) {
 | 
			
		||||
+	case BCMA_PFLASH:
 | 
			
		||||
+		early_nvram_init_pflash();
 | 
			
		||||
+	case BCMA_SFLASH:
 | 
			
		||||
+		err = early_nvram_init_sflash();
 | 
			
		||||
+		if (err < 0)
 | 
			
		||||
+			printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+	default:
 | 
			
		||||
+		printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
+static void early_nvram_init(void)
 | 
			
		||||
+{
 | 
			
		||||
+	int err = 0;
 | 
			
		||||
+
 | 
			
		||||
+	switch (bcm47xx_bus_type) {
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
+	case BCM47XX_BUS_TYPE_SSB:
 | 
			
		||||
+		if (bcm47xx_bus.ssb.chipco.flash_type == SSB_PFLASH) {
 | 
			
		||||
+			early_nvram_init_pflash();
 | 
			
		||||
+		} else if (bcm47xx_bus.ssb.chipco.flash_type == SSB_SFLASH) {
 | 
			
		||||
+			err = early_nvram_init_sflash();
 | 
			
		||||
+			if (err < 0)
 | 
			
		||||
+				printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
+		}
 | 
			
		||||
+		early_nvram_init_ssb();
 | 
			
		||||
+		break;
 | 
			
		||||
+#endif
 | 
			
		||||
+#ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
+	case BCM47XX_BUS_TYPE_BCMA:
 | 
			
		||||
+		if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_PFLASH) {
 | 
			
		||||
+			early_nvram_init_pflash();
 | 
			
		||||
+		} else if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH) {
 | 
			
		||||
+			err = early_nvram_init_sflash();
 | 
			
		||||
+			if (err < 0)
 | 
			
		||||
+				printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
+		}
 | 
			
		||||
+		early_nvram_init_bcma();
 | 
			
		||||
+		break;
 | 
			
		||||
+#endif
 | 
			
		||||
+	}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
--- a/arch/mips/bcm47xx/Kconfig
 | 
			
		||||
+++ b/arch/mips/bcm47xx/Kconfig
 | 
			
		||||
@@ -24,6 +24,7 @@ config BCM47XX_BCMA
 | 
			
		||||
 	select BCMA_DRIVER_MIPS
 | 
			
		||||
 	select BCMA_DRIVER_PCI_HOSTMODE if PCI
 | 
			
		||||
 	select BCMA_SFLASH
 | 
			
		||||
+	select BCMA_NFLASH
 | 
			
		||||
 	default y
 | 
			
		||||
 	help
 | 
			
		||||
 	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
 | 
			
		||||
--- a/arch/mips/bcm47xx/bus.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/bus.c
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
@ -8,7 +18,7 @@
 | 
			
		||||
  *
 | 
			
		||||
  * This program is free software; you can redistribute  it and/or modify it
 | 
			
		||||
  * under  the terms of  the GNU General  Public License as published by the
 | 
			
		||||
@@ -92,3 +93,9 @@ void bcm47xx_sflash_struct_ssb_init(stru
 | 
			
		||||
@@ -80,3 +81,9 @@ void bcm47xx_sflash_struct_ssb_init(stru
 | 
			
		||||
 	sflash->numblocks = scc->sflash.numblocks;
 | 
			
		||||
 	sflash->size = scc->sflash.size;
 | 
			
		||||
 }
 | 
			
		||||
@ -36,7 +46,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static char nvram_buf[NVRAM_SPACE];
 | 
			
		||||
 
 | 
			
		||||
@@ -137,6 +139,51 @@ found:
 | 
			
		||||
@@ -134,6 +136,51 @@ found:
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@ -85,20 +95,20 @@
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void early_nvram_init(void)
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
 static void early_nvram_init_ssb(void)
 | 
			
		||||
 {
 | 
			
		||||
 	int err = 0;
 | 
			
		||||
@@ -163,6 +210,10 @@ static void early_nvram_init(void)
 | 
			
		||||
 			err = early_nvram_init_sflash();
 | 
			
		||||
 			if (err < 0)
 | 
			
		||||
 				printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+		} else if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_NFLASH) {
 | 
			
		||||
+			err = early_nvram_init_nflash();
 | 
			
		||||
+			if (err < 0)
 | 
			
		||||
+				printk(KERN_WARNING "can not read from nflash: %i\n", err);
 | 
			
		||||
 		} else {
 | 
			
		||||
 			printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
 		}
 | 
			
		||||
@@ -164,6 +211,10 @@ static void early_nvram_init_bcma(void)
 | 
			
		||||
 		err = early_nvram_init_sflash();
 | 
			
		||||
 		if (err < 0)
 | 
			
		||||
 			printk(KERN_WARNING "can not read from flash: %i\n", err);
 | 
			
		||||
+	case BCMA_NFLASH:
 | 
			
		||||
+		err = early_nvram_init_nflash();
 | 
			
		||||
+		if (err < 0)
 | 
			
		||||
+			printk(KERN_WARNING "can not read from nflash: %i\n", err);
 | 
			
		||||
 	default:
 | 
			
		||||
 		printk(KERN_WARNING "unknow flash type\n");
 | 
			
		||||
 	}
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
@ -115,19 +125,9 @@
 | 
			
		||||
 struct bcm47xx_sflash bcm47xx_sflash;
 | 
			
		||||
+struct bcm47xx_nflash bcm47xx_nflash;
 | 
			
		||||
 
 | 
			
		||||
 static void bcm47xx_machine_restart(char *command)
 | 
			
		||||
 {
 | 
			
		||||
@@ -325,6 +327,9 @@ static void __init bcm47xx_register_bcma
 | 
			
		||||
 
 | 
			
		||||
 	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH)
 | 
			
		||||
 		bcm47xx_sflash_struct_bcma_init(&bcm47xx_sflash, &bcm47xx_bus.bcma.bus.drv_cc);
 | 
			
		||||
+	
 | 
			
		||||
+	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_NFLASH)
 | 
			
		||||
+		bcm47xx_nflash_struct_bcma_init(&bcm47xx_nflash, &bcm47xx_bus.bcma.bus.drv_cc);
 | 
			
		||||
 }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -395,6 +400,19 @@ static struct platform_device bcm47xx_sf
 | 
			
		||||
 static struct resource bcm47xx_pflash_resource = {
 | 
			
		||||
 	.name	= "bcm47xx_pflash",
 | 
			
		||||
@@ -73,6 +75,19 @@ static struct platform_device bcm47xx_sf
 | 
			
		||||
 	.num_resources	= 1,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@ -144,19 +144,29 @@
 | 
			
		||||
+	.num_resources	= 1,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static int __init bcm47xx_register_flash(void)
 | 
			
		||||
 static void bcm47xx_machine_restart(char *command)
 | 
			
		||||
 {
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
@@ -429,6 +447,9 @@ static int __init bcm47xx_register_flash
 | 
			
		||||
 		} else if (drv_cc->flash_type == BCMA_SFLASH) {
 | 
			
		||||
 			bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
 			return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+		} else if (drv_cc->flash_type == BCMA_NFLASH) {
 | 
			
		||||
+			bcm47xx_nflash_dev.dev.platform_data = &bcm47xx_nflash;
 | 
			
		||||
+			return platform_device_register(&bcm47xx_nflash_dev);
 | 
			
		||||
 		} else {
 | 
			
		||||
 			printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
 			return -1;
 | 
			
		||||
 	printk(KERN_ALERT "Please stand by while rebooting the system...\n");
 | 
			
		||||
@@ -369,6 +384,9 @@ static void __init bcm47xx_register_bcma
 | 
			
		||||
 
 | 
			
		||||
 	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH)
 | 
			
		||||
 		bcm47xx_sflash_struct_bcma_init(&bcm47xx_sflash, &bcm47xx_bus.bcma.bus.drv_cc);
 | 
			
		||||
+	
 | 
			
		||||
+	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_NFLASH)
 | 
			
		||||
+		bcm47xx_nflash_struct_bcma_init(&bcm47xx_nflash, &bcm47xx_bus.bcma.bus.drv_cc);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int __init bcm47xx_register_flash_bcma(void)
 | 
			
		||||
@@ -383,6 +401,9 @@ static int __init bcm47xx_register_flash
 | 
			
		||||
 	case BCMA_SFLASH:
 | 
			
		||||
 		bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash;
 | 
			
		||||
 		return platform_device_register(&bcm47xx_sflash_dev);
 | 
			
		||||
+	case BCMA_NFLASH:
 | 
			
		||||
+		bcm47xx_nflash_dev.dev.platform_data = &bcm47xx_nflash;
 | 
			
		||||
+		return platform_device_register(&bcm47xx_nflash_dev);
 | 
			
		||||
 	default:
 | 
			
		||||
 		printk(KERN_ERR "No flash device found\n");
 | 
			
		||||
 		return -1;
 | 
			
		||||
--- a/arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
+++ b/arch/mips/include/asm/mach-bcm47xx/bus.h
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
@ -175,7 +185,15 @@
 | 
			
		||||
 
 | 
			
		||||
 struct bcm47xx_sflash {
 | 
			
		||||
 	enum bcm47xx_bus_type sflash_type;
 | 
			
		||||
@@ -38,3 +40,18 @@ void bcm47xx_sflash_struct_bcma_init(str
 | 
			
		||||
@@ -29,11 +31,24 @@ struct bcm47xx_sflash {
 | 
			
		||||
 	u32 blocksize;		/* Block size */
 | 
			
		||||
 	u32 numblocks;		/* Number of blocks */
 | 
			
		||||
 	u32 size;		/* Total size in bytes */
 | 
			
		||||
-
 | 
			
		||||
-	struct mtd_info *mtd;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 void bcm47xx_sflash_struct_bcma_init(struct bcm47xx_sflash *sflash, struct bcma_drv_cc *bcc);
 | 
			
		||||
 void bcm47xx_sflash_struct_ssb_init(struct bcm47xx_sflash *sflash, struct ssb_chipcommon *scc);
 | 
			
		||||
 
 | 
			
		||||
 extern struct bcm47xx_sflash bcm47xx_sflash;
 | 
			
		||||
@ -194,6 +212,30 @@
 | 
			
		||||
+void bcm47xx_nflash_struct_bcma_init(struct bcm47xx_nflash *nflash, struct bcma_drv_cc *bcc);
 | 
			
		||||
+
 | 
			
		||||
+extern struct bcm47xx_nflash bcm47xx_nflash;
 | 
			
		||||
--- a/drivers/bcma/Kconfig
 | 
			
		||||
+++ b/drivers/bcma/Kconfig
 | 
			
		||||
@@ -43,6 +43,11 @@ config BCMA_SFLASH
 | 
			
		||||
 	depends on BCMA_DRIVER_MIPS
 | 
			
		||||
 	default y
 | 
			
		||||
 
 | 
			
		||||
+config BCMA_NFLASH
 | 
			
		||||
+	bool
 | 
			
		||||
+	depends on BCMA_DRIVER_MIPS
 | 
			
		||||
+	default y
 | 
			
		||||
+
 | 
			
		||||
 config BCMA_DRIVER_MIPS
 | 
			
		||||
 	bool "BCMA Broadcom MIPS core driver"
 | 
			
		||||
 	depends on BCMA && MIPS
 | 
			
		||||
--- a/drivers/bcma/Makefile
 | 
			
		||||
+++ b/drivers/bcma/Makefile
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
 bcma-y					+= main.o scan.o core.o sprom.o
 | 
			
		||||
 bcma-y					+= driver_chipcommon.o driver_chipcommon_pmu.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_SFLASH)		+= driver_chipcommon_sflash.o
 | 
			
		||||
+bcma-$(CONFIG_BCMA_NFLASH)		+= driver_chipcommon_nflash.o
 | 
			
		||||
 bcma-y					+= driver_pci.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)	+= driver_pci_host.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_DRIVER_MIPS)		+= driver_mips.o
 | 
			
		||||
--- a/drivers/bcma/bcma_private.h
 | 
			
		||||
+++ b/drivers/bcma/bcma_private.h
 | 
			
		||||
@@ -46,6 +46,11 @@ u32 bcma_pmu_get_clockcpu(struct bcma_dr
 | 
			
		||||
@ -320,7 +362,7 @@
 | 
			
		||||
+	mask = cc->nflash.pagesize - 1;
 | 
			
		||||
+	if (bcma_nflash_offset_is_valid(cc, offset, len, mask))
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	
 | 
			
		||||
+
 | 
			
		||||
+	/* disable partial page enable */
 | 
			
		||||
+	reg = bcma_cc_read32(cc, NAND_ACC_CONTROL);
 | 
			
		||||
+	reg &= ~NAC_PARTIAL_PAGE_EN;
 | 
			
		||||
@ -349,7 +391,7 @@
 | 
			
		||||
+		return (len - res);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Erase a region. Returns success (0) or failure (-1). 
 | 
			
		||||
+/* Erase a region. Returns success (0) or failure (-1).
 | 
			
		||||
+ * Poll for completion.
 | 
			
		||||
+ */
 | 
			
		||||
+int bcma_nflash_erase(struct bcma_drv_cc *cc, u32 offset)
 | 
			
		||||
@ -393,30 +435,30 @@
 | 
			
		||||
 	switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
 | 
			
		||||
 	case BCMA_CC_FLASHT_STSER:
 | 
			
		||||
 	case BCMA_CC_FLASHT_ATSER:
 | 
			
		||||
--- a/drivers/bcma/Kconfig
 | 
			
		||||
+++ b/drivers/bcma/Kconfig
 | 
			
		||||
@@ -43,6 +43,11 @@ config BCMA_SFLASH
 | 
			
		||||
 	depends on BCMA_DRIVER_MIPS
 | 
			
		||||
 	default y
 | 
			
		||||
--- a/drivers/mtd/nand/Kconfig
 | 
			
		||||
+++ b/drivers/mtd/nand/Kconfig
 | 
			
		||||
@@ -537,4 +537,12 @@ config MTD_NAND_FSMC
 | 
			
		||||
 	  Enables support for NAND Flash chips on the ST Microelectronics
 | 
			
		||||
 	  Flexible Static Memory Controller (FSMC)
 | 
			
		||||
 
 | 
			
		||||
+config BCMA_NFLASH
 | 
			
		||||
+	bool
 | 
			
		||||
+	depends on BCMA_DRIVER_MIPS
 | 
			
		||||
+config MTD_NAND_BCM47XX
 | 
			
		||||
+	tristate "bcm47xx nand flash support"
 | 
			
		||||
+	default y
 | 
			
		||||
+	depends on BCM47XX
 | 
			
		||||
+	select MTD_PARTITIONS
 | 
			
		||||
+	help
 | 
			
		||||
+	  Support for bcm47xx nand flash
 | 
			
		||||
+
 | 
			
		||||
 config BCMA_DRIVER_MIPS
 | 
			
		||||
 	bool "BCMA Broadcom MIPS core driver"
 | 
			
		||||
 	depends on BCMA && MIPS
 | 
			
		||||
--- a/drivers/bcma/Makefile
 | 
			
		||||
+++ b/drivers/bcma/Makefile
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
 bcma-y					+= main.o scan.o core.o sprom.o
 | 
			
		||||
 bcma-y					+= driver_chipcommon.o driver_chipcommon_pmu.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_SFLASH)		+= driver_chipcommon_sflash.o
 | 
			
		||||
+bcma-$(CONFIG_BCMA_NFLASH)		+= driver_chipcommon_nflash.o
 | 
			
		||||
 bcma-y					+= driver_pci.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)	+= driver_pci_host.o
 | 
			
		||||
 bcma-$(CONFIG_BCMA_DRIVER_MIPS)		+= driver_mips.o
 | 
			
		||||
 endif # MTD_NAND
 | 
			
		||||
--- a/drivers/mtd/nand/Makefile
 | 
			
		||||
+++ b/drivers/mtd/nand/Makefile
 | 
			
		||||
@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mp
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 | 
			
		||||
+obj-$(CONFIG_MTD_NAND_BCM47XX)		+= bcm47xx_nand.o
 | 
			
		||||
 
 | 
			
		||||
 nand-objs := nand_base.o nand_bbt.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/mtd/nand/bcm47xx_nand.c
 | 
			
		||||
@@ -0,0 +1,506 @@
 | 
			
		||||
@ -590,7 +632,7 @@
 | 
			
		||||
+				goto done;
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+	
 | 
			
		||||
+
 | 
			
		||||
+		/* Copy input data into holding block */
 | 
			
		||||
+		copy_len = min(len, blocksize - (offset & mask));
 | 
			
		||||
+		memcpy(block + (offset & mask), ptr, copy_len);
 | 
			
		||||
@ -639,7 +681,7 @@
 | 
			
		||||
+		pr_err("ERASE: nflash_mtd_poll error\n");
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	}
 | 
			
		||||
+	
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
@ -704,14 +746,14 @@
 | 
			
		||||
+		nflash->next_opcode = 0;
 | 
			
		||||
+		bcm47xx_erase(mtd, page_addr*pagesize, pagesize);
 | 
			
		||||
+		break;
 | 
			
		||||
+	
 | 
			
		||||
+
 | 
			
		||||
+	case NAND_CMD_ERASE2:
 | 
			
		||||
+		break;
 | 
			
		||||
+
 | 
			
		||||
+	case NAND_CMD_RNDOUT:
 | 
			
		||||
+		if (column > mtd->writesize)
 | 
			
		||||
+			read_offset += (column - mtd->writesize);
 | 
			
		||||
+		else 
 | 
			
		||||
+		else
 | 
			
		||||
+			read_offset += column;
 | 
			
		||||
+		break;
 | 
			
		||||
+
 | 
			
		||||
@ -740,7 +782,7 @@
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	if (nflash->next_opcode == NAND_CMD_STATUS)
 | 
			
		||||
+		return NAND_STATUS_WP; 
 | 
			
		||||
+		return NAND_STATUS_WP;
 | 
			
		||||
+
 | 
			
		||||
+	id = bcma_cc_read32(nflash->bcc, nflash->next_opcode);
 | 
			
		||||
+
 | 
			
		||||
@ -879,7 +921,7 @@
 | 
			
		||||
+		pr_err("mtd_device_register failed\n");
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+	
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+
 | 
			
		||||
+done:
 | 
			
		||||
@ -926,30 +968,6 @@
 | 
			
		||||
+
 | 
			
		||||
+MODULE_LICENSE("GPL");
 | 
			
		||||
+MODULE_DESCRIPTION("BCM47XX NAND flash driver");
 | 
			
		||||
--- a/drivers/mtd/nand/Kconfig
 | 
			
		||||
+++ b/drivers/mtd/nand/Kconfig
 | 
			
		||||
@@ -537,4 +537,12 @@ config MTD_NAND_FSMC
 | 
			
		||||
 	  Enables support for NAND Flash chips on the ST Microelectronics
 | 
			
		||||
 	  Flexible Static Memory Controller (FSMC)
 | 
			
		||||
 
 | 
			
		||||
+config MTD_NAND_BCM47XX
 | 
			
		||||
+	tristate "bcm47xx nand flash support"
 | 
			
		||||
+	default y
 | 
			
		||||
+	depends on BCM47XX
 | 
			
		||||
+	select MTD_PARTITIONS
 | 
			
		||||
+	help
 | 
			
		||||
+	  Support for bcm47xx nand flash
 | 
			
		||||
+
 | 
			
		||||
 endif # MTD_NAND
 | 
			
		||||
--- a/drivers/mtd/nand/Makefile
 | 
			
		||||
+++ b/drivers/mtd/nand/Makefile
 | 
			
		||||
@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mp
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 | 
			
		||||
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 | 
			
		||||
+obj-$(CONFIG_MTD_NAND_BCM47XX)		+= bcm47xx_nand.o
 | 
			
		||||
 
 | 
			
		||||
 nand-objs := nand_base.o nand_bbt.o
 | 
			
		||||
--- a/include/linux/bcma/bcma_driver_chipcommon.h
 | 
			
		||||
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
 | 
			
		||||
@@ -376,6 +376,7 @@ struct bcma_chipcommon_pmu {
 | 
			
		||||
@ -985,8 +1003,8 @@
 | 
			
		||||
 	};
 | 
			
		||||
 
 | 
			
		||||
 	int nr_serial_ports;
 | 
			
		||||
@@ -483,4 +495,13 @@ int bcma_sflash_commit(struct bcma_drv_c
 | 
			
		||||
 			     const u8 *buf);
 | 
			
		||||
@@ -481,4 +493,13 @@ int bcma_sflash_write(struct bcma_drv_cc
 | 
			
		||||
 int bcma_sflash_erase(struct bcma_drv_cc *cc, u32 offset);
 | 
			
		||||
 #endif /* CONFIG_BCMA_SFLASH */
 | 
			
		||||
 
 | 
			
		||||
+#ifdef CONFIG_BCMA_NFLASH
 | 
			
		||||
@ -1008,7 +1026,7 @@
 | 
			
		||||
+ * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com>
 | 
			
		||||
+ * Copyright (C) 2009, Broadcom Corporation
 | 
			
		||||
+ * All Rights Reserved.
 | 
			
		||||
+ * 
 | 
			
		||||
+ *
 | 
			
		||||
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
 | 
			
		||||
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
 | 
			
		||||
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 #include <asm/bootinfo.h>
 | 
			
		||||
 #include <asm/reboot.h>
 | 
			
		||||
 #include <asm/time.h>
 | 
			
		||||
@@ -281,6 +283,31 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
@@ -320,6 +322,31 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@ -56,7 +56,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 static void __init bcm47xx_register_ssb(void)
 | 
			
		||||
 {
 | 
			
		||||
 	int err;
 | 
			
		||||
@@ -313,6 +340,10 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
@@ -352,6 +379,10 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
 			memcpy(&mcore->serial_ports[1], &port, sizeof(port));
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
@ -65,5 +65,5 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
+	bcm47xx_early_serial_setup(mcore);
 | 
			
		||||
+#endif
 | 
			
		||||
 }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 static int __init bcm47xx_register_flash_ssb(void)
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
--- a/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
@@ -243,8 +243,7 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
@@ -258,8 +258,7 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
 		value = eq + 1;
 | 
			
		||||
 		if ((eq - var) == strlen(name) &&
 | 
			
		||||
 			strncmp(var, name, (eq - var)) == 0) {
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@
 | 
			
		||||
 obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -93,156 +93,7 @@ static void bcm47xx_machine_halt(void)
 | 
			
		||||
@@ -132,156 +132,7 @@ static void bcm47xx_machine_halt(void)
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@
 | 
			
		||||
  *  Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com>
 | 
			
		||||
  *
 | 
			
		||||
  *  This program is free software; you can redistribute  it and/or modify it
 | 
			
		||||
@@ -93,7 +93,7 @@ static void bcm47xx_machine_halt(void)
 | 
			
		||||
@@ -132,7 +132,7 @@ static void bcm47xx_machine_halt(void)
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_SSB
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
 {
 | 
			
		||||
 	char prefix[10];
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,7 @@ static int bcm47xx_get_sprom(struct ssb_
 | 
			
		||||
@@ -149,7 +149,7 @@ static int bcm47xx_get_sprom(struct ssb_
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
 | 
			
		||||
@ -27,7 +27,7 @@
 | 
			
		||||
 {
 | 
			
		||||
 	char buf[20];
 | 
			
		||||
 
 | 
			
		||||
@@ -165,7 +165,7 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
@@ -204,7 +204,7 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
 	char buf[100];
 | 
			
		||||
 	struct ssb_mipscore *mcore;
 | 
			
		||||
 
 | 
			
		||||
@ -36,7 +36,7 @@
 | 
			
		||||
 	if (err)
 | 
			
		||||
 		printk(KERN_WARNING "bcm47xx: someone else already registered"
 | 
			
		||||
 			" a ssb SPROM callback handler (err %d)\n", err);
 | 
			
		||||
@@ -199,10 +199,41 @@ static void __init bcm47xx_register_ssb(
 | 
			
		||||
@@ -256,10 +256,41 @@ static int __init bcm47xx_register_flash
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_BCM47XX_BCMA
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -98,6 +98,7 @@ static int bcm47xx_get_sprom_ssb(struct
 | 
			
		||||
@@ -137,6 +137,7 @@ static int bcm47xx_get_sprom_ssb(struct
 | 
			
		||||
 	char prefix[10];
 | 
			
		||||
 
 | 
			
		||||
 	if (bus->bustype == SSB_BUSTYPE_PCI) {
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 | 
			
		||||
 			 bus->host_pci->bus->number + 1,
 | 
			
		||||
 			 PCI_SLOT(bus->host_pci->devfn));
 | 
			
		||||
@@ -126,6 +127,7 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
@@ -165,6 +166,7 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
 	if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
 | 
			
		||||
 		iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 | 
			
		||||
 
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
 	bcm47xx_fill_sprom(&iv->sprom, NULL);
 | 
			
		||||
 
 | 
			
		||||
 	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 | 
			
		||||
@@ -206,12 +208,14 @@ static int bcm47xx_get_sprom_bcma(struct
 | 
			
		||||
@@ -263,12 +265,14 @@ static int bcm47xx_get_sprom_bcma(struct
 | 
			
		||||
 
 | 
			
		||||
 	switch (bus->hosttype) {
 | 
			
		||||
 	case BCMA_HOSTTYPE_PCI:
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
--- a/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/nvram.c
 | 
			
		||||
@@ -249,3 +249,30 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
@@ -264,3 +264,30 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
 	return NVRAM_ERR_ENVNOTFOUND;
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(nvram_getenv);
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
+EXPORT_SYMBOL(nvram_get);
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -376,3 +376,20 @@ static int __init bcm47xx_register_flash
 | 
			
		||||
@@ -384,3 +384,20 @@ static int __init bcm47xx_register_flash
 | 
			
		||||
 	return -1;
 | 
			
		||||
 }
 | 
			
		||||
 fs_initcall(bcm47xx_register_flash);
 | 
			
		||||
 | 
			
		||||
@ -254,7 +254,7 @@ out the configuration than the in kernel cfe config reader.
 | 
			
		||||
 
 | 
			
		||||
 /* Probe for NVRAM header */
 | 
			
		||||
 static void early_nvram_init_pflash(void)
 | 
			
		||||
@@ -61,6 +63,25 @@ static void early_nvram_init_pflash(void
 | 
			
		||||
@@ -58,6 +60,25 @@ static void early_nvram_init_pflash(void
 | 
			
		||||
 		break;
 | 
			
		||||
 #endif
 | 
			
		||||
 	}
 | 
			
		||||
@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader.
 | 
			
		||||
 
 | 
			
		||||
 	off = FLASH_MIN;
 | 
			
		||||
 	while (off <= lim) {
 | 
			
		||||
@@ -232,6 +253,12 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
@@ -247,6 +268,12 @@ int nvram_getenv(char *name, char *val,
 | 
			
		||||
 	if (!nvram_buf[0])
 | 
			
		||||
 		early_nvram_init();
 | 
			
		||||
 
 | 
			
		||||
@ -293,7 +293,7 @@ out the configuration than the in kernel cfe config reader.
 | 
			
		||||
 	/* Look for name=value and return value */
 | 
			
		||||
 	var = &nvram_buf[sizeof(struct nvram_header)];
 | 
			
		||||
 	end = nvram_buf + sizeof(nvram_buf) - 2;
 | 
			
		||||
@@ -260,6 +287,9 @@ char *nvram_get(const char *name)
 | 
			
		||||
@@ -275,6 +302,9 @@ char *nvram_get(const char *name)
 | 
			
		||||
 	if (!nvram_buf[0])
 | 
			
		||||
 		early_nvram_init();
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
--- a/arch/mips/bcm47xx/setup.c
 | 
			
		||||
+++ b/arch/mips/bcm47xx/setup.c
 | 
			
		||||
@@ -133,6 +133,10 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
@@ -172,6 +172,10 @@ static int bcm47xx_get_invariants(struct
 | 
			
		||||
 	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 | 
			
		||||
 		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user