[OpenWrt-Devel] [PATCH 21/33] atheros: v3.18: remap flash for boardconfig parsing

Sergey Ryazanov ryazanov.s.a at gmail.com
Thu Mar 12 22:19:26 EDT 2015


Rework boardconfig handling code to honestly remap flash memory region.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a at gmail.com>
---
 target/linux/atheros/patches-3.18/100-board.patch  | 137 ++++++++++-----------
 .../atheros/patches-3.18/102-ar5312_gpio.patch     |   2 +-
 .../atheros/patches-3.18/103-ar2315_gpio.patch     |  10 +-
 .../atheros/patches-3.18/105-ar2315_pci.patch      |   2 +-
 4 files changed, 74 insertions(+), 77 deletions(-)

diff --git a/target/linux/atheros/patches-3.18/100-board.patch b/target/linux/atheros/patches-3.18/100-board.patch
index c0e935e..7ba8153 100644
--- a/target/linux/atheros/patches-3.18/100-board.patch
+++ b/target/linux/atheros/patches-3.18/100-board.patch
@@ -77,7 +77,7 @@
 +obj-$(CONFIG_SOC_AR2315) += ar2315.o
 --- /dev/null
 +++ b/arch/mips/ath25/board.c
-@@ -0,0 +1,234 @@
+@@ -0,0 +1,244 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
@@ -112,57 +112,55 @@
 +
 +void (*ath25_irq_dispatch)(void);
 +
-+static inline bool check_radio_magic(u8 *addr)
++static inline bool check_radio_magic(const void __iomem *addr)
 +{
 +	addr += 0x7a; /* offset for flash magic */
-+	return (addr[0] == 0x5a) && (addr[1] == 0xa5);
++	return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5);
 +}
 +
-+static inline bool check_notempty(u8 *addr)
++static inline bool check_notempty(const void __iomem *addr)
 +{
-+	return *(u32 *)addr != 0xffffffff;
++	return __raw_readl(addr) != 0xffffffff;
 +}
 +
-+static inline bool check_board_data(u8 *flash_limit, u8 *addr, bool broken)
++static inline bool check_board_data(const void __iomem *addr, bool broken)
 +{
 +	/* config magic found */
-+	if (*((u32 *)addr) == ATH25_BD_MAGIC)
++	if (__raw_readl(addr) == ATH25_BD_MAGIC)
 +		return true;
 +
 +	if (!broken)
 +		return false;
 +
++	/* broken board data detected, use radio data to find the
++	 * offset, user will fix this */
++
++	if (check_radio_magic(addr + 0x1000))
++		return true;
 +	if (check_radio_magic(addr + 0xf8))
-+		ath25_board.radio = addr + 0xf8;
-+	if ((addr < flash_limit + 0x10000) &&
-+	    check_radio_magic(addr + 0x10000))
-+		ath25_board.radio = addr + 0x10000;
-+
-+	if (ath25_board.radio) {
-+		/* broken board data detected, use radio data to find the
-+		 * offset, user will fix this */
 +		return true;
-+	}
 +
 +	return false;
 +}
 +
-+static u8 * __init find_board_config(u8 *flash_limit, bool broken)
++static const void __iomem * __init find_board_config(const void __iomem *limit,
++						     const bool broken)
 +{
-+	u8 *addr;
-+	u8 *begin = flash_limit - 0x1000;
-+	u8 *end = flash_limit - 0x30000;
++	const void __iomem *addr;
++	const void __iomem *begin = limit - 0x1000;
++	const void __iomem *end = limit - 0x30000;
 +
 +	for (addr = begin; addr >= end; addr -= 0x1000)
-+		if (check_board_data(flash_limit, addr, broken))
++		if (check_board_data(addr, broken))
 +			return addr;
 +
 +	return NULL;
 +}
 +
