4 * Intel/Ziatech ZT5550 CompactPCI Host Controller driver
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 * Send feedback to <scottm@somanetworks.com>
33 #include <linux/config.h>
34 #include <linux/module.h>
35 #include <linux/init.h>
36 #include <linux/errno.h>
37 #include <linux/pci.h>
38 #include "cpci_hotplug.h"
39 #include "cpcihp_zt5550.h"
41 #define DRIVER_VERSION "0.2"
42 #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
43 #define DRIVER_DESC "ZT5550 CompactPCI Hot Plug Driver"
45 #if !defined(CONFIG_HOTPLUG_PCI_CPCI_ZT5550_MODULE)
46 #define MY_NAME "cpcihp_zt5550"
48 #define MY_NAME THIS_MODULE->name
51 #define dbg(format, arg...) \
54 printk (KERN_DEBUG "%s: " format "\n", \
57 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
58 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
59 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
64 static struct cpci_hp_controller_ops zt5550_hpc_ops;
65 static struct cpci_hp_controller zt5550_hpc;
67 /* Primary cPCI bus bridge device */
68 static struct pci_dev *bus0_dev;
69 static struct pci_bus *bus0;
71 /* Host controller device */
72 static struct pci_dev *hc_dev;
74 /* Host controller register addresses */
75 static void *hc_registers;
76 static void *csr_hc_index;
77 static void *csr_hc_data;
78 static void *csr_int_status;
79 static void *csr_int_mask;
82 static int zt5550_hc_config(struct pci_dev *pdev)
84 /* Since we know that no boards exist with two HC chips, treat it as an error */
86 err("too many host controller devices?");
90 dbg("hc_dev = %p", hc_dev);
91 dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
92 dbg("pci resource len %lx", pci_resource_len(hc_dev, 1));
94 if(!request_mem_region(pci_resource_start(hc_dev, 1),
95 pci_resource_len(hc_dev, 1), MY_NAME)) {
96 err("cannot reserve MMIO region");
101 ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
103 err("cannot remap MMIO region %lx @ %lx",
104 pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
105 release_mem_region(pci_resource_start(hc_dev, 1),
106 pci_resource_len(hc_dev, 1));
110 csr_hc_index = hc_registers + CSR_HCINDEX;
111 csr_hc_data = hc_registers + CSR_HCDATA;
112 csr_int_status = hc_registers + CSR_INTSTAT;
113 csr_int_mask = hc_registers + CSR_INTMASK;
116 * Disable host control, fault and serial interrupts
118 dbg("disabling host control, fault and serial interrupts");
119 writeb((u8) HC_INT_MASK_REG, csr_hc_index);
120 writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data);
121 dbg("disabled host control, fault and serial interrupts");
124 * Disable timer0, timer1 and ENUM interrupts
126 dbg("disabling timer0, timer1 and ENUM interrupts");
127 writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
128 dbg("disabled timer0, timer1 and ENUM interrupts");
132 static int zt5550_hc_cleanup(void)
137 iounmap(hc_registers);
138 release_mem_region(pci_resource_start(hc_dev, 1),
139 pci_resource_len(hc_dev, 1));
143 static int zt5550_hc_query_enum(void)
147 value = inb_p(ENUM_PORT);
148 return ((value & ENUM_MASK) == ENUM_MASK);
151 static int zt5550_hc_check_irq(void *dev_id)
157 if(dev_id == zt5550_hpc.dev_id) {
158 reg = readb(csr_int_status);
165 static int zt5550_hc_enable_irq(void)
172 reg = readb(csr_int_mask);
173 reg = reg & ~ENUM_INT_MASK;
174 writeb(reg, csr_int_mask);
178 int zt5550_hc_disable_irq(void)
186 reg = readb(csr_int_mask);
187 reg = reg | ENUM_INT_MASK;
188 writeb(reg, csr_int_mask);
192 static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
196 status = zt5550_hc_config(pdev);
200 dbg("returned from zt5550_hc_config");
202 memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
203 zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
204 zt5550_hpc.ops = &zt5550_hpc_ops;
206 zt5550_hpc.irq = hc_dev->irq;
207 zt5550_hpc.irq_flags = SA_SHIRQ;
208 zt5550_hpc.dev_id = hc_dev;
210 zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
211 zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq;
212 zt5550_hpc_ops.check_irq = zt5550_hc_check_irq;
214 info("using ENUM# polling mode");
217 status = cpci_hp_register_controller(&zt5550_hpc);
219 err("could not register cPCI hotplug controller");
222 dbg("registered controller");
224 /* Look for first device matching cPCI bus's bridge vendor and device IDs */
225 if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC,
226 PCI_DEVICE_ID_DEC_21154, NULL))) {
228 goto init_register_error;
230 bus0 = bus0_dev->subordinate;
232 status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
234 err("could not register cPCI hotplug bus");
235 goto init_register_error;
237 dbg("registered bus");
239 status = cpci_hp_start();
241 err("could not started cPCI hotplug system");
242 cpci_hp_unregister_bus(bus0);
243 goto init_register_error;
245 dbg("started cpci hp system");
249 cpci_hp_unregister_controller(&zt5550_hpc);
251 err("status = %d", status);
257 static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
260 cpci_hp_unregister_bus(bus0);
261 cpci_hp_unregister_controller(&zt5550_hpc);
266 static struct pci_device_id zt5550_hc_pci_tbl[] = {
267 { PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, },
270 MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl);
272 static struct pci_driver zt5550_hc_driver = {
274 .id_table = zt5550_hc_pci_tbl,
275 .probe = zt5550_hc_init_one,
276 .remove = __devexit_p(zt5550_hc_remove_one),
279 static int __init zt5550_init(void)
283 info(DRIVER_DESC " version: " DRIVER_VERSION);
284 r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register");
288 return pci_module_init(&zt5550_hc_driver);
294 pci_unregister_driver(&zt5550_hc_driver);
295 release_region(ENUM_PORT, 1);
298 module_init(zt5550_init);
299 module_exit(zt5550_exit);
301 MODULE_AUTHOR(DRIVER_AUTHOR);
302 MODULE_DESCRIPTION(DRIVER_DESC);
303 MODULE_LICENSE("GPL");
304 MODULE_PARM(debug, "i");
305 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
306 MODULE_PARM(poll, "i");
307 MODULE_PARM_DESC(poll, "#ENUM polling mode enabled or not");