From 9ceee12a49b0c7f1652235f581f19187a01611e3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Mar 2015 03:01:17 +0000 Subject: [PATCH] atheros: v3.18: remap flash for boardconfig parsing Rework boardconfig handling code to honestly remap flash memory region. Signed-off-by: Sergey Ryazanov SVN-Revision: 44725 --- .../atheros/patches-3.18/100-board.patch | 137 +++++++++--------- .../patches-3.18/102-ar5312_gpio.patch | 2 +- .../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 c0e935e5d8..7ba815362c 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; + -+ 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; ++ /* broken board data detected, use radio data to find the ++ * offset, user will fix this */ + -+ if (ath25_board.radio) { -+ /* 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)) + 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 3493e8e434..7056aebe85 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 f0ab110400..32022e6aeb 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 6665a1138b..f182cb7350 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; }