Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.8 130 lines 3.1 kB view raw
1/* 2 * Atheros AR71XX/AR724X specific PCI setup code 3 * 4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> 5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 7 * 8 * Parts of this file are based on Atheros' 2.6.15 BSP 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 as published 12 * by the Free Software Foundation. 13 */ 14 15#include <linux/init.h> 16#include <linux/pci.h> 17#include <asm/mach-ath79/ar71xx_regs.h> 18#include <asm/mach-ath79/ath79.h> 19#include <asm/mach-ath79/irq.h> 20#include <asm/mach-ath79/pci.h> 21#include "pci.h" 22 23static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); 24static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; 25static unsigned ath79_pci_nr_irqs __initdata; 26 27static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { 28 { 29 .slot = 17, 30 .pin = 1, 31 .irq = ATH79_PCI_IRQ(0), 32 }, { 33 .slot = 18, 34 .pin = 1, 35 .irq = ATH79_PCI_IRQ(1), 36 }, { 37 .slot = 19, 38 .pin = 1, 39 .irq = ATH79_PCI_IRQ(2), 40 } 41}; 42 43static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { 44 { 45 .slot = 0, 46 .pin = 1, 47 .irq = ATH79_PCI_IRQ(0), 48 } 49}; 50 51int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) 52{ 53 int irq = -1; 54 int i; 55 56 if (ath79_pci_nr_irqs == 0 || 57 ath79_pci_irq_map == NULL) { 58 if (soc_is_ar71xx()) { 59 ath79_pci_irq_map = ar71xx_pci_irq_map; 60 ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); 61 } else if (soc_is_ar724x() || 62 soc_is_ar9342() || 63 soc_is_ar9344()) { 64 ath79_pci_irq_map = ar724x_pci_irq_map; 65 ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); 66 } else { 67 pr_crit("pci %s: invalid irq map\n", 68 pci_name((struct pci_dev *) dev)); 69 return irq; 70 } 71 } 72 73 for (i = 0; i < ath79_pci_nr_irqs; i++) { 74 const struct ath79_pci_irq *entry; 75 76 entry = &ath79_pci_irq_map[i]; 77 if (entry->slot == slot && entry->pin == pin) { 78 irq = entry->irq; 79 break; 80 } 81 } 82 83 if (irq < 0) 84 pr_crit("pci %s: no irq found for pin %u\n", 85 pci_name((struct pci_dev *) dev), pin); 86 else 87 pr_info("pci %s: using irq %d for pin %u\n", 88 pci_name((struct pci_dev *) dev), irq, pin); 89 90 return irq; 91} 92 93int pcibios_plat_dev_init(struct pci_dev *dev) 94{ 95 if (ath79_pci_plat_dev_init) 96 return ath79_pci_plat_dev_init(dev); 97 98 return 0; 99} 100 101void __init ath79_pci_set_irq_map(unsigned nr_irqs, 102 const struct ath79_pci_irq *map) 103{ 104 ath79_pci_nr_irqs = nr_irqs; 105 ath79_pci_irq_map = map; 106} 107 108void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) 109{ 110 ath79_pci_plat_dev_init = func; 111} 112 113int __init ath79_register_pci(void) 114{ 115 if (soc_is_ar71xx()) 116 return ar71xx_pcibios_init(); 117 118 if (soc_is_ar724x()) 119 return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); 120 121 if (soc_is_ar9342() || soc_is_ar9344()) { 122 u32 bootstrap; 123 124 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 125 if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) 126 return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); 127 } 128 129 return -ENODEV; 130}