-+static u8 * __init find_radio_config(u8 *flash_limit, u8 *bcfg)
++static const void __iomem * __init find_radio_config(const void __iomem *limit,
++						     const void __iomem *bcfg)
 +{
-+	u8 *rcfg, *begin, *end;
++	const void __iomem *rcfg, *begin, *end;
 +
 +	/*
 +	 * Now find the start of Radio Configuration data, using heuristics:
@@ -170,36 +168,44 @@
 +	 * at a time until we find non-0xffffffff.
 +	 */
 +	begin = bcfg + 0x1000;
-+	end = flash_limit;
++	end = limit;
 +	for (rcfg = begin; rcfg < end; rcfg += 0x1000)
 +		if (check_notempty(rcfg) && check_radio_magic(rcfg))
 +			return rcfg;
 +
 +	/* AR2316 relocates radio config to new location */
 +	begin = bcfg + 0xf8;
-+	end = flash_limit - 0x1000 + 0xf8;
++	end = limit - 0x1000 + 0xf8;
 +	for (rcfg = begin; rcfg < end; rcfg += 0x1000)
 +		if (check_notempty(rcfg) && check_radio_magic(rcfg))
 +			return rcfg;
 +
-+	pr_warn("WARNING: Could not find Radio Configuration data\n");
-+
 +	return NULL;
 +}
 +
-+int __init ath25_find_config(u8 *flash_limit)
++/*
++ * NB: Search region size could be larger than the actual flash size,
++ * but this shouldn't be a problem here, because the flash
++ * will simply be mapped multiple times.
++ */
++int __init ath25_find_config(phys_addr_t base, unsigned long size)
 +{
++	const void __iomem *flash_base, *flash_limit;
 +	struct ath25_boarddata *config;
 +	unsigned int rcfg_size;
 +	int broken_boarddata = 0;
-+	u8 *bcfg, *rcfg;
++	const void __iomem *bcfg, *rcfg;
 +	u8 *board_data;
 +	u8 *radio_data;
 +	u8 *mac_addr;
 +	u32 offset;
 +
++	flash_base = ioremap_nocache(base, size);
++	flash_limit = flash_base + size;
++
 +	ath25_board.config = NULL;
 +	ath25_board.radio = NULL;
++
 +	/* Copy the board and radio data to RAM, because accessing the mapped
 +	 * memory of the flash directly after booting is not safe */
 +
@@ -214,12 +220,12 @@
 +
 +	if (!bcfg) {
 +		pr_warn("WARNING: No board configuration data found!\n");
-+		return -ENODEV;
++		goto error;
 +	}
 +
 +	board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
 +	ath25_board.config = (struct ath25_boarddata *)board_data;
-+	memcpy(board_data, bcfg, 0x100);
++	memcpy_fromio(board_data, bcfg, 0x100);
 +	if (broken_boarddata) {
 +		pr_warn("WARNING: broken board data detected\n");
 +		config = ath25_board.config;
@@ -237,13 +243,11 @@
 +	/* Radio config starts 0x100 bytes after board config, regardless
 +	 * of what the physical layout on the flash chip looks like */
 +
-+	if (ath25_board.radio)
-+		rcfg = (u8 *)ath25_board.radio;
-+	else
-+		rcfg = find_radio_config(flash_limit, bcfg);
-+
-+	if (!rcfg)
-+		return -ENODEV;
++	rcfg = find_radio_config(flash_limit, bcfg);
++	if (!rcfg) {
++		pr_warn("WARNING: Could not find Radio Configuration data\n");
++		goto error;
++	}
 +
 +	radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
 +	ath25_board.radio = radio_data;
@@ -251,7 +255,7 @@
 +	pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg,
 +		offset);
 +	rcfg_size = BOARD_CONFIG_BUFSZ - offset;
-+	memcpy(radio_data, rcfg, rcfg_size);
++	memcpy_fromio(radio_data, rcfg, rcfg_size);
 +
 +	mac_addr = &radio_data[0x1d * 2];
 +	if (is_broadcast_ether_addr(mac_addr)) {
@@ -259,7 +263,13 @@
 +		ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac);
 +	}
 +
++	iounmap(flash_base);
++
 +	return 0;
++
++error:
++	iounmap(flash_base);
++	return -ENODEV;
 +}
 +
 +static void ath25_halt(void)
