From 9df8689444c36bfb7ec024969d7fbf82b5f7f111 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 27 Sep 2010 14:53:46 +0000 Subject: [PATCH] ar71xx: move ath9k specific PCI fixup into a separate file SVN-Revision: 23131 --- target/linux/ar71xx/config-2.6.32 | 1 + target/linux/ar71xx/config-2.6.33 | 1 + target/linux/ar71xx/config-2.6.34 | 1 + target/linux/ar71xx/config-2.6.35 | 1 + .../ar71xx/files/arch/mips/ar71xx/Kconfig | 5 + .../ar71xx/files/arch/mips/ar71xx/Makefile | 1 + .../files/arch/mips/ar71xx/dev-ap91-pci.c | 73 +---------- .../files/arch/mips/ar71xx/dev-ap94-pci.c | 80 +----------- .../files/arch/mips/ar71xx/pci-ath9k-fixup.c | 123 ++++++++++++++++++ .../files/arch/mips/ar71xx/pci-ath9k-fixup.h | 6 + 10 files changed, 144 insertions(+), 148 deletions(-) create mode 100644 target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c create mode 100644 target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h diff --git a/target/linux/ar71xx/config-2.6.32 b/target/linux/ar71xx/config-2.6.32 index 1c464f8458..f3465f02c9 100644 --- a/target/linux/ar71xx/config-2.6.32 +++ b/target/linux/ar71xx/config-2.6.32 @@ -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 diff --git a/target/linux/ar71xx/config-2.6.33 b/target/linux/ar71xx/config-2.6.33 index ea56d706e9..3be2319d43 100644 --- a/target/linux/ar71xx/config-2.6.33 +++ b/target/linux/ar71xx/config-2.6.33 @@ -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 diff --git a/target/linux/ar71xx/config-2.6.34 b/target/linux/ar71xx/config-2.6.34 index 81ccd6ba67..c13583a0de 100644 --- a/target/linux/ar71xx/config-2.6.34 +++ b/target/linux/ar71xx/config-2.6.34 @@ -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 diff --git a/target/linux/ar71xx/config-2.6.35 b/target/linux/ar71xx/config-2.6.35 index 81ccd6ba67..c13583a0de 100644 --- a/target/linux/ar71xx/config-2.6.35 +++ b/target/linux/ar71xx/config-2.6.35 @@ -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 diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig index 2b4c3bdcf0..2c43900518 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig @@ -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 diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile index 81dab7c711..8548fd9af1 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile @@ -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 diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c index f24d4697c1..2342d7f7ea 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c @@ -16,10 +16,10 @@ #include #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); } diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c index bfa668f74f..2436491b4e 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c @@ -16,12 +16,12 @@ #include #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 index 0000000000..21f5a6816e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c @@ -0,0 +1,123 @@ +/* + * Atheros AP94 reference board PCI initialization + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * 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 +#include + +#include +#include + +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 index 0000000000..5794941f08 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h @@ -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 */ -- 2.30.2