aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-4.1/800-bcma-add-table-of-serial-flashes-with-smaller-blocks.patch
blob: 99d909bc037e6462a409b940d617cd5ba0c4bb40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From 597715c61ae75a05ab3310a34ff3857a006f0f63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 20 Nov 2014 21:32:42 +0100
Subject: [PATCH] bcma: add table of serial flashes with smaller blocks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/bcma/driver_chipcommon_sflash.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

--- a/drivers/bcma/driver_chipcommon_sflash.c
+++ b/drivers/bcma/driver_chipcommon_sflash.c
@@ -9,6 +9,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/bcma/bcma.h>
+#include <bcm47xx_board.h>
 
 static struct resource bcma_sflash_resource = {
 	.name	= "bcma_sflash",
@@ -41,6 +42,13 @@ static const struct bcma_sflash_tbl_e bc
 	{ NULL },
 };
 
+/* Some devices use smaller blocks (and have more of them) */
+static const struct bcma_sflash_tbl_e bcma_sflash_st_shrink_tbl[] = {
+	{ "M25P16", 0x14, 0x1000, 512, },
+	{ "M25P32", 0x15, 0x1000, 1024, },
+	{ NULL },
+};
+
 static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
 	{ "SST25WF512", 1, 0x1000, 16, },
 	{ "SST25VF512", 0x48, 0x1000, 16, },
@@ -84,6 +92,24 @@ static void bcma_sflash_cmd(struct bcma_
 	bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n");
 }
 
