summaryrefslogtreecommitdiff
path: root/include/linux/ioc4.h
blob: 729bfa4c4ac5f74d4d9e0e92caad66d2ca0c26e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
 */

#ifndef _LINUX_IOC4_H
#define _LINUX_IOC4_H

#include <linux/interrupt.h>

/***********************************
 * Structures needed by subdrivers *
 ***********************************/

/* This structure fully describes the IOC4 miscellaneous registers which
 * appear at bar[0]+0x00000 through bar[0]+0x0005c.  The corresponding
 * PCI resource is managed by the main IOC4 driver because it contains
 * registers of interest to many different IOC4 subdrivers.
 */
struct ioc4_misc_regs {
	/* Miscellaneous IOC4 registers */
	union ioc4_pci_err_addr_l {
		uint32_t raw;
		struct {
			uint32_t valid:1;	/* Address captured */
			uint32_t master_id:4;	/* Unit causing error
						 * 0/1: Serial port 0 TX/RX
						 * 2/3: Serial port 1 TX/RX
						 * 4/5: Serial port 2 TX/RX
						 * 6/7: Serial port 3 TX/RX
						 * 8: ATA/ATAPI
						 * 9-15: Undefined
						 */
			uint32_t mul_err:1;	/* Multiple errors occurred */
			uint32_t addr:26;	/* Bits 31-6 of error addr */
		} fields;
	} pci_err_addr_l;
	uint32_t pci_err_addr_h;	/* Bits 63-32 of error addr */
	union ioc4_sio_int {
		uint32_t raw;
		struct {
			uint8_t tx_mt:1;	/* TX ring buffer empty */
			uint8_t rx_full:1;	/* RX ring buffer full */
			uint8_t rx_high:1;	/* RX high-water exceeded */
			uint8_t rx_timer:1;	/* RX timer has triggered */
			uint8_t delta_dcd:1;	/* DELTA_DCD seen */
			uint8_t delta_cts:1;	/* DELTA_CTS seen */
			uint8_t intr_pass:1;	/* Interrupt pass-through */
			uint8_t tx_explicit:1;	/* TX, MCW, or delay complete */
		} fields[4];
	} sio_ir;		/* Serial interrupt state */
	union ioc4_other_int {
		uint32_t raw;
		struct {
			uint32_t ata_int:1;	/* ATA port passthru */
			uint32_t ata_memerr:1;	/* ATA halted by mem error */
			uint32_t memerr:4;	/* Serial halted by mem err */
			uint32_t kbd_int:1;	/* kbd/mouse intr asserted */
			uint32_t reserved:16;	/* zero */
			uint32_t rt_int:1;	/* INT_OUT section latch */
			uint32_t gen_int:8;	/* Intr. from generic pins */
		} fields;
	} other_ir;		/* Other interrupt state */
	union ioc4_sio_int sio_ies;	/* Serial interrupt enable set */
	union ioc4_other_int other_ies;	/* Other interrupt enable set */
	union ioc4_sio_int sio_iec;	/* Serial interrupt enable clear */
	union ioc4_other_int other_iec;	/* Other interrupt enable clear */
	union ioc4_sio_cr {
		uint32_t raw;
		struct {
			uint32_t cmd_pulse:4;	/* Bytebus strobe width */
			uint32_t arb_diag:3;	/* PCI bus requester */
			uint32_t sio_diag_idle:1;	/* Active ser req? */
			uint32_t ata_diag_idle:1;	/* Active ATA req? */
			uint32_t ata_diag_active:1;	/* ATA req is winner */
			uint32_t reserved:22;	/* zero */
		} fields;
	} sio_cr;
	uint32_t unused1;
	union ioc4_int_out {
		uint32_t raw;
		struct {
			uint32_t count:16;	/* Period control */
			uint32_t mode:3;	/* Output signal shape */
			uint32_t reserved:11;	/* zero */
			uint32_t diag:1;	/* Timebase control */
			uint32_t int_out:1;	/* Current value */
		} fields;
	} int_out;		/* External interrupt output control */
	uint32_t unused2;
	union ioc4_gpcr {
		uint32_t raw;
		struct {
			uint32_t dir:8;	/* Pin direction */
			uint32_t edge:8;	/* Edge/level mode */
			uint32_t reserved1:4;	/* zero */
			uint32_t int_out_en:1;	/* INT_OUT enable */
			uint32_t reserved2:11;	/* zero */
		} fields;
	} gpcr_s;		/* Generic PIO control set */
	union ioc4_gpcr gpcr_c;	/* Generic PIO control clear */
	union ioc4_gpdr {
		uint32_t raw;
		struct {
			uint32_t gen_pin:8;	/* State of pins */
			uint32_t reserved:24;
		} fields;
	} gpdr;			/* Generic PIO data */
	uint32_t unused3;
	union ioc4_gppr {
		uint32_t raw;
		struct {
			uint32_t gen_pin:1;	/* Single pin state */
			uint32_t reserved:31;
		} fields;
	} gppr[8];		/* Generic PIO pins */
};

/* One of these per IOC4
 *
 * The idd_serial_data field is present here, even though it's used
 * solely by the serial subdriver, because the main IOC4 module
 * properly owns pci_{get,set}_drvdata functionality.  This field
 * allows that subdriver to stash its own drvdata somewhere.
 */
struct ioc4_driver_data {
	struct list_head idd_list;
	unsigned long idd_bar0;
	struct pci_dev *idd_pdev;
	const struct pci_device_id *idd_pci_id;
	struct __iomem ioc4_misc_regs *idd_misc_regs;
	void *idd_serial_data;
};

/* One per submodule */
struct ioc4_submodule {
	struct list_head is_list;
	char *is_name;
	struct module *is_owner;
	int (*is_probe) (struct ioc4_driver_data *);
	int (*is_remove) (struct ioc4_driver_data *);
};

#define IOC4_NUM_CARDS		8	/* max cards per partition */

/**********************************
 * Functions needed by submodules *
 **********************************/

extern int ioc4_register_submodule(struct ioc4_submodule *);
extern void ioc4_unregister_submodule(struct ioc4_submodule *);

#endif				/* _LINUX_IOC4_H */