@@ -629,7 +639,7 @@
 +#endif /* __ASM_MACH_ATH25_WAR_H */
 --- /dev/null
 +++ b/arch/mips/ath25/ar2315_regs.h
-@@ -0,0 +1,480 @@
+@@ -0,0 +1,481 @@
 +/*
 + * Register definitions for AR2315+
 + *
@@ -672,7 +682,8 @@
 +/*
 + * Address map
 + */
-+#define AR2315_SPI_READ         0x08000000      /* SPI FLASH */
++#define AR2315_SPI_READ_BASE	0x08000000	/* SPI flash */
++#define AR2315_SPI_READ_SIZE	0x01000000
 +#define AR2315_WLAN0            0x10000000      /* Wireless MMR */
 +#define AR2315_PCI              0x10100000      /* PCI MMR */
 +#define AR2315_PCI_SIZE		0x00001000
@@ -1112,7 +1123,7 @@
 +#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */
 --- /dev/null
 +++ b/arch/mips/ath25/ar5312_regs.h
-@@ -0,0 +1,227 @@
+@@ -0,0 +1,228 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
@@ -1170,7 +1181,8 @@
 +#define AR5312_GPIO_BASE		0x1c002000
 +#define AR5312_RST_BASE			0x1c003000
 +#define AR5312_RST_SIZE			0x00000100
-+#define AR5312_FLASH            0x1e000000
++#define AR5312_FLASH_BASE		0x1e000000
++#define AR5312_FLASH_SIZE		0x00800000
 +
 +/*
 + * Need these defines to determine true number of ethernet MACs
@@ -1342,7 +1354,7 @@
 +#endif	/* __ASM_MACH_ATH25_AR5312_REGS_H */
 --- /dev/null
 +++ b/arch/mips/ath25/ar5312.c
-@@ -0,0 +1,483 @@
+@@ -0,0 +1,478 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
@@ -1523,8 +1535,8 @@
 +};
 +
 +static struct resource ar5312_flash_resource = {
-+	.start = AR5312_FLASH,
-+	.end = AR5312_FLASH + 0x800000 - 1,
++	.start = AR5312_FLASH_BASE,
++	.end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1,
 +	.flags = IORESOURCE_MEM,
 +};
 +
@@ -1567,12 +1579,7 @@
 +};
 +#endif
 +
-+/*
-+ * NB: This mapping size is larger than the actual flash size,
-+ * but this shouldn't be a problem here, because the flash
-+ * will simply be mapped multiple times.
-+ */
-+static char __init *ar5312_flash_limit(void)
++static void __init ar5312_flash_init(void)
 +{
 +	void __iomem *flashctl_base;
 +	u32 ctl;
@@ -1617,8 +1624,6 @@
 +	__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
 +
 +	iounmap(flashctl_base);
-+
-+	return (char *)KSEG1ADDR(AR5312_FLASH + 0x800000);
 +}
 +
 +void __init ar5312_init_devices(void)
@@ -1626,8 +1631,10 @@
 +	struct ath25_boarddata *config;
 +	u8 *c;
 +
++	ar5312_flash_init();
++
 +	/* Locate board/radio config data */
-+	ath25_find_config(ar5312_flash_limit());
++	ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE);
 +	config = ath25_board.config;
 +
 +	/* AR2313 has CPU minor rev. 10 */
@@ -1828,7 +1835,7 @@
 +}
 --- /dev/null
 +++ b/arch/mips/ath25/ar2315.c
-@@ -0,0 +1,428 @@
+@@ -0,0 +1,418 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
@@ -2018,8 +2025,8 @@
 +	{
 +		.name = "spiflash_read",
 +		.flags = IORESOURCE_MEM,
-+		.start = AR2315_SPI_READ,
-+		.end = AR2315_SPI_READ + 0x1000000 - 1,
++		.start = AR2315_SPI_READ_BASE,
++		.end = AR2315_SPI_READ_BASE + AR2315_SPI_READ_SIZE - 1,
 +	},
 +	{
 +		.name = "spiflash_mmr",
@@ -2056,16 +2063,6 @@
 +	.num_resources = ARRAY_SIZE(ar2315_wdt_res)
 +};
 +
