ar71xx: move ath9k specific PCI fixup into a separate file
authorGabor Juhos <juhosg@openwrt.org>
Mon, 27 Sep 2010 14:53:46 +0000 (14:53 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Mon, 27 Sep 2010 14:53:46 +0000 (14:53 +0000)
SVN-Revision: 23131

target/linux/ar71xx/config-2.6.32
target/linux/ar71xx/config-2.6.33
target/linux/ar71xx/config-2.6.34
target/linux/ar71xx/config-2.6.35
target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig
target/linux/ar71xx/files/arch/mips/ar71xx/Makefile
target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c
target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c
target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c [new file with mode: 0644]
target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h [new file with mode: 0644]

index 1c464f8..f3465f0 100644 (file)
@@ -48,6 +48,7 @@ CONFIG_AR71XX_MACH_WRT400N=y
 CONFIG_AR71XX_MACH_WZR_HP_G300NH=y
 CONFIG_AR71XX_MACH_ZCN_1523H=y
 CONFIG_AR71XX_NVRAM=y
+CONFIG_AR71XX_PCI_ATH9K_FIXUP=y
 CONFIG_AR71XX_WDT=y
 CONFIG_AR8216_PHY=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
index ea56d70..3be2319 100644 (file)
@@ -47,6 +47,7 @@ CONFIG_AR71XX_MACH_WRT160NL=y
 CONFIG_AR71XX_MACH_WRT400N=y
 CONFIG_AR71XX_MACH_WZR_HP_G300NH=y
 CONFIG_AR71XX_MACH_ZCN_1523H=y
+CONFIG_AR71XX_PCI_ATH9K_FIXUP=y
 CONFIG_AR71XX_NVRAM=y
 CONFIG_AR71XX_WDT=y
 CONFIG_AR8216_PHY=y
index 81ccd6b..c13583a 100644 (file)
@@ -48,6 +48,7 @@ CONFIG_AR71XX_MACH_WRT400N=y
 CONFIG_AR71XX_MACH_WZR_HP_G300NH=y
 CONFIG_AR71XX_MACH_ZCN_1523H=y
 CONFIG_AR71XX_NVRAM=y
+CONFIG_AR71XX_PCI_ATH9K_FIXUP=y
 CONFIG_AR71XX_WDT=y
 CONFIG_AR8216_PHY=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
index 81ccd6b..c13583a 100644 (file)
@@ -48,6 +48,7 @@ CONFIG_AR71XX_MACH_WRT400N=y
 CONFIG_AR71XX_MACH_WZR_HP_G300NH=y
 CONFIG_AR71XX_MACH_ZCN_1523H=y
 CONFIG_AR71XX_NVRAM=y
+CONFIG_AR71XX_PCI_ATH9K_FIXUP=y
 CONFIG_AR71XX_WDT=y
 CONFIG_AR8216_PHY=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
index 2b4c3bd..2c43900 100644 (file)
@@ -261,6 +261,7 @@ config AR71XX_DEV_M25P80
        def_bool n
 
 config AR71XX_DEV_AP91_PCI
+       select AR71XX_PCI_ATH9K_FIXUP
        def_bool n
 
 config AR71XX_DEV_AP91_ETH
@@ -268,6 +269,7 @@ config AR71XX_DEV_AP91_ETH
        def_bool n
 
 config AR71XX_DEV_AP94_PCI
+       select AR71XX_PCI_ATH9K_FIXUP
        def_bool n
 
 config AR71XX_DEV_AR913X_WMAC
@@ -294,4 +296,7 @@ config AR71XX_DEV_USB
 config AR71XX_NVRAM
        def_bool n
 
+config AR71XX_PCI_ATH9K_FIXUP
+       def_bool n
+
 endif
index 81dab7c..8548fd9 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_AR71XX_DEV_PB9X_PCI)     += dev-pb9x-pci.o
 obj-$(CONFIG_AR71XX_DEV_USB)           += dev-usb.o
 
 obj-$(CONFIG_AR71XX_NVRAM)             += nvram.o
+obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP)   += pci-ath9k-fixup.o
 
 obj-$(CONFIG_AR71XX_MACH_AP81)         += mach-ap81.o
 obj-$(CONFIG_AR71XX_MACH_AP83)         += mach-ap83.o
index f24d469..2342d7f 100644 (file)
 #include <asm/mach-ar71xx/pci.h>
 
 #include "dev-ap91-pci.h"
+#include "pci-ath9k-fixup.h"
 
 static struct ath9k_platform_data ap91_wmac_data;
 static char ap91_wmac_mac[6];
-static int ap91_pci_fixup_enabled;
 
 static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
        {
@@ -40,75 +40,6 @@ static int ap91_pci_plat_dev_init(struct pci_dev *dev)
        return 0;
 }
 
-static void ap91_pci_fixup(struct pci_dev *dev)
-{
-       void __iomem *mem;
-       u16 *cal_data;
-       u16 cmd;
-       u32 val;
-
-       if (!ap91_pci_fixup_enabled)
-               return;
-
-       printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
-
-       cal_data = ap91_wmac_data.eeprom_data;
-       if (*cal_data != 0xa55a) {
-               printk(KERN_ERR "PCI: no calibration data found for %s\n",
-                      pci_name(dev));
-               return;
-       }
-
-       mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
-       if (!mem) {
-               printk(KERN_ERR "PCI: ioremap error for device %s\n",
-                      pci_name(dev));
-               return;
-       }
-
-       /* Setup the PCI device to allow access to the internal registers */
-       switch (ar71xx_soc) {
-       case AR71XX_SOC_AR7240:
-               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
-               break;
-
-       case AR71XX_SOC_AR7241:
-       case AR71XX_SOC_AR7242:
-               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff);
-               break;
-
-       default:
-               BUG();
-       }
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-       pci_write_config_word(dev, PCI_COMMAND, cmd);
-
-        /* set pointer to first reg address */
-       cal_data += 3;
-       while (*cal_data != 0xffff) {
-               u32 reg;
-               reg = *cal_data++;
-               val = *cal_data++;
-               val |= (*cal_data++) << 16;
-
-               __raw_writel(val, mem + reg);
-               udelay(100);
-       }
-
-       pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
-       dev->vendor = val & 0xffff;
-       dev->device = (val >> 16) & 0xffff;
-
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
-       dev->revision = val & 0xff;
-       dev->class = val >> 8; /* upper 3 bytes */
-
-       iounmap(mem);
-}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup);
-
 void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
 {
        if (cal_data)
@@ -123,5 +54,5 @@ void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
        ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
        ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
 
-       ap91_pci_fixup_enabled = 1;
+       pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data);
 }
index bfa668f..2436491 100644 (file)
 #include <asm/mach-ar71xx/pci.h>
 
 #include "dev-ap94-pci.h"
+#include "pci-ath9k-fixup.h"
 
 static struct ath9k_platform_data ap94_wmac0_data;
 static struct ath9k_platform_data ap94_wmac1_data;
 static char ap94_wmac0_mac[6];
 static char ap94_wmac1_mac[6];
-static int ap94_pci_fixup_enabled;
 
 static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
         {
@@ -50,81 +50,6 @@ static int ap94_pci_plat_dev_init(struct pci_dev *dev)
        return 0;
 }
 
