aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci')
-rw-r--r--arch/mips/pci/Makefile2
-rw-r--r--arch/mips/pci/pci-bcm47xx.c60
-rw-r--r--arch/mips/pci/pci-ip27.c40
-rw-r--r--arch/mips/pci/pci-tx4938.c2
-rw-r--r--arch/mips/pci/pci-tx4939.c109
5 files changed, 203 insertions, 10 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 15e01aec37fd..b1886244cedf 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o
15obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o 15obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
16obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o 16obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
17obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o 17obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
18obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
18 19
19# 20#
20# These are still pretty much in the old state, watch, go blind. 21# These are still pretty much in the old state, watch, go blind.
@@ -44,6 +45,7 @@ obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
44obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o 45obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o
45obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o 46obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o
46obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o 47obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o
48obj-$(CONFIG_SOC_TX4939) += pci-tx4939.o
47obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o 49obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o
48obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o 50obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o
49obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o 51obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
new file mode 100644
index 000000000000..bea9b6cdfdbf
--- /dev/null
+++ b/arch/mips/pci/pci-bcm47xx.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2008 Aurelien Jarno <aurelien@aurel32.net>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
10 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
12 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
15 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
16 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
18 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/ssb/ssb.h>
28
29int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
30{
31 return 0;
32}
33
34int pcibios_plat_dev_init(struct pci_dev *dev)
35{
36 int res;
37 u8 slot, pin;
38
39 res = ssb_pcibios_plat_dev_init(dev);
40 if (res < 0) {
41 printk(KERN_ALERT "PCI: Failed to init device %s\n",
42 pci_name(dev));
43 return res;
44 }
45
46 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
47 slot = PCI_SLOT(dev->devfn);
48 res = ssb_pcibios_map_irq(dev, slot, pin);
49
50 /* IRQ-0 and IRQ-1 are software interrupts. */
51 if (res < 2) {
52 printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
53 pci_name(dev));
54 return res;
55 }
56
57 dev->irq = res;
58 return 0;
59}
60
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index bd78368c82bf..f97ab1461012 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -143,25 +143,47 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
143 */ 143 */
144int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 144int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
145{ 145{
146 return 0;
147}
148
149/* Most MIPS systems have straight-forward swizzling needs. */
150static inline u8 bridge_swizzle(u8 pin, u8 slot)
151{
152 return (((pin - 1) + slot) % 4) + 1;
153}
154
155static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
156{
157 while (dev->bus->parent) {
158 /* Move up the chain of bridges. */
159 dev = dev->bus->self;
160 }
161
162 return dev;
163}
164
165/* Do platform specific device initialization at pci_enable_device() time */
166int pcibios_plat_dev_init(struct pci_dev *dev)
167{
146 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); 168 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
147 int irq = bc->pci_int[slot]; 169 struct pci_dev *rdev = bridge_root_dev(dev);
170 int slot = PCI_SLOT(rdev->devfn);
171 int irq;
148 172
173 irq = bc->pci_int[slot];
149 if (irq == -1) { 174 if (irq == -1) {
150 irq = bc->pci_int[slot] = request_bridge_irq(bc); 175 irq = request_bridge_irq(bc);
151 if (irq < 0) 176 if (irq < 0)
152 panic("Can't allocate interrupt for PCI device %s\n", 177 return irq;
153 pci_name(dev)); 178
179 bc->pci_int[slot] = irq;
154 } 180 }
155 181
156 irq_to_bridge[irq] = bc; 182 irq_to_bridge[irq] = bc;
157 irq_to_slot[irq] = slot; 183 irq_to_slot[irq] = slot;
158 184
159 return irq; 185 dev->irq = irq;
160}
161 186
162/* Do platform specific device initialization at pci_enable_device() time */
163int pcibios_plat_dev_init(struct pci_dev *dev)
164{
165 return 0; 187 return 0;
166} 188}
167 189
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c
index 60e2c52c2c5e..1ea257bc3b8f 100644
--- a/arch/mips/pci/pci-tx4938.c
+++ b/arch/mips/pci/pci-tx4938.c
@@ -114,7 +114,7 @@ int __init tx4938_pciclk66_setup(void)
114 return pciclk; 114 return pciclk;
115} 115}
116 116
117int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) 117int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
118{ 118{
119 if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { 119 if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) {
120 switch (slot) { 120 switch (slot) {
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c
new file mode 100644
index 000000000000..5fecf1cdc325
--- /dev/null
+++ b/arch/mips/pci/pci-tx4939.c
@@ -0,0 +1,109 @@
1/*
2 * linux/arch/mips/pci/pci-tx4939.c
3 *
4 * Based on linux/arch/mips/txx9/rbtx4939/setup.c,
5 * and RBTX49xx patch from CELF patch archive.
6 *
7 * Copyright 2001, 2003-2005 MontaVista Software Inc.
8 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
9 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <linux/kernel.h>
18#include <linux/interrupt.h>
19#include <asm/txx9/generic.h>
20#include <asm/txx9/tx4939.h>
21
22int __init tx4939_report_pciclk(void)
23{
24 int pciclk = 0;
25
26 pr_info("PCIC --%s PCICLK:",
27 (__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66) ?
28 " PCI66" : "");
29 if (__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_PCICLKEN_ALL) {
30 pciclk = txx9_master_clock * 20 / 6;
31 if (!(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66))
32 pciclk /= 2;
33 printk(KERN_CONT "Internal(%u.%uMHz)",
34 (pciclk + 50000) / 1000000,
35 ((pciclk + 50000) / 100000) % 10);
36 } else {
37 printk(KERN_CONT "External");
38 pciclk = -1;
39 }
40 printk(KERN_CONT "\n");
41 return pciclk;
42}
43
44void __init tx4939_report_pci1clk(void)
45{
46 unsigned int pciclk = txx9_master_clock * 20 / 6;
47
48 pr_info("PCIC1 -- PCICLK:%u.%uMHz\n",
49 (pciclk + 50000) / 1000000,
50 ((pciclk + 50000) / 100000) % 10);
51}
52
53int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
54{
55 if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) {
56 switch (slot) {
57 case TX4927_PCIC_IDSEL_AD_TO_SLOT(31):
58 if (__raw_readq(&tx4939_ccfgptr->pcfg) &
59 TX4939_PCFG_ET0MODE)
60 return TXX9_IRQ_BASE + TX4939_IR_ETH(0);
61 break;
62 case TX4927_PCIC_IDSEL_AD_TO_SLOT(30):
63 if (__raw_readq(&tx4939_ccfgptr->pcfg) &
64 TX4939_PCFG_ET1MODE)
65 return TXX9_IRQ_BASE + TX4939_IR_ETH(1);
66 break;
67 }
68 return 0;
69 }
70 return -1;
71}
72
73int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
74{
75 int irq = tx4939_pcic1_map_irq(dev, slot);
76
77 if (irq >= 0)
78 return irq;
79 irq = pin;
80 /* IRQ rotation */
81 irq--; /* 0-3 */
82 irq = (irq + 33 - slot) % 4;
83 irq++; /* 1-4 */
84
85 switch (irq) {
86 case 1:
87 irq = TXX9_IRQ_BASE + TX4939_IR_INTA;
88 break;
89 case 2:
90 irq = TXX9_IRQ_BASE + TX4939_IR_INTB;
91 break;
92 case 3:
93 irq = TXX9_IRQ_BASE + TX4939_IR_INTC;
94 break;
95 case 4:
96 irq = TXX9_IRQ_BASE + TX4939_IR_INTD;
97 break;
98 }
99 return irq;
100}
101
102void __init tx4939_setup_pcierr_irq(void)
103{
104 if (request_irq(TXX9_IRQ_BASE + TX4939_IR_PCIERR,
105 tx4927_pcierr_interrupt,
106 IRQF_DISABLED, "PCI error",
107 (void *)TX4939_PCIC_REG))
108 pr_warning("Failed to request irq for PCIERR\n");
109}