-+/*
-+ * NB: We use mapping size that is larger than the actual flash size,
-+ * but this shouldn't be a problem here, because the flash will simply
-+ * be mapped multiple times.
-+ */
-+static u8 __init *ar2315_flash_limit(void)
-+{
-+	return (u8 *)KSEG1ADDR(ar2315_spiflash_res[0].end + 1);
-+}
-+
 +#ifdef CONFIG_LEDS_GPIO
 +static struct gpio_led ar2315_leds[6];
 +static struct gpio_led_platform_data ar2315_led_data = {
@@ -2113,7 +2110,7 @@
 +void __init ar2315_init_devices(void)
 +{
 +	/* Find board configuration */
-+	ath25_find_config(ar2315_flash_limit());
++	ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
 +	ar2315_eth_data.macaddr = ath25_board.config->enet0_mac;
 +
 +	ar2315_init_gpio_leds();
@@ -2365,7 +2362,7 @@
 +extern struct ar231x_board_config ath25_board;
 +extern void (*ath25_irq_dispatch)(void);
 +
-+int ath25_find_config(u8 *flash_limit);
++int ath25_find_config(phys_addr_t offset, unsigned long size);
 +int ath25_add_ethernet(int nr, u32 base, const char *mii_name, u32 mii_base,
 +		       int irq, void *pdata);
 +void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk);
diff --git a/target/linux/atheros/patches-3.18/102-ar5312_gpio.patch b/target/linux/atheros/patches-3.18/102-ar5312_gpio.patch
index 3493e8e..7056aeb 100644
--- a/target/linux/atheros/patches-3.18/102-ar5312_gpio.patch
+++ b/target/linux/atheros/patches-3.18/102-ar5312_gpio.patch
@@ -33,7 +33,7 @@
  #ifdef CONFIG_LEDS_GPIO
  static struct gpio_led ar5312_leds[] = {
  	{ .name = "wlan", .gpio = 0, .active_low = 1, },
-@@ -299,6 +315,8 @@ void __init ar5312_init_devices(void)
+@@ -294,6 +310,8 @@ void __init ar5312_init_devices(void)
  
  	platform_device_register(&ar5312_physmap_flash);
  
diff --git a/target/linux/atheros/patches-3.18/103-ar2315_gpio.patch b/target/linux/atheros/patches-3.18/103-ar2315_gpio.patch
index f0ab110..32022e6 100644
--- a/target/linux/atheros/patches-3.18/103-ar2315_gpio.patch
+++ b/target/linux/atheros/patches-3.18/103-ar2315_gpio.patch
@@ -40,11 +40,11 @@
 +	.num_resources = ARRAY_SIZE(ar2315_gpio_res)
 +};
 +
- /*
-  * NB: We use mapping size that is larger than the actual flash size,
-  * but this shouldn't be a problem here, because the flash will simply
-@@ -285,6 +313,7 @@ void __init ar2315_init_devices(void)
- 	ath25_find_config(ar2315_flash_limit());
+ #ifdef CONFIG_LEDS_GPIO
+ static struct gpio_led ar2315_leds[6];
+ static struct gpio_led_platform_data ar2315_led_data = {
+@@ -275,6 +303,7 @@ void __init ar2315_init_devices(void)
+ 	ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
  	ar2315_eth_data.macaddr = ath25_board.config->enet0_mac;
  
 +	platform_device_register(&ar2315_gpio);
diff --git a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch
index 6665a11..f182cb7 100644
--- a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch
+++ b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch
@@ -531,7 +531,7 @@
  	else if (pending & CAUSEF_IP2)
  		do_IRQ(AR2315_IRQ_MISC_INTRS);
  	else if (pending & CAUSEF_IP7)
-@@ -450,8 +454,60 @@ void __init ar2315_plat_mem_setup(void)
+@@ -440,8 +444,60 @@ void __init ar2315_plat_mem_setup(void)
  	_machine_restart = ar2315_restart;
  }
  
-- 
2.0.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list