more changes on original files
[linux-2.4.git] / arch / i386 / kernel / pci-visws.c
1 /*
2  *      Low-Level PCI Support for SGI Visual Workstation
3  *
4  *      (c) 1999--2000 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <linux/config.h>
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/pci.h>
12 #include <linux/init.h>
13 #include <linux/irq.h>
14
15 #include <asm/smp.h>
16 #include <asm/lithium.h>
17 #include <asm/io.h>
18
19 #include "pci-i386.h"
20
21 unsigned int pci_probe = 0;
22
23 /*
24  *  The VISWS uses configuration access type 1 only.
25  */
26
27 #define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
28
29 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
30 {
31         outl(CONFIG_CMD(dev,where), 0xCF8);
32         *value = inb(0xCFC + (where&3));
33         return PCIBIOS_SUCCESSFUL;
34 }
35
36 static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
37 {
38         outl(CONFIG_CMD(dev,where), 0xCF8);    
39         *value = inw(0xCFC + (where&2));
40         return PCIBIOS_SUCCESSFUL;    
41 }
42
43 static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
44 {
45         outl(CONFIG_CMD(dev,where), 0xCF8);
46         *value = inl(0xCFC);
47         return PCIBIOS_SUCCESSFUL;    
48 }
49
50 static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
51 {
52         outl(CONFIG_CMD(dev,where), 0xCF8);    
53         outb(value, 0xCFC + (where&3));
54         return PCIBIOS_SUCCESSFUL;
55 }
56
57 static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
58 {
59         outl(CONFIG_CMD(dev,where), 0xCF8);
60         outw(value, 0xCFC + (where&2));
61         return PCIBIOS_SUCCESSFUL;
62 }
63
64 static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
65 {
66         outl(CONFIG_CMD(dev,where), 0xCF8);
67         outl(value, 0xCFC);
68         return PCIBIOS_SUCCESSFUL;
69 }
70
71 #undef CONFIG_CMD
72
73 static struct pci_ops visws_pci_ops = {
74         pci_conf1_read_config_byte,
75         pci_conf1_read_config_word,
76         pci_conf1_read_config_dword,
77         pci_conf1_write_config_byte,
78         pci_conf1_write_config_word,
79         pci_conf1_write_config_dword
80 };
81
82 static void __init pcibios_fixup_irqs(void)
83 {
84         struct pci_dev *dev, *p;
85         u8 pin;
86         int irq;
87
88         pci_for_each_dev(dev) {
89                 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
90                 dev->irq = 0;
91                 if (!pin)
92                         continue;
93                 pin--;
94                 if (dev->bus->parent) {
95                         p = dev->bus->parent->self;
96                         pin = (pin + PCI_SLOT(dev->devfn)) % 4;
97                 } else
98                         p = dev;
99                 irq = visws_get_PCI_irq_vector(p->bus->number, PCI_SLOT(p->devfn), pin+1);
100                 if (irq >= 0)
101                         dev->irq = irq;
102                 DBG("PCI IRQ: %s pin %d -> %d\n", dev->slot_name, pin, irq);
103         }
104 }
105
106 void __init pcibios_fixup_bus(struct pci_bus *b)
107 {
108         pci_read_bridge_bases(b);
109 }
110
111 #if 0
112 static struct resource visws_pci_bus_resources[2] = {
113         { "Host bus 1", 0xf4000000, 0xf7ffffff, 0 },
114         { "Host bus 2", 0xf0000000, 0xf3ffffff, 0 }
115 };
116 #endif
117
118 void __init pcibios_init(void)
119 {
120         unsigned int sec_bus = li_pcib_read16(LI_PCI_BUSNUM) & 0xff;
121
122         pcibios_set_cacheline_size();
123         printk("PCI: Probing PCI hardware on host buses 00 and %02x\n", sec_bus);
124         pci_scan_bus(0, &visws_pci_ops, NULL);
125         pci_scan_bus(sec_bus, &visws_pci_ops, NULL);
126         pcibios_fixup_irqs();
127         pcibios_resource_survey();
128 }
129
130 char * __init pcibios_setup(char *str)
131 {
132         return str;
133 }
134
135 int pcibios_enable_device(struct pci_dev *dev, int mask)
136 {
137         return pcibios_enable_resources(dev, mask);
138 }
139
140 void __init pcibios_penalize_isa_irq(irq)
141 {
142 }