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/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/errno.h>
38 #include <linux/pci.h>
39 #include "cpci_hotplug.h"
40 #include "cpcihp_zt5550.h"
42 #define DRIVER_VERSION "0.2"
43 #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
44 #define DRIVER_DESC "ZT5550 CompactPCI Hot Plug Driver"
46 #define MY_NAME "cpcihp_zt5550"
48 #define dbg(format, arg...) \
51 printk (KERN_DEBUG "%s: " format "\n", \
54 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
55 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
56 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
61 static struct cpci_hp_controller_ops zt5550_hpc_ops
;
62 static struct cpci_hp_controller zt5550_hpc
;
64 /* Primary cPCI bus bridge device */
65 static struct pci_dev
*bus0_dev
;
66 static struct pci_bus
*bus0
;
68 /* Host controller device */
69 static struct pci_dev
*hc_dev
;
71 /* Host controller register addresses */
72 static void __iomem
*hc_registers
;
73 static void __iomem
*csr_hc_index
;
74 static void __iomem
*csr_hc_data
;
75 static void __iomem
*csr_int_status
;
76 static void __iomem
*csr_int_mask
;
79 static int zt5550_hc_config(struct pci_dev
*pdev
)
81 /* Since we know that no boards exist with two HC chips, treat it as an error */
83 err("too many host controller devices?");
87 dbg("hc_dev = %p", hc_dev
);
88 dbg("pci resource start %lx", pci_resource_start(hc_dev
, 1));
89 dbg("pci resource len %lx", pci_resource_len(hc_dev
, 1));
91 if(!request_mem_region(pci_resource_start(hc_dev
, 1),
92 pci_resource_len(hc_dev
, 1), MY_NAME
)) {
93 err("cannot reserve MMIO region");
98 ioremap(pci_resource_start(hc_dev
, 1), pci_resource_len(hc_dev
, 1));
100 err("cannot remap MMIO region %lx @ %lx",
101 pci_resource_len(hc_dev
, 1), pci_resource_start(hc_dev
, 1));
102 release_mem_region(pci_resource_start(hc_dev
, 1),
103 pci_resource_len(hc_dev
, 1));
107 csr_hc_index
= hc_registers
+ CSR_HCINDEX
;
108 csr_hc_data
= hc_registers
+ CSR_HCDATA
;
109 csr_int_status
= hc_registers
+ CSR_INTSTAT
;
110 csr_int_mask
= hc_registers
+ CSR_INTMASK
;
113 * Disable host control, fault and serial interrupts
115 dbg("disabling host control, fault and serial interrupts");
116 writeb((u8
) HC_INT_MASK_REG
, csr_hc_index
);
117 writeb((u8
) ALL_INDEXED_INTS_MASK
, csr_hc_data
);
118 dbg("disabled host control, fault and serial interrupts");
121 * Disable timer0, timer1 and ENUM interrupts
123 dbg("disabling timer0, timer1 and ENUM interrupts");
124 writeb((u8
) ALL_DIRECT_INTS_MASK
, csr_int_mask
);
125 dbg("disabled timer0, timer1 and ENUM interrupts");
129 static int zt5550_hc_cleanup(void)
134 iounmap(hc_registers
);
135 release_mem_region(pci_resource_start(hc_dev
, 1),
136 pci_resource_len(hc_dev
, 1));
140 static int zt5550_hc_query_enum(void)
144 value
= inb_p(ENUM_PORT
);
145 return ((value
& ENUM_MASK
) == ENUM_MASK
);
148 static int zt5550_hc_check_irq(void *dev_id
)
154 if(dev_id
== zt5550_hpc
.dev_id
) {
155 reg
= readb(csr_int_status
);
162 static int zt5550_hc_enable_irq(void)
169 reg
= readb(csr_int_mask
);
170 reg
= reg
& ~ENUM_INT_MASK
;
171 writeb(reg
, csr_int_mask
);
175 static int zt5550_hc_disable_irq(void)
183 reg
= readb(csr_int_mask
);
184 reg
= reg
| ENUM_INT_MASK
;
185 writeb(reg
, csr_int_mask
);
189 static int zt5550_hc_init_one (struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
193 status
= zt5550_hc_config(pdev
);
197 dbg("returned from zt5550_hc_config");
199 memset(&zt5550_hpc
, 0, sizeof (struct cpci_hp_controller
));
200 zt5550_hpc_ops
.query_enum
= zt5550_hc_query_enum
;
201 zt5550_hpc
.ops
= &zt5550_hpc_ops
;
203 zt5550_hpc
.irq
= hc_dev
->irq
;
204 zt5550_hpc
.irq_flags
= SA_SHIRQ
;
205 zt5550_hpc
.dev_id
= hc_dev
;
207 zt5550_hpc_ops
.enable_irq
= zt5550_hc_enable_irq
;
208 zt5550_hpc_ops
.disable_irq
= zt5550_hc_disable_irq
;
209 zt5550_hpc_ops
.check_irq
= zt5550_hc_check_irq
;
211 info("using ENUM# polling mode");
214 status
= cpci_hp_register_controller(&zt5550_hpc
);
216 err("could not register cPCI hotplug controller");
219 dbg("registered controller");
221 /* Look for first device matching cPCI bus's bridge vendor and device IDs */
222 if(!(bus0_dev
= pci_get_device(PCI_VENDOR_ID_DEC
,
223 PCI_DEVICE_ID_DEC_21154
, NULL
))) {
225 goto init_register_error
;
227 bus0
= bus0_dev
->subordinate
;
228 pci_dev_put(bus0_dev
);
230 status
= cpci_hp_register_bus(bus0
, 0x0a, 0x0f);
232 err("could not register cPCI hotplug bus");
233 goto init_register_error
;
235 dbg("registered bus");
237 status
= cpci_hp_start();
239 err("could not started cPCI hotplug system");
240 cpci_hp_unregister_bus(bus0
);
241 goto init_register_error
;
243 dbg("started cpci hp system");
247 cpci_hp_unregister_controller(&zt5550_hpc
);
249 err("status = %d", status
);
255 static void __devexit
zt5550_hc_remove_one(struct pci_dev
*pdev
)
258 cpci_hp_unregister_bus(bus0
);
259 cpci_hp_unregister_controller(&zt5550_hpc
);
264 static struct pci_device_id zt5550_hc_pci_tbl
[] = {
265 { PCI_VENDOR_ID_ZIATECH
, PCI_DEVICE_ID_ZIATECH_5550_HC
, PCI_ANY_ID
, PCI_ANY_ID
, },
268 MODULE_DEVICE_TABLE(pci
, zt5550_hc_pci_tbl
);
270 static struct pci_driver zt5550_hc_driver
= {
272 .id_table
= zt5550_hc_pci_tbl
,
273 .probe
= zt5550_hc_init_one
,
274 .remove
= __devexit_p(zt5550_hc_remove_one
),
277 static int __init
zt5550_init(void)
281 info(DRIVER_DESC
" version: " DRIVER_VERSION
);
282 r
= request_region(ENUM_PORT
, 1, "#ENUM hotswap signal register");
286 return pci_register_driver(&zt5550_hc_driver
);
292 pci_unregister_driver(&zt5550_hc_driver
);
293 release_region(ENUM_PORT
, 1);
296 module_init(zt5550_init
);
297 module_exit(zt5550_exit
);
299 MODULE_AUTHOR(DRIVER_AUTHOR
);
300 MODULE_DESCRIPTION(DRIVER_DESC
);
301 MODULE_LICENSE("GPL");
302 module_param(debug
, bool, 0644);
303 MODULE_PARM_DESC(debug
, "Debugging mode enabled or not");
304 module_param(poll
, bool, 0644);
305 MODULE_PARM_DESC(poll
, "#ENUM polling mode enabled or not");