+const struct bcma_sflash_tbl_e *bcma_sflash_shrink_flash(u32 id)
+{
+	enum bcm47xx_board board = bcm47xx_board_get();
+	const struct bcma_sflash_tbl_e *e;
+
+	switch (board) {
+	case BCM47XX_BOARD_NETGEAR_WGR614_V10:
+	case BCM47XX_BOARD_NETGEAR_WNR1000_V3:
+		for (e = bcma_sflash_st_shrink_tbl; e->name; e++) {
+			if (e->id == id)
+				return e;
+		}
+		return NULL;
+	default:
+		return NULL;
+	}
+}
+
 /* Initialize serial flash access */
 int bcma_sflash_init(struct bcma_drv_cc *cc)
 {
@@ -114,6 +140,10 @@ int bcma_sflash_init(struct bcma_drv_cc
 		case 0x13:
 			return -ENOTSUPP;
 		default:
+			e = bcma_sflash_shrink_flash(id);
+			if (e)
+				break;
+
 			for (e = bcma_sflash_st_tbl; e->name; e++) {
 				if (e->id == id)
 					break;
or: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
From d8582dcf1ed66eee88a11e4760f42c0d6c8822be Mon Sep 17 00:00:00 2001
From: Yousong Zhou <yszhou4tech@gmail.com>
Date: Sat, 31 Jan 2015 22:26:03 +0800
Subject: [PATCH 331/331] MIPS: kexec: Accept command line parameters from
 userspace.

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
---
 arch/mips/kernel/machine_kexec.c   |  153 +++++++++++++++++++++++++++++++-----
 arch/mips/kernel/machine_kexec.h   |   20 +++++
 arch/mips/kernel/relocate_kernel.S |   21 +++--
 3 files changed, 167 insertions(+), 27 deletions(-)
 create mode 100644 arch/mips/kernel/machine_kexec.h

--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -10,45 +10,145 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 
+#include <asm/bootinfo.h>
 #include <asm/cacheflush.h>
 #include <asm/page.h>
-
-extern const unsigned char relocate_new_kernel[];
-extern const size_t relocate_new_kernel_size;
-
-extern unsigned long kexec_start_address;
-extern unsigned long kexec_indirection_page;
+#include <asm/uaccess.h>
+#include "machine_kexec.h"
 
 int (*_machine_kexec_prepare)(struct kimage *) = NULL;
 void (*_machine_kexec_shutdown)(void) = NULL;
 void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
+
 #ifdef CONFIG_SMP
 void (*relocated_kexec_smp_wait) (void *);
 atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
 #endif
 
-int
-machine_kexec_prepare(struct kimage *kimage)
+static void machine_kexec_print_args(void)
 {
+	unsigned long argc = (int)kexec_args[0];
+	int i;
+
+	pr_info("kexec_args[0] (argc): %lu\n", argc);
+	pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
+	pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
+	pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
+
+	for (i = 0; i < argc; i++) {
+		pr_info("kexec_argv[%d] = %p, %s\n",
+				i, kexec_argv[i], kexec_argv[i]);
+	}
+}
+
+static void machine_kexec_init_argv(struct kimage *image)
+{
+	void __user *buf = NULL;
+	size_t bufsz;
+	size_t size;
+	int i;
+
+	bufsz = 0;
+	for (i = 0; i < image->nr_segments; i++) {
+		struct kexec_segment *seg;
+
+		seg = &image->segment[i];
+		if (seg->bufsz < 6)
+			continue;
+
+		if (strncmp((char *) seg->buf, "kexec ", 6))
+			continue;
+
+		buf = seg->buf;
+		bufsz = seg->bufsz;
+		break;
+	}
+
+	if (!buf)
+		return;
+
+	size = KEXEC_COMMAND_LINE_SIZE;
+	size = min(size, bufsz);
+	if (size < bufsz)
+		pr_warn("kexec command line truncated to %zd bytes\n", size);
+
+	/* Copy to kernel space */
+	copy_from_user(kexec_argv_buf, buf, size);
+	kexec_argv_buf[size - 1] = 0;
+}
+
+static void machine_kexec_parse_argv(struct kimage *image)
+{
+	char *reboot_code_buffer;
+	int reloc_delta;
+	char *ptr;
+	int argc;
+	int i;
+
+	ptr = kexec_argv_buf;
+	argc = 0;
+
+	/*
+	 * convert command line string to array of parameters
+	 * (as bootloader does).
+	 */
+	while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) {
+		if (*ptr == ' ') {
+			*ptr++ = '\0';
+			continue;
+		}
+
+		kexec_argv[argc++] = ptr;
+		ptr = strchr(ptr, ' ');
+	}
+
+	if (!argc)
+		return;
+
+	kexec_args[0] = argc;
+	kexec_args[1] = (unsigned long)kexec_argv;
+	kexec_args[2] = 0;
+	kexec_args[3] = 0;
+
+	reboot_code_buffer = page_address(image->control_code_page);
+	reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel;
+
+	kexec_args[1] += reloc_delta;
+	for (i = 0; i < argc; i++)
+		kexec_argv[i] += reloc_delta;
+}
+
+int machine_kexec_prepare(struct kimage *kimage)
+{
+	/*
+	 * Whenever arguments passed from kexec-tools, Init the arguments as
+	 * the original ones to try avoiding booting failure.
+	 */
+
+	kexec_args[0] = fw_arg0;
+	kexec_args[1] = fw_arg1;
+	kexec_args[2] = fw_arg2;
+	kexec_args[3] = fw_arg3;
+
+	machine_kexec_init_argv(kimage);
+	machine_kexec_parse_argv(kimage);
+
 	if (_machine_kexec_prepare)
 		return _machine_kexec_prepare(kimage);
 	return 0;
 }
 
-void
-machine_kexec_cleanup(struct kimage *kimage)
+void machine_kexec_cleanup(struct kimage *kimage)
 {
 }
 
-void
-machine_shutdown(void)
+void machine_shutdown(void)
 {
 	if (_machine_kexec_shutdown)
 		_machine_kexec_shutdown();
 }
 
-void
-machine_crash_shutdown(struct pt_regs *regs)
+void machine_crash_shutdown(struct pt_regs *regs)
 {
 	if (_machine_crash_shutdown)
 		_machine_crash_shutdown(regs);
@@ -66,10 +166,12 @@ machine_kexec(struct kimage *image)
 	unsigned long *ptr;
 
 	reboot_code_buffer =
-	  (unsigned long)page_address(image->control_code_page);
+		(unsigned long)page_address(image->control_code_page);
+	pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
 
 	kexec_start_address =
 		(unsigned long) phys_to_virt(image->start);
+	pr_info("kexec_start_address = %p\n", (void *)kexec_start_address);
 
 	if (image->type == KEXEC_TYPE_DEFAULT) {
 		kexec_indirection_page =
@@ -77,9 +179,19 @@ machine_kexec(struct kimage *image)
 	} else {
 		kexec_indirection_page = (unsigned long)&image->head;
 	}
+	pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page);
 
-	memcpy((void*)reboot_code_buffer, relocate_new_kernel,
-	       relocate_new_kernel_size);
+	pr_info("Where is memcpy: %p\n", memcpy);
+	pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n",
+		(void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end);
+	pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE,
+		(void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer);
+	memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel,
+	       KEXEC_RELOCATE_NEW_KERNEL_SIZE);
+
+	pr_info("Before _print_args().\n");
+	machine_kexec_print_args();
+	pr_info("Before eval loop.\n");
 
 	/*
 	 * The generic kexec code builds a page list with physical
@@ -98,15 +210,16 @@ machine_kexec(struct kimage *image)
 	/*
 	 * we do not want to be bothered.
 	 */
+	pr_info("Before irq_disable.\n");
 	local_irq_disable();
 
-	printk("Will call new kernel at %08lx\n", image->start);
-	printk("Bye ...\n");
+	pr_info("Will call new kernel at %08lx\n", image->start);
+	pr_info("Bye ...\n");
 	__flush_cache_all();
 #ifdef CONFIG_SMP
 	/* All secondary cpus now may jump to kexec_wait cycle */
 	relocated_kexec_smp_wait = reboot_code_buffer +
-		(void *)(kexec_smp_wait - relocate_new_kernel);
+		(void *)(kexec_smp_wait - kexec_relocate_new_kernel);
 	smp_wmb();
 	atomic_set(&kexec_ready_to_reboot, 1);
 #endif
--- /dev/null
+++ b/arch/mips/kernel/machine_kexec.h
@@ -0,0 +1,20 @@
+#ifndef _MACHINE_KEXEC_H
+#define _MACHINE_KEXEC_H
+
+#ifndef __ASSEMBLY__
+extern const unsigned char kexec_relocate_new_kernel[];
+extern unsigned long kexec_relocate_new_kernel_end;
+extern unsigned long kexec_start_address;
+extern unsigned long kexec_indirection_page;
+
+extern char kexec_argv_buf[];
+extern char *kexec_argv[];
+
+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE	((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel)
+#endif /* !__ASSEMBLY__ */
+
+#define KEXEC_COMMAND_LINE_SIZE		256
+#define KEXEC_ARGV_SIZE			(KEXEC_COMMAND_LINE_SIZE / 16)
+#define KEXEC_MAX_ARGC			(KEXEC_ARGV_SIZE / sizeof(long))
+
+#endif
--- a/arch/mips/kernel/relocate_kernel.S
+++ b/arch/mips/kernel/relocate_kernel.S
@@ -12,8 +12,9 @@
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
 #include <asm/addrspace.h>
+#include "machine_kexec.h"
 
-LEAF(relocate_new_kernel)
+LEAF(kexec_relocate_new_kernel)
 	PTR_L a0,	arg0
 	PTR_L a1,	arg1
 	PTR_L a2,	arg2
@@ -98,7 +99,7 @@ done:
 #endif
 	/* jump to kexec_start_address */
 	j		s1
-	END(relocate_new_kernel)
+	END(kexec_relocate_new_kernel)
 
 #ifdef CONFIG_SMP
 /*
@@ -184,9 +185,15 @@ kexec_indirection_page:
 	PTR		0
 	.size		kexec_indirection_page, PTRSIZE
 
-relocate_new_kernel_end:
+kexec_argv_buf:
+	EXPORT(kexec_argv_buf)
+	.skip		KEXEC_COMMAND_LINE_SIZE
+	.size		kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE
+
+kexec_argv:
+	EXPORT(kexec_argv)
+	.skip		KEXEC_ARGV_SIZE
+	.size		kexec_argv, KEXEC_ARGV_SIZE
 
-relocate_new_kernel_size:
-	EXPORT(relocate_new_kernel_size)
-	PTR		relocate_new_kernel_end - relocate_new_kernel
-	.size		relocate_new_kernel_size, PTRSIZE
+kexec_relocate_new_kernel_end:
+	EXPORT(kexec_relocate_new_kernel_end)