aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ioc4.h
diff options
context:
space:
mode:
authorBrent Casavant <bcasavan@sgi.com>2005-06-21 20:15:59 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:32 -0400
commit22329b511a97557b293583194037d1f4c71e1504 (patch)
tree925e6c4566371e7ffb66a54b631049b958c19eca /include/linux/ioc4.h
parente400bae98499583767da58fb0a1b9ad3e24fcb86 (diff)
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure of the SGI IOC4 I/O controller device drivers. These changes are motivated by several factors: - The IOC4 chip PCI resources are of mixed use between functions (i.e. multiple functions are handled in the same address range, sometimes within the same register), muddling resource ownership and initialization issues. Centralizing this ownership in a core driver is desirable. - The IOC4 chip implements multiple functions (serial, IDE, others not yet implemented in the mainline kernel) but is not a multifunction PCI device. In order to properly handle device addition and removal as well as module insertion and deletion, an intermediary IOC4-specific driver layer is needed to handle these operations cleanly. - All IOC4 drivers are currently enabled by a single CONFIG value. As not all systems need all IOC4 functions, it is desireable to enable these drivers independently. - The current IOC4 core driver will trigger loading of all function-level drivers, as it makes direct calls to them. This situation should be reversed (i.e. function-level drivers cause loading of core driver) in order to maintain a clear and least-surprise driver loading model. - IOC4 hardware design necessitates some driver-level dependency on the PCI bus clock speed. Current code assumes a 66MHz bus, but the speed should be autodetected and appropriate compensation taken. This patch series effects the above changes by a newly and better designed IOC4 core driver with which the function-level drivers can register and deregister themselves upon module insertion/removal. By tracking these modules, device addition/removal is also handled properly. PCI resource management and ownership issues are centralized in this core driver, and IOC4-wide configuration actions such as bus speed detection are also handled in this core driver. This patch: The SGI IOC4 I/O controller chip implements multiple functions, though it is not a multi-function PCI device. Additionally, various PCI resources of the IOC4 are shared by multiple hardware functions, and thus resource ownership by driver is not clearly delineated. Due to the current driver design, all core and subordinate drivers must be loaded, or none, which is undesirable if not all IOC4 hardware features are being used. This patch reorganizes the IOC4 drivers so that the core driver provides a subdriver registration service. Through appropriate callbacks the subdrivers can now handle device addition and removal, as well as module insertion and deletion (though the IOC4 IDE driver requires further work before module deletion will work). The core driver now takes care of allocating PCI resources and data which must be shared between subdrivers, to clearly delineate module ownership of these items. Signed-off-by: Brent Casavant <bcasavan@sgi.com> Acked-by: Pat Gefre <pfg@sgi.com Acked-by: Jeremy Higdon <jeremy@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/ioc4.h')
-rw-r--r--include/linux/ioc4.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h
new file mode 100644
index 000000000000..729bfa4c4ac5
--- /dev/null
+++ b/include/linux/ioc4.h
@@ -0,0 +1,156 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9#ifndef _LINUX_IOC4_H
10#define _LINUX_IOC4_H
11
12#include <linux/interrupt.h>
13
14/***********************************
15 * Structures needed by subdrivers *
16 ***********************************/
17
18/* This structure fully describes the IOC4 miscellaneous registers which
19 * appear at bar[0]+0x00000 through bar[0]+0x0005c. The corresponding
20 * PCI resource is managed by the main IOC4 driver because it contains
21 * registers of interest to many different IOC4 subdrivers.
22 */
23struct ioc4_misc_regs {
24 /* Miscellaneous IOC4 registers */
25 union ioc4_pci_err_addr_l {
26 uint32_t raw;
27 struct {
28 uint32_t valid:1; /* Address captured */
29 uint32_t master_id:4; /* Unit causing error
30 * 0/1: Serial port 0 TX/RX
31 * 2/3: Serial port 1 TX/RX
32 * 4/5: Serial port 2 TX/RX
33 * 6/7: Serial port 3 TX/RX
34 * 8: ATA/ATAPI
35 * 9-15: Undefined
36 */
37 uint32_t mul_err:1; /* Multiple errors occurred */
38 uint32_t addr:26; /* Bits 31-6 of error addr */
39 } fields;
40 } pci_err_addr_l;
41 uint32_t pci_err_addr_h; /* Bits 63-32 of error addr */
42 union ioc4_sio_int {
43 uint32_t raw;
44 struct {
45 uint8_t tx_mt:1; /* TX ring buffer empty */
46 uint8_t rx_full:1; /* RX ring buffer full */
47 uint8_t rx_high:1; /* RX high-water exceeded */
48 uint8_t rx_timer:1; /* RX timer has triggered */
49 uint8_t delta_dcd:1; /* DELTA_DCD seen */
50 uint8_t delta_cts:1; /* DELTA_CTS seen */
51 uint8_t intr_pass:1; /* Interrupt pass-through */
52 uint8_t tx_explicit:1; /* TX, MCW, or delay complete */
53 } fields[4];
54 } sio_ir; /* Serial interrupt state */
55 union ioc4_other_int {
56 uint32_t raw;
57 struct {
58 uint32_t ata_int:1; /* ATA port passthru */
59 uint32_t ata_memerr:1; /* ATA halted by mem error */
60 uint32_t memerr:4; /* Serial halted by mem err */
61 uint32_t kbd_int:1; /* kbd/mouse intr asserted */
62 uint32_t reserved:16; /* zero */
63 uint32_t rt_int:1; /* INT_OUT section latch */
64 uint32_t gen_int:8; /* Intr. from generic pins */
65 } fields;
66 } other_ir; /* Other interrupt state */
67 union ioc4_sio_int sio_ies; /* Serial interrupt enable set */
68 union ioc4_other_int other_ies; /* Other interrupt enable set */
69 union ioc4_sio_int sio_iec; /* Serial interrupt enable clear */
70 union ioc4_other_int other_iec; /* Other interrupt enable clear */
71 union ioc4_sio_cr {
72 uint32_t raw;
73 struct {
74 uint32_t cmd_pulse:4; /* Bytebus strobe width */
75 uint32_t arb_diag:3; /* PCI bus requester */
76 uint32_t sio_diag_idle:1; /* Active ser req? */
77 uint32_t ata_diag_idle:1; /* Active ATA req? */
78 uint32_t ata_diag_active:1; /* ATA req is winner */
79 uint32_t reserved:22; /* zero */
80 } fields;
81 } sio_cr;
82 uint32_t unused1;
83 union ioc4_int_out {
84 uint32_t raw;
85 struct {
86 uint32_t count:16; /* Period control */
87 uint32_t mode:3; /* Output signal shape */
88 uint32_t reserved:11; /* zero */
89 uint32_t diag:1; /* Timebase control */
90 uint32_t int_out:1; /* Current value */
91 } fields;
92 } int_out; /* External interrupt output control */
93 uint32_t unused2;
94 union ioc4_gpcr {
95 uint32_t raw;
96 struct {
97 uint32_t dir:8; /* Pin direction */
98 uint32_t edge:8; /* Edge/level mode */
99 uint32_t reserved1:4; /* zero */
100 uint32_t int_out_en:1; /* INT_OUT enable */
101 uint32_t reserved2:11; /* zero */
102 } fields;
103 } gpcr_s; /* Generic PIO control set */
104 union ioc4_gpcr gpcr_c; /* Generic PIO control clear */
105 union ioc4_gpdr {
106 uint32_t raw;
107 struct {
108 uint32_t gen_pin:8; /* State of pins */
109 uint32_t reserved:24;
110 } fields;
111 } gpdr; /* Generic PIO data */
112 uint32_t unused3;
113 union ioc4_gppr {
114 uint32_t raw;
115 struct {
116 uint32_t gen_pin:1; /* Single pin state */
117 uint32_t reserved:31;
118 } fields;
119 } gppr[8]; /* Generic PIO pins */
120};
121
122/* One of these per IOC4
123 *
124 * The idd_serial_data field is present here, even though it's used
125 * solely by the serial subdriver, because the main IOC4 module
126 * properly owns pci_{get,set}_drvdata functionality. This field
127 * allows that subdriver to stash its own drvdata somewhere.
128 */
129struct ioc4_driver_data {
130 struct list_head idd_list;
131 unsigned long idd_bar0;
132 struct pci_dev *idd_pdev;
133 const struct pci_device_id *idd_pci_id;
134 struct __iomem ioc4_misc_regs *idd_misc_regs;
135 void *idd_serial_data;
136};
137
138/* One per submodule */
139struct ioc4_submodule {
140 struct list_head is_list;
141 char *is_name;
142 struct module *is_owner;
143 int (*is_probe) (struct ioc4_driver_data *);
144 int (*is_remove) (struct ioc4_driver_data *);
145};
146
147#define IOC4_NUM_CARDS 8 /* max cards per partition */
148
149/**********************************
150 * Functions needed by submodules *
151 **********************************/
152
153extern int ioc4_register_submodule(struct ioc4_submodule *);
154extern void ioc4_unregister_submodule(struct ioc4_submodule *);
155
156#endif /* _LINUX_IOC4_H */