-static void ap94_pci_fixup(struct pci_dev *dev)
-{
-       void __iomem *mem;
-       u16 *cal_data;
-       u16 cmd;
-       u32 bar0;
-       u32 val;
-
-       if (!ap94_pci_fixup_enabled)
-               return;
-
-       switch (PCI_SLOT(dev->devfn)) {
-       case 17:
-               cal_data = ap94_wmac0_data.eeprom_data;
-               break;
-       case 18:
-               cal_data = ap94_wmac1_data.eeprom_data;
-               break;
-       default:
-               return;
-       }
-
-       if (*cal_data != 0xa55a) {
-               printk(KERN_ERR "PCI: no calibration data found for %s\n",
-                      pci_name(dev));
-               return;
-       }
-
-       mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
-       if (!mem) {
-               printk(KERN_ERR "PCI: ioremap error for device %s\n",
-                      pci_name(dev));
-               return;
-       }
-
-       printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
-
-       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
-
-       /* Setup the PCI device to allow access to the internal registers */
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE);
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-       pci_write_config_word(dev, PCI_COMMAND, cmd);
-
-       /* set pointer to first reg address */
-       cal_data += 3;
-       while (*cal_data != 0xffff) {
-               u32 reg;
-               reg = *cal_data++;
-               val = *cal_data++;
-               val |= (*cal_data++) << 16;
-
-               __raw_writel(val, mem + reg);
-               udelay(100);
-       }
-
-       pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
-       dev->vendor = val & 0xffff;
-       dev->device = (val >> 16) & 0xffff;
-
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
-       dev->revision = val & 0xff;
-       dev->class = val >> 8; /* upper 3 bytes */
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-       pci_write_config_word(dev, PCI_COMMAND, cmd);
-
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
-
-       iounmap(mem);
-}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup);
-
 void __init ap94_pci_enable_quirk_wndr3700(void)
 {
        ap94_wmac0_data.quirk_wndr3700 = 1;
@@ -155,5 +80,6 @@ void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
        ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
        ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
 
-       ap94_pci_fixup_enabled = 1;
+       pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data);
+       pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data);
 }
diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c
new file mode 100644 (file)
index 0000000..21f5a68
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Atheros AP94 reference board PCI initialization
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+struct ath9k_fixup {
+       u16             *cal_data;
+       unsigned        slot;
+};
+
+static int ath9k_num_fixups;
+static struct ath9k_fixup ath9k_fixups[2];
+
+static void ath9k_pci_fixup(struct pci_dev *dev)
+{
+       void __iomem *mem;
+       u16 *cal_data = NULL;
+       u16 cmd;
+       u32 bar0;
+       u32 val;
+       unsigned i;
+
+       for (i = 0; i < ath9k_num_fixups; i++) {
+               if (ath9k_fixups[i].cal_data == NULL)
+                       continue;
+
+               if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn))
+                       continue;
+
+               cal_data = ath9k_fixups[i].cal_data;
+               break;
+       }
+
+       if (cal_data == NULL)
+               return;
+
+       if (*cal_data != 0xa55a) {
+               pr_err("pci %s: invalid calibration data\n", pci_name(dev));
+               return;
+       }
+
+       pr_info("pci %s: fixup device configuration\n", pci_name(dev));
+
+       mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
+       if (!mem) {
+               pr_err("pci %s: ioremap error\n", pci_name(dev));
+               return;
+       }
+
+       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
+
+       switch (ar71xx_soc) {
+       case AR71XX_SOC_AR7161:
+               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+                                      AR71XX_PCI_MEM_BASE);
+               break;
+       case AR71XX_SOC_AR7240:
+               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
+               break;
+
+       case AR71XX_SOC_AR7241:
+       case AR71XX_SOC_AR7242:
+               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff);
+               break;
+
+       default:
+               BUG();
+       }
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+       /* set pointer to first reg address */
+       cal_data += 3;
+       while (*cal_data != 0xffff) {
+               u32 reg;
+               reg = *cal_data++;
+               val = *cal_data++;
+               val |= (*cal_data++) << 16;
+
+               __raw_writel(val, mem + reg);
+               udelay(100);
+       }
+
+       pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
+       dev->vendor = val & 0xffff;
+       dev->device = (val >> 16) & 0xffff;
+
+       pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
+       dev->revision = val & 0xff;
+       dev->class = val >> 8; /* upper 3 bytes */
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+       pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
+
+       iounmap(mem);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
+
+void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data)
+{
+       if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
+               return;
+
+       ath9k_fixups[ath9k_num_fixups].slot = slot;
+       ath9k_fixups[ath9k_num_fixups].cal_data = cal_data;
+       ath9k_num_fixups++;
+}
diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h
new file mode 100644 (file)
index 0000000..5794941
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _PCI_ATH9K_FIXUP
+#define _PCI_ATH9K_FIXUP
+
+void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init;
+
+#endif /* _PCI_ATH9K_FIXUP */