atheros: v3.18: remap flash for boardconfig parsing
authorFelix Fietkau <nbd@openwrt.org>
Fri, 13 Mar 2015 03:01:17 +0000 (03:01 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 13 Mar 2015 03:01:17 +0000 (03:01 +0000)
Rework boardconfig handling code to honestly remap flash memory region.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
SVN-Revision: 44725

target/linux/atheros/patches-3.18/100-board.patch
target/linux/atheros/patches-3.18/102-ar5312_gpio.patch
target/linux/atheros/patches-3.18/103-ar2315_gpio.patch
target/linux/atheros/patches-3.18/105-ar2315_pci.patch

index c0e935e5d87ede22ce93a79fd8eb1b8770516abd..7ba815362c8e686ba9c6466092854e128d76a0e1 100644 (file)
@@ -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
 +
 +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:
 +       * 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 */
 +
 +
 +      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;
 +      /* 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;
 +      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)) {
 +              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)
 +#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+
 + *
 +/*
 + * 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
 +#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
 +#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
 +#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
 +};
 +
 +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,
 +};
 +
 +};
 +#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;
 +      __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
 +
 +      iounmap(flashctl_base);
-+
-+      return (char *)KSEG1ADDR(AR5312_FLASH + 0x800000);
 +}
 +
 +void __init ar5312_init_devices(void)
 +      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 */
 +}
 --- /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
 +      {
 +              .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",
 +      .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 = {
 +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();
 +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);
index 3493e8e4344dd781f40041068b61b843c5812810..7056aebe857828d7b1897313f5871eea14468628 100644 (file)
@@ -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);
  
index f0ab11040012e7211a074624875430484fbf733a..32022e6aebf4845c29aab98873cf3a58071af053 100644 (file)
 +      .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);
index 6665a1138b41a87599aa8d76fdf08c29a4e3fc6a..f182cb73500705e6e7180fd1b65f7893d27e503a 100644 (file)
        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;
  }