diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-10 16:32:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-10 16:32:05 -0400 |
commit | 0ab598099c18affd73a21482274c00e8119236be (patch) | |
tree | 599ddc4ffb8bfa4bb6364eb4f4a3e91bfd9cb6c9 | |
parent | b526ca438b95a6d71210e0ffc79aabac8aba2b1e (diff) | |
parent | 26e6385f14b991e30450daee4348cbbc4bc4bb09 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Use alloc_pci_dev() in PCI bus probes.
[SPARC64]: Bump PROMINTR_MAX to 32.
[SPARC64]: Fix recursion in PROM tree building.
[SERIAL] sunzilog: Interrupt enable before ISR handler installed
[SPARC64] PCI: Consolidate PCI access code into pci_common.c
-rw-r--r-- | arch/sparc64/kernel/pci.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_common.c | 194 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_fire.c | 135 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_impl.h | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 119 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 288 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 122 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 86 | ||||
-rw-r--r-- | arch/sparc64/kernel/prom.c | 19 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 138 | ||||
-rw-r--r-- | drivers/serial/sunzilog.h | 19 | ||||
-rw-r--r-- | include/asm-sparc64/openprom.h | 2 |
12 files changed, 349 insertions, 781 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index d85e1ed7c3e4..cf9a75112d0f 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -377,7 +377,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
377 | const char *type; | 377 | const char *type; |
378 | u32 class; | 378 | u32 class; |
379 | 379 | ||
380 | dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); | 380 | dev = alloc_pci_dev(); |
381 | if (!dev) | 381 | if (!dev) |
382 | return NULL; | 382 | return NULL; |
383 | 383 | ||
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 76faaa8135dd..f974fefc3ebc 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -14,6 +14,200 @@ | |||
14 | #include <asm/oplib.h> | 14 | #include <asm/oplib.h> |
15 | 15 | ||
16 | #include "pci_impl.h" | 16 | #include "pci_impl.h" |
17 | #include "pci_sun4v.h" | ||
18 | |||
19 | static int config_out_of_range(struct pci_pbm_info *pbm, | ||
20 | unsigned long bus, | ||
21 | unsigned long devfn, | ||
22 | unsigned long reg) | ||
23 | { | ||
24 | if (bus < pbm->pci_first_busno || | ||
25 | bus > pbm->pci_last_busno) | ||
26 | return 1; | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static void *sun4u_config_mkaddr(struct pci_pbm_info *pbm, | ||
31 | unsigned long bus, | ||
32 | unsigned long devfn, | ||
33 | unsigned long reg) | ||
34 | { | ||
35 | unsigned long rbits = pbm->config_space_reg_bits; | ||
36 | |||
37 | if (config_out_of_range(pbm, bus, devfn, reg)) | ||
38 | return NULL; | ||
39 | |||
40 | reg = (reg & ((1 << rbits) - 1)); | ||
41 | devfn <<= rbits; | ||
42 | bus <<= rbits + 8; | ||
43 | |||
44 | return (void *) (pbm->config_space | bus | devfn | reg); | ||
45 | } | ||
46 | |||
47 | static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
48 | int where, int size, u32 *value) | ||
49 | { | ||
50 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
51 | unsigned char bus = bus_dev->number; | ||
52 | u32 *addr; | ||
53 | u16 tmp16; | ||
54 | u8 tmp8; | ||
55 | |||
56 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
57 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
58 | size, value); | ||
59 | |||
60 | switch (size) { | ||
61 | case 1: | ||
62 | *value = 0xff; | ||
63 | break; | ||
64 | case 2: | ||
65 | *value = 0xffff; | ||
66 | break; | ||
67 | case 4: | ||
68 | *value = 0xffffffff; | ||
69 | break; | ||
70 | } | ||
71 | |||
72 | addr = sun4u_config_mkaddr(pbm, bus, devfn, where); | ||
73 | if (!addr) | ||
74 | return PCIBIOS_SUCCESSFUL; | ||
75 | |||
76 | switch (size) { | ||
77 | case 1: | ||
78 | pci_config_read8((u8 *)addr, &tmp8); | ||
79 | *value = (u32) tmp8; | ||
80 | break; | ||
81 | |||
82 | case 2: | ||
83 | if (where & 0x01) { | ||
84 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
85 | where); | ||
86 | return PCIBIOS_SUCCESSFUL; | ||
87 | } | ||
88 | pci_config_read16((u16 *)addr, &tmp16); | ||
89 | *value = (u32) tmp16; | ||
90 | break; | ||
91 | |||
92 | case 4: | ||
93 | if (where & 0x03) { | ||
94 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
95 | where); | ||
96 | return PCIBIOS_SUCCESSFUL; | ||
97 | } | ||
98 | pci_config_read32(addr, value); | ||
99 | break; | ||
100 | } | ||
101 | return PCIBIOS_SUCCESSFUL; | ||
102 | } | ||
103 | |||
104 | static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
105 | int where, int size, u32 value) | ||
106 | { | ||
107 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
108 | unsigned char bus = bus_dev->number; | ||
109 | u32 *addr; | ||
110 | |||
111 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
112 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
113 | size, value); | ||
114 | addr = sun4u_config_mkaddr(pbm, bus, devfn, where); | ||
115 | if (!addr) | ||
116 | return PCIBIOS_SUCCESSFUL; | ||
117 | |||
118 | switch (size) { | ||
119 | case 1: | ||
120 | pci_config_write8((u8 *)addr, value); | ||
121 | break; | ||
122 | |||
123 | case 2: | ||
124 | if (where & 0x01) { | ||
125 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
126 | where); | ||
127 | return PCIBIOS_SUCCESSFUL; | ||
128 | } | ||
129 | pci_config_write16((u16 *)addr, value); | ||
130 | break; | ||
131 | |||
132 | case 4: | ||
133 | if (where & 0x03) { | ||
134 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
135 | where); | ||
136 | return PCIBIOS_SUCCESSFUL; | ||
137 | } | ||
138 | pci_config_write32(addr, value); | ||
139 | } | ||
140 | return PCIBIOS_SUCCESSFUL; | ||
141 | } | ||
142 | |||
143 | struct pci_ops sun4u_pci_ops = { | ||
144 | .read = sun4u_read_pci_cfg, | ||
145 | .write = sun4u_write_pci_cfg, | ||
146 | }; | ||
147 | |||
148 | static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
149 | int where, int size, u32 *value) | ||
150 | { | ||
151 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
152 | u32 devhandle = pbm->devhandle; | ||
153 | unsigned int bus = bus_dev->number; | ||
154 | unsigned int device = PCI_SLOT(devfn); | ||
155 | unsigned int func = PCI_FUNC(devfn); | ||
156 | unsigned long ret; | ||
157 | |||
158 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
159 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
160 | size, value); | ||
161 | if (config_out_of_range(pbm, bus, devfn, where)) { | ||
162 | ret = ~0UL; | ||
163 | } else { | ||
164 | ret = pci_sun4v_config_get(devhandle, | ||
165 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
166 | where, size); | ||
167 | } | ||
168 | switch (size) { | ||
169 | case 1: | ||
170 | *value = ret & 0xff; | ||
171 | break; | ||
172 | case 2: | ||
173 | *value = ret & 0xffff; | ||
174 | break; | ||
175 | case 4: | ||
176 | *value = ret & 0xffffffff; | ||
177 | break; | ||
178 | }; | ||
179 | |||
180 | |||
181 | return PCIBIOS_SUCCESSFUL; | ||
182 | } | ||
183 | |||
184 | static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
185 | int where, int size, u32 value) | ||
186 | { | ||
187 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
188 | u32 devhandle = pbm->devhandle; | ||
189 | unsigned int bus = bus_dev->number; | ||
190 | unsigned int device = PCI_SLOT(devfn); | ||
191 | unsigned int func = PCI_FUNC(devfn); | ||
192 | unsigned long ret; | ||
193 | |||
194 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
195 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
196 | size, value); | ||
197 | if (config_out_of_range(pbm, bus, devfn, where)) { | ||
198 | /* Do nothing. */ | ||
199 | } else { | ||
200 | ret = pci_sun4v_config_put(devhandle, | ||
201 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
202 | where, size, value); | ||
203 | } | ||
204 | return PCIBIOS_SUCCESSFUL; | ||
205 | } | ||
206 | |||
207 | struct pci_ops sun4v_pci_ops = { | ||
208 | .read = sun4v_read_pci_cfg, | ||
209 | .write = sun4v_write_pci_cfg, | ||
210 | }; | ||
17 | 211 | ||
18 | void pci_get_pbm_props(struct pci_pbm_info *pbm) | 212 | void pci_get_pbm_props(struct pci_pbm_info *pbm) |
19 | { | 213 | { |
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 2e0eb4ee8f71..9198c1a0f7a5 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c | |||
@@ -27,138 +27,6 @@ | |||
27 | "i" (ASI_PHYS_BYPASS_EC_E) \ | 27 | "i" (ASI_PHYS_BYPASS_EC_E) \ |
28 | : "memory") | 28 | : "memory") |
29 | 29 | ||
30 | /* Fire config space address format is nearly identical to | ||
31 | * that of SCHIZO and PSYCHO, except that in order to accomodate | ||
32 | * PCI-E extended config space the encoding can handle 12 bits | ||
33 | * of register address: | ||
34 | * | ||
35 | * 32 28 27 20 19 15 14 12 11 2 1 0 | ||
36 | * ------------------------------------------------- | ||
37 | * |0 0 0 0 0| bus | device | function | reg | 0 0 | | ||
38 | * ------------------------------------------------- | ||
39 | */ | ||
40 | #define FIRE_CONFIG_BASE(PBM) ((PBM)->config_space) | ||
41 | #define FIRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ | ||
42 | (((unsigned long)(BUS) << 20) | \ | ||
43 | ((unsigned long)(DEVFN) << 12) | \ | ||
44 | ((unsigned long)(REG))) | ||
45 | |||
46 | static void *fire_pci_config_mkaddr(struct pci_pbm_info *pbm, | ||
47 | unsigned char bus, | ||
48 | unsigned int devfn, | ||
49 | int where) | ||
50 | { | ||
51 | if (!pbm) | ||
52 | return NULL; | ||
53 | return (void *) | ||
54 | (FIRE_CONFIG_BASE(pbm) | | ||
55 | FIRE_CONFIG_ENCODE(bus, devfn, where)); | ||
56 | } | ||
57 | |||
58 | /* FIRE PCI configuration space accessors. */ | ||
59 | |||
60 | static int fire_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
61 | int where, int size, u32 *value) | ||
62 | { | ||
63 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
64 | unsigned char bus = bus_dev->number; | ||
65 | u32 *addr; | ||
66 | u16 tmp16; | ||
67 | u8 tmp8; | ||
68 | |||
69 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
70 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
71 | size, value); | ||
72 | switch (size) { | ||
73 | case 1: | ||
74 | *value = 0xff; | ||
75 | break; | ||
76 | case 2: | ||
77 | *value = 0xffff; | ||
78 | break; | ||
79 | case 4: | ||
80 | *value = 0xffffffff; | ||
81 | break; | ||
82 | } | ||
83 | |||
84 | addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); | ||
85 | if (!addr) | ||
86 | return PCIBIOS_SUCCESSFUL; | ||
87 | |||
88 | switch (size) { | ||
89 | case 1: | ||
90 | pci_config_read8((u8 *)addr, &tmp8); | ||
91 | *value = tmp8; | ||
92 | break; | ||
93 | |||
94 | case 2: | ||
95 | if (where & 0x01) { | ||
96 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
97 | where); | ||
98 | return PCIBIOS_SUCCESSFUL; | ||
99 | } | ||
100 | pci_config_read16((u16 *)addr, &tmp16); | ||
101 | *value = tmp16; | ||
102 | break; | ||
103 | |||
104 | case 4: | ||
105 | if (where & 0x03) { | ||
106 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
107 | where); | ||
108 | return PCIBIOS_SUCCESSFUL; | ||
109 | } | ||
110 | |||
111 | pci_config_read32(addr, value); | ||
112 | break; | ||
113 | } | ||
114 | return PCIBIOS_SUCCESSFUL; | ||
115 | } | ||
116 | |||
117 | static int fire_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
118 | int where, int size, u32 value) | ||
119 | { | ||
120 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
121 | unsigned char bus = bus_dev->number; | ||
122 | u32 *addr; | ||
123 | |||
124 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
125 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
126 | size, value); | ||
127 | addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); | ||
128 | if (!addr) | ||
129 | return PCIBIOS_SUCCESSFUL; | ||
130 | |||
131 | switch (size) { | ||
132 | case 1: | ||
133 | pci_config_write8((u8 *)addr, value); | ||
134 | break; | ||
135 | |||
136 | case 2: | ||
137 | if (where & 0x01) { | ||
138 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
139 | where); | ||
140 | return PCIBIOS_SUCCESSFUL; | ||
141 | } | ||
142 | pci_config_write16((u16 *)addr, value); | ||
143 | break; | ||
144 | |||
145 | case 4: | ||
146 | if (where & 0x03) { | ||
147 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
148 | where); | ||
149 | return PCIBIOS_SUCCESSFUL; | ||
150 | } | ||
151 | |||
152 | pci_config_write32(addr, value); | ||
153 | } | ||
154 | return PCIBIOS_SUCCESSFUL; | ||
155 | } | ||
156 | |||
157 | static struct pci_ops pci_fire_ops = { | ||
158 | .read = fire_read_pci_cfg, | ||
159 | .write = fire_write_pci_cfg, | ||
160 | }; | ||
161 | |||
162 | static void pci_fire_scan_bus(struct pci_pbm_info *pbm) | 30 | static void pci_fire_scan_bus(struct pci_pbm_info *pbm) |
163 | { | 31 | { |
164 | pbm->pci_bus = pci_scan_one_pbm(pbm); | 32 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
@@ -314,7 +182,8 @@ static void pci_fire_pbm_init(struct pci_controller_info *p, | |||
314 | pci_pbm_root = pbm; | 182 | pci_pbm_root = pbm; |
315 | 183 | ||
316 | pbm->scan_bus = pci_fire_scan_bus; | 184 | pbm->scan_bus = pci_fire_scan_bus; |
317 | pbm->pci_ops = &pci_fire_ops; | 185 | pbm->pci_ops = &sun4u_pci_ops; |
186 | pbm->config_space_reg_bits = 12; | ||
318 | 187 | ||
319 | pbm->index = pci_num_pbms++; | 188 | pbm->index = pci_num_pbms++; |
320 | 189 | ||
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 8e38023868aa..f660c2b685eb 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -77,6 +77,9 @@ struct pci_pbm_info { | |||
77 | /* Base of PCI Config space, can be per-PBM or shared. */ | 77 | /* Base of PCI Config space, can be per-PBM or shared. */ |
78 | unsigned long config_space; | 78 | unsigned long config_space; |
79 | 79 | ||
80 | /* This will be 12 on PCI-E controllers, 8 elsewhere. */ | ||
81 | unsigned long config_space_reg_bits; | ||
82 | |||
80 | /* State of 66MHz capabilities on this PBM. */ | 83 | /* State of 66MHz capabilities on this PBM. */ |
81 | int is_66mhz_capable; | 84 | int is_66mhz_capable; |
82 | int all_devs_66mhz; | 85 | int all_devs_66mhz; |
@@ -156,4 +159,7 @@ extern void pci_config_write8(u8 *addr, u8 val); | |||
156 | extern void pci_config_write16(u16 *addr, u16 val); | 159 | extern void pci_config_write16(u16 *addr, u16 val); |
157 | extern void pci_config_write32(u32 *addr, u32 val); | 160 | extern void pci_config_write32(u32 *addr, u32 val); |
158 | 161 | ||
162 | extern struct pci_ops sun4u_pci_ops; | ||
163 | extern struct pci_ops sun4v_pci_ops; | ||
164 | |||
159 | #endif /* !(PCI_IMPL_H) */ | 165 | #endif /* !(PCI_IMPL_H) */ |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 2edcb1dd13c3..598393a2df16 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -94,122 +94,6 @@ static void *psycho_pci_config_mkaddr(struct pci_pbm_info *pbm, | |||
94 | PSYCHO_CONFIG_ENCODE(bus, devfn, where)); | 94 | PSYCHO_CONFIG_ENCODE(bus, devfn, where)); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int psycho_out_of_range(struct pci_pbm_info *pbm, | ||
98 | unsigned char bus, | ||
99 | unsigned char devfn) | ||
100 | { | ||
101 | return ((bus == pbm->pci_first_busno) && | ||
102 | PCI_SLOT(devfn) > 8); | ||
103 | } | ||
104 | |||
105 | /* PSYCHO PCI configuration space accessors. */ | ||
106 | |||
107 | static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
108 | int where, int size, u32 *value) | ||
109 | { | ||
110 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
111 | unsigned char bus = bus_dev->number; | ||
112 | u32 *addr; | ||
113 | u16 tmp16; | ||
114 | u8 tmp8; | ||
115 | |||
116 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
117 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
118 | size, value); | ||
119 | |||
120 | switch (size) { | ||
121 | case 1: | ||
122 | *value = 0xff; | ||
123 | break; | ||
124 | case 2: | ||
125 | *value = 0xffff; | ||
126 | break; | ||
127 | case 4: | ||
128 | *value = 0xffffffff; | ||
129 | break; | ||
130 | } | ||
131 | |||
132 | addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); | ||
133 | if (!addr) | ||
134 | return PCIBIOS_SUCCESSFUL; | ||
135 | |||
136 | if (psycho_out_of_range(pbm, bus, devfn)) | ||
137 | return PCIBIOS_SUCCESSFUL; | ||
138 | switch (size) { | ||
139 | case 1: | ||
140 | pci_config_read8((u8 *)addr, &tmp8); | ||
141 | *value = (u32) tmp8; | ||
142 | break; | ||
143 | |||
144 | case 2: | ||
145 | if (where & 0x01) { | ||
146 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
147 | where); | ||
148 | return PCIBIOS_SUCCESSFUL; | ||
149 | } | ||
150 | pci_config_read16((u16 *)addr, &tmp16); | ||
151 | *value = (u32) tmp16; | ||
152 | break; | ||
153 | |||
154 | case 4: | ||
155 | if (where & 0x03) { | ||
156 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
157 | where); | ||
158 | return PCIBIOS_SUCCESSFUL; | ||
159 | } | ||
160 | pci_config_read32(addr, value); | ||
161 | break; | ||
162 | } | ||
163 | return PCIBIOS_SUCCESSFUL; | ||
164 | } | ||
165 | |||
166 | static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
167 | int where, int size, u32 value) | ||
168 | { | ||
169 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
170 | unsigned char bus = bus_dev->number; | ||
171 | u32 *addr; | ||
172 | |||
173 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
174 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
175 | size, value); | ||
176 | addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); | ||
177 | if (!addr) | ||
178 | return PCIBIOS_SUCCESSFUL; | ||
179 | |||
180 | if (psycho_out_of_range(pbm, bus, devfn)) | ||
181 | return PCIBIOS_SUCCESSFUL; | ||
182 | |||
183 | switch (size) { | ||
184 | case 1: | ||
185 | pci_config_write8((u8 *)addr, value); | ||
186 | break; | ||
187 | |||
188 | case 2: | ||
189 | if (where & 0x01) { | ||
190 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
191 | where); | ||
192 | return PCIBIOS_SUCCESSFUL; | ||
193 | } | ||
194 | pci_config_write16((u16 *)addr, value); | ||
195 | break; | ||
196 | |||
197 | case 4: | ||
198 | if (where & 0x03) { | ||
199 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
200 | where); | ||
201 | return PCIBIOS_SUCCESSFUL; | ||
202 | } | ||
203 | pci_config_write32(addr, value); | ||
204 | } | ||
205 | return PCIBIOS_SUCCESSFUL; | ||
206 | } | ||
207 | |||
208 | static struct pci_ops psycho_ops = { | ||
209 | .read = psycho_read_pci_cfg, | ||
210 | .write = psycho_write_pci_cfg, | ||
211 | }; | ||
212 | |||
213 | /* PSYCHO error handling support. */ | 97 | /* PSYCHO error handling support. */ |
214 | enum psycho_error_type { | 98 | enum psycho_error_type { |
215 | UE_ERR, CE_ERR, PCI_ERR | 99 | UE_ERR, CE_ERR, PCI_ERR |
@@ -1089,7 +973,8 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1089 | pci_pbm_root = pbm; | 973 | pci_pbm_root = pbm; |
1090 | 974 | ||
1091 | pbm->scan_bus = psycho_scan_bus; | 975 | pbm->scan_bus = psycho_scan_bus; |
1092 | pbm->pci_ops = &psycho_ops; | 976 | pbm->pci_ops = &sun4u_pci_ops; |
977 | pbm->config_space_reg_bits = 8; | ||
1093 | 978 | ||
1094 | pbm->index = pci_num_pbms++; | 979 | pbm->index = pci_num_pbms++; |
1095 | 980 | ||
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 4cefe6e83b24..e2377796de89 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -205,294 +205,9 @@ | |||
205 | #define SABRE_MEMSPACE 0x100000000UL | 205 | #define SABRE_MEMSPACE 0x100000000UL |
206 | #define SABRE_MEMSPACE_SIZE 0x07fffffffUL | 206 | #define SABRE_MEMSPACE_SIZE 0x07fffffffUL |
207 | 207 | ||
208 | /* UltraSparc-IIi Programmer's Manual, page 325, PCI | ||
209 | * configuration space address format: | ||
210 | * | ||
211 | * 32 24 23 16 15 11 10 8 7 2 1 0 | ||
212 | * --------------------------------------------------------- | ||
213 | * |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 | | ||
214 | * --------------------------------------------------------- | ||
215 | */ | ||
216 | #define SABRE_CONFIG_BASE(PBM) \ | ||
217 | ((PBM)->config_space | (1UL << 24)) | ||
218 | #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ | ||
219 | (((unsigned long)(BUS) << 16) | \ | ||
220 | ((unsigned long)(DEVFN) << 8) | \ | ||
221 | ((unsigned long)(REG))) | ||
222 | |||
223 | static int hummingbird_p; | 208 | static int hummingbird_p; |
224 | static struct pci_bus *sabre_root_bus; | 209 | static struct pci_bus *sabre_root_bus; |
225 | 210 | ||
226 | static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm, | ||
227 | unsigned char bus, | ||
228 | unsigned int devfn, | ||
229 | int where) | ||
230 | { | ||
231 | if (!pbm) | ||
232 | return NULL; | ||
233 | return (void *) | ||
234 | (SABRE_CONFIG_BASE(pbm) | | ||
235 | SABRE_CONFIG_ENCODE(bus, devfn, where)); | ||
236 | } | ||
237 | |||
238 | static int sabre_out_of_range(unsigned char devfn) | ||
239 | { | ||
240 | if (hummingbird_p) | ||
241 | return 0; | ||
242 | |||
243 | return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) || | ||
244 | ((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) || | ||
245 | (PCI_SLOT(devfn) > 1)); | ||
246 | } | ||
247 | |||
248 | static int __sabre_out_of_range(struct pci_pbm_info *pbm, | ||
249 | unsigned char bus, | ||
250 | unsigned char devfn) | ||
251 | { | ||
252 | if (hummingbird_p) | ||
253 | return 0; | ||
254 | |||
255 | return ((pbm->parent == 0) || | ||
256 | ((pbm == &pbm->parent->pbm_A) && | ||
257 | (bus == pbm->pci_first_busno) && | ||
258 | PCI_SLOT(devfn) > 8)); | ||
259 | } | ||
260 | |||
261 | static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
262 | int where, int size, u32 *value) | ||
263 | { | ||
264 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
265 | unsigned char bus = bus_dev->number; | ||
266 | u32 *addr; | ||
267 | u16 tmp16; | ||
268 | u8 tmp8; | ||
269 | |||
270 | switch (size) { | ||
271 | case 1: | ||
272 | *value = 0xff; | ||
273 | break; | ||
274 | case 2: | ||
275 | *value = 0xffff; | ||
276 | break; | ||
277 | case 4: | ||
278 | *value = 0xffffffff; | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); | ||
283 | if (!addr) | ||
284 | return PCIBIOS_SUCCESSFUL; | ||
285 | |||
286 | if (__sabre_out_of_range(pbm, bus, devfn)) | ||
287 | return PCIBIOS_SUCCESSFUL; | ||
288 | |||
289 | switch (size) { | ||
290 | case 1: | ||
291 | pci_config_read8((u8 *) addr, &tmp8); | ||
292 | *value = tmp8; | ||
293 | break; | ||
294 | |||
295 | case 2: | ||
296 | if (where & 0x01) { | ||
297 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
298 | where); | ||
299 | return PCIBIOS_SUCCESSFUL; | ||
300 | } | ||
301 | pci_config_read16((u16 *) addr, &tmp16); | ||
302 | *value = tmp16; | ||
303 | break; | ||
304 | |||
305 | case 4: | ||
306 | if (where & 0x03) { | ||
307 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
308 | where); | ||
309 | return PCIBIOS_SUCCESSFUL; | ||
310 | } | ||
311 | pci_config_read32(addr, value); | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | return PCIBIOS_SUCCESSFUL; | ||
316 | } | ||
317 | |||
318 | static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, | ||
319 | int where, int size, u32 *value) | ||
320 | { | ||
321 | struct pci_pbm_info *pbm = bus->sysdata; | ||
322 | |||
323 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
324 | return pci_host_bridge_read_pci_cfg(bus, devfn, where, | ||
325 | size, value); | ||
326 | |||
327 | if (!bus->number && sabre_out_of_range(devfn)) { | ||
328 | switch (size) { | ||
329 | case 1: | ||
330 | *value = 0xff; | ||
331 | break; | ||
332 | case 2: | ||
333 | *value = 0xffff; | ||
334 | break; | ||
335 | case 4: | ||
336 | *value = 0xffffffff; | ||
337 | break; | ||
338 | } | ||
339 | return PCIBIOS_SUCCESSFUL; | ||
340 | } | ||
341 | |||
342 | if (bus->number || PCI_SLOT(devfn)) | ||
343 | return __sabre_read_pci_cfg(bus, devfn, where, size, value); | ||
344 | |||
345 | /* When accessing PCI config space of the PCI controller itself (bus | ||
346 | * 0, device slot 0, function 0) there are restrictions. Each | ||
347 | * register must be accessed as it's natural size. Thus, for example | ||
348 | * the Vendor ID must be accessed as a 16-bit quantity. | ||
349 | */ | ||
350 | |||
351 | switch (size) { | ||
352 | case 1: | ||
353 | if (where < 8) { | ||
354 | u32 tmp32; | ||
355 | u16 tmp16; | ||
356 | |||
357 | __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32); | ||
358 | tmp16 = (u16) tmp32; | ||
359 | if (where & 1) | ||
360 | *value = tmp16 >> 8; | ||
361 | else | ||
362 | *value = tmp16 & 0xff; | ||
363 | } else | ||
364 | return __sabre_read_pci_cfg(bus, devfn, where, 1, value); | ||
365 | break; | ||
366 | |||
367 | case 2: | ||
368 | if (where < 8) | ||
369 | return __sabre_read_pci_cfg(bus, devfn, where, 2, value); | ||
370 | else { | ||
371 | u32 tmp32; | ||
372 | u8 tmp8; | ||
373 | |||
374 | __sabre_read_pci_cfg(bus, devfn, where, 1, &tmp32); | ||
375 | tmp8 = (u8) tmp32; | ||
376 | *value = tmp8; | ||
377 | __sabre_read_pci_cfg(bus, devfn, where + 1, 1, &tmp32); | ||
378 | tmp8 = (u8) tmp32; | ||
379 | *value |= tmp8 << 8; | ||
380 | } | ||
381 | break; | ||
382 | |||
383 | case 4: { | ||
384 | u32 tmp32; | ||
385 | u16 tmp16; | ||
386 | |||
387 | sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32); | ||
388 | tmp16 = (u16) tmp32; | ||
389 | *value = tmp16; | ||
390 | sabre_read_pci_cfg(bus, devfn, where + 2, 2, &tmp32); | ||
391 | tmp16 = (u16) tmp32; | ||
392 | *value |= tmp16 << 16; | ||
393 | break; | ||
394 | } | ||
395 | } | ||
396 | return PCIBIOS_SUCCESSFUL; | ||
397 | } | ||
398 | |||
399 | static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
400 | int where, int size, u32 value) | ||
401 | { | ||
402 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
403 | unsigned char bus = bus_dev->number; | ||
404 | u32 *addr; | ||
405 | |||
406 | addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); | ||
407 | if (!addr) | ||
408 | return PCIBIOS_SUCCESSFUL; | ||
409 | |||
410 | if (__sabre_out_of_range(pbm, bus, devfn)) | ||
411 | return PCIBIOS_SUCCESSFUL; | ||
412 | |||
413 | switch (size) { | ||
414 | case 1: | ||
415 | pci_config_write8((u8 *) addr, value); | ||
416 | break; | ||
417 | |||
418 | case 2: | ||
419 | if (where & 0x01) { | ||
420 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
421 | where); | ||
422 | return PCIBIOS_SUCCESSFUL; | ||
423 | } | ||
424 | pci_config_write16((u16 *) addr, value); | ||
425 | break; | ||
426 | |||
427 | case 4: | ||
428 | if (where & 0x03) { | ||
429 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
430 | where); | ||
431 | return PCIBIOS_SUCCESSFUL; | ||
432 | } | ||
433 | pci_config_write32(addr, value); | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | return PCIBIOS_SUCCESSFUL; | ||
438 | } | ||
439 | |||
440 | static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, | ||
441 | int where, int size, u32 value) | ||
442 | { | ||
443 | struct pci_pbm_info *pbm = bus->sysdata; | ||
444 | |||
445 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
446 | return pci_host_bridge_write_pci_cfg(bus, devfn, where, | ||
447 | size, value); | ||
448 | |||
449 | if (bus->number) | ||
450 | return __sabre_write_pci_cfg(bus, devfn, where, size, value); | ||
451 | |||
452 | if (sabre_out_of_range(devfn)) | ||
453 | return PCIBIOS_SUCCESSFUL; | ||
454 | |||
455 | switch (size) { | ||
456 | case 1: | ||
457 | if (where < 8) { | ||
458 | u32 tmp32; | ||
459 | u16 tmp16; | ||
460 | |||
461 | __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32); | ||
462 | tmp16 = (u16) tmp32; | ||
463 | if (where & 1) { | ||
464 | value &= 0x00ff; | ||
465 | value |= tmp16 << 8; | ||
466 | } else { | ||
467 | value &= 0xff00; | ||
468 | value |= tmp16; | ||
469 | } | ||
470 | tmp32 = (u32) tmp16; | ||
471 | return __sabre_write_pci_cfg(bus, devfn, where & ~1, 2, tmp32); | ||
472 | } else | ||
473 | return __sabre_write_pci_cfg(bus, devfn, where, 1, value); | ||
474 | break; | ||
475 | case 2: | ||
476 | if (where < 8) | ||
477 | return __sabre_write_pci_cfg(bus, devfn, where, 2, value); | ||
478 | else { | ||
479 | __sabre_write_pci_cfg(bus, devfn, where, 1, value & 0xff); | ||
480 | __sabre_write_pci_cfg(bus, devfn, where + 1, 1, value >> 8); | ||
481 | } | ||
482 | break; | ||
483 | case 4: | ||
484 | sabre_write_pci_cfg(bus, devfn, where, 2, value & 0xffff); | ||
485 | sabre_write_pci_cfg(bus, devfn, where + 2, 2, value >> 16); | ||
486 | break; | ||
487 | } | ||
488 | return PCIBIOS_SUCCESSFUL; | ||
489 | } | ||
490 | |||
491 | static struct pci_ops sabre_ops = { | ||
492 | .read = sabre_read_pci_cfg, | ||
493 | .write = sabre_write_pci_cfg, | ||
494 | }; | ||
495 | |||
496 | /* SABRE error handling support. */ | 211 | /* SABRE error handling support. */ |
497 | static void sabre_check_iommu_error(struct pci_pbm_info *pbm, | 212 | static void sabre_check_iommu_error(struct pci_pbm_info *pbm, |
498 | unsigned long afsr, | 213 | unsigned long afsr, |
@@ -1010,7 +725,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *p | |||
1010 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | 725 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
1011 | 726 | ||
1012 | pbm->scan_bus = sabre_scan_bus; | 727 | pbm->scan_bus = sabre_scan_bus; |
1013 | pbm->pci_ops = &sabre_ops; | 728 | pbm->pci_ops = &sun4u_pci_ops; |
729 | pbm->config_space_reg_bits = 8; | ||
1014 | 730 | ||
1015 | pbm->index = pci_num_pbms++; | 731 | pbm->index = pci_num_pbms++; |
1016 | 732 | ||
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e375d72b8eed..ae76898bbe2b 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -104,125 +104,6 @@ static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm, | |||
104 | SCHIZO_CONFIG_ENCODE(bus, devfn, where)); | 104 | SCHIZO_CONFIG_ENCODE(bus, devfn, where)); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* Just make sure the bus number is in range. */ | ||
108 | static int schizo_out_of_range(struct pci_pbm_info *pbm, | ||
109 | unsigned char bus, | ||
110 | unsigned char devfn) | ||
111 | { | ||
112 | if (bus < pbm->pci_first_busno || | ||
113 | bus > pbm->pci_last_busno) | ||
114 | return 1; | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | /* SCHIZO PCI configuration space accessors. */ | ||
119 | |||
120 | static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
121 | int where, int size, u32 *value) | ||
122 | { | ||
123 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
124 | unsigned char bus = bus_dev->number; | ||
125 | u32 *addr; | ||
126 | u16 tmp16; | ||
127 | u8 tmp8; | ||
128 | |||
129 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
130 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
131 | size, value); | ||
132 | switch (size) { | ||
133 | case 1: | ||
134 | *value = 0xff; | ||
135 | break; | ||
136 | case 2: | ||
137 | *value = 0xffff; | ||
138 | break; | ||
139 | case 4: | ||
140 | *value = 0xffffffff; | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); | ||
145 | if (!addr) | ||
146 | return PCIBIOS_SUCCESSFUL; | ||
147 | |||
148 | if (schizo_out_of_range(pbm, bus, devfn)) | ||
149 | return PCIBIOS_SUCCESSFUL; | ||
150 | switch (size) { | ||
151 | case 1: | ||
152 | pci_config_read8((u8 *)addr, &tmp8); | ||
153 | *value = tmp8; | ||
154 | break; | ||
155 | |||
156 | case 2: | ||
157 | if (where & 0x01) { | ||
158 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
159 | where); | ||
160 | return PCIBIOS_SUCCESSFUL; | ||
161 | } | ||
162 | pci_config_read16((u16 *)addr, &tmp16); | ||
163 | *value = tmp16; | ||
164 | break; | ||
165 | |||
166 | case 4: | ||
167 | if (where & 0x03) { | ||
168 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
169 | where); | ||
170 | return PCIBIOS_SUCCESSFUL; | ||
171 | } | ||
172 | pci_config_read32(addr, value); | ||
173 | break; | ||
174 | } | ||
175 | return PCIBIOS_SUCCESSFUL; | ||
176 | } | ||
177 | |||
178 | static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
179 | int where, int size, u32 value) | ||
180 | { | ||
181 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
182 | unsigned char bus = bus_dev->number; | ||
183 | u32 *addr; | ||
184 | |||
185 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
186 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
187 | size, value); | ||
188 | addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); | ||
189 | if (!addr) | ||
190 | return PCIBIOS_SUCCESSFUL; | ||
191 | |||
192 | if (schizo_out_of_range(pbm, bus, devfn)) | ||
193 | return PCIBIOS_SUCCESSFUL; | ||
194 | |||
195 | switch (size) { | ||
196 | case 1: | ||
197 | pci_config_write8((u8 *)addr, value); | ||
198 | break; | ||
199 | |||
200 | case 2: | ||
201 | if (where & 0x01) { | ||
202 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
203 | where); | ||
204 | return PCIBIOS_SUCCESSFUL; | ||
205 | } | ||
206 | pci_config_write16((u16 *)addr, value); | ||
207 | break; | ||
208 | |||
209 | case 4: | ||
210 | if (where & 0x03) { | ||
211 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
212 | where); | ||
213 | return PCIBIOS_SUCCESSFUL; | ||
214 | } | ||
215 | |||
216 | pci_config_write32(addr, value); | ||
217 | } | ||
218 | return PCIBIOS_SUCCESSFUL; | ||
219 | } | ||
220 | |||
221 | static struct pci_ops schizo_ops = { | ||
222 | .read = schizo_read_pci_cfg, | ||
223 | .write = schizo_write_pci_cfg, | ||
224 | }; | ||
225 | |||
226 | /* SCHIZO error handling support. */ | 107 | /* SCHIZO error handling support. */ |
227 | enum schizo_error_type { | 108 | enum schizo_error_type { |
228 | UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR | 109 | UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR |
@@ -1494,7 +1375,8 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1494 | pci_pbm_root = pbm; | 1375 | pci_pbm_root = pbm; |
1495 | 1376 | ||
1496 | pbm->scan_bus = schizo_scan_bus; | 1377 | pbm->scan_bus = schizo_scan_bus; |
1497 | pbm->pci_ops = &schizo_ops; | 1378 | pbm->pci_ops = &sun4u_pci_ops; |
1379 | pbm->config_space_reg_bits = 8; | ||
1498 | 1380 | ||
1499 | pbm->index = pci_num_pbms++; | 1381 | pbm->index = pci_num_pbms++; |
1500 | 1382 | ||
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 0c76a8891a96..34df4047587a 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -593,89 +593,6 @@ const struct pci_iommu_ops pci_sun4v_iommu_ops = { | |||
593 | .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu, | 593 | .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu, |
594 | }; | 594 | }; |
595 | 595 | ||
596 | static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) | ||
597 | { | ||
598 | if (bus < pbm->pci_first_busno || | ||
599 | bus > pbm->pci_last_busno) | ||
600 | return 1; | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
605 | int where, int size, u32 *value) | ||
606 | { | ||
607 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
608 | u32 devhandle = pbm->devhandle; | ||
609 | unsigned int bus = bus_dev->number; | ||
610 | unsigned int device = PCI_SLOT(devfn); | ||
611 | unsigned int func = PCI_FUNC(devfn); | ||
612 | unsigned long ret; | ||
613 | |||
614 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
615 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
616 | size, value); | ||
617 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { | ||
618 | ret = ~0UL; | ||
619 | } else { | ||
620 | ret = pci_sun4v_config_get(devhandle, | ||
621 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
622 | where, size); | ||
623 | #if 0 | ||
624 | printk("rcfg: [%x:%x:%x:%d]=[%lx]\n", | ||
625 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), | ||
626 | where, size, ret); | ||
627 | #endif | ||
628 | } | ||
629 | switch (size) { | ||
630 | case 1: | ||
631 | *value = ret & 0xff; | ||
632 | break; | ||
633 | case 2: | ||
634 | *value = ret & 0xffff; | ||
635 | break; | ||
636 | case 4: | ||
637 | *value = ret & 0xffffffff; | ||
638 | break; | ||
639 | }; | ||
640 | |||
641 | |||
642 | return PCIBIOS_SUCCESSFUL; | ||
643 | } | ||
644 | |||
645 | static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
646 | int where, int size, u32 value) | ||
647 | { | ||
648 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
649 | u32 devhandle = pbm->devhandle; | ||
650 | unsigned int bus = bus_dev->number; | ||
651 | unsigned int device = PCI_SLOT(devfn); | ||
652 | unsigned int func = PCI_FUNC(devfn); | ||
653 | unsigned long ret; | ||
654 | |||
655 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
656 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
657 | size, value); | ||
658 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { | ||
659 | /* Do nothing. */ | ||
660 | } else { | ||
661 | ret = pci_sun4v_config_put(devhandle, | ||
662 | HV_PCI_DEVICE_BUILD(bus, device, func), | ||
663 | where, size, value); | ||
664 | #if 0 | ||
665 | printk("wcfg: [%x:%x:%x:%d] v[%x] == [%lx]\n", | ||
666 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), | ||
667 | where, size, value, ret); | ||
668 | #endif | ||
669 | } | ||
670 | return PCIBIOS_SUCCESSFUL; | ||
671 | } | ||
672 | |||
673 | static struct pci_ops pci_sun4v_ops = { | ||
674 | .read = pci_sun4v_read_pci_cfg, | ||
675 | .write = pci_sun4v_write_pci_cfg, | ||
676 | }; | ||
677 | |||
678 | |||
679 | static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) | 596 | static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) |
680 | { | 597 | { |
681 | struct property *prop; | 598 | struct property *prop; |
@@ -1238,7 +1155,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1238 | pci_pbm_root = pbm; | 1155 | pci_pbm_root = pbm; |
1239 | 1156 | ||
1240 | pbm->scan_bus = pci_sun4v_scan_bus; | 1157 | pbm->scan_bus = pci_sun4v_scan_bus; |
1241 | pbm->pci_ops = &pci_sun4v_ops; | 1158 | pbm->pci_ops = &sun4v_pci_ops; |
1159 | pbm->config_space_reg_bits = 12; | ||
1242 | 1160 | ||
1243 | pbm->index = pci_num_pbms++; | 1161 | pbm->index = pci_num_pbms++; |
1244 | 1162 | ||
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c54d4d8af014..b7976b14d0ba 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -1636,10 +1636,21 @@ static struct device_node * __init create_node(phandle node, struct device_node | |||
1636 | 1636 | ||
1637 | static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) | 1637 | static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) |
1638 | { | 1638 | { |
1639 | struct device_node *ret = NULL, *prev_sibling = NULL; | ||
1639 | struct device_node *dp; | 1640 | struct device_node *dp; |
1640 | 1641 | ||
1641 | dp = create_node(node, parent); | 1642 | while (1) { |
1642 | if (dp) { | 1643 | dp = create_node(node, parent); |
1644 | if (!dp) | ||
1645 | break; | ||
1646 | |||
1647 | if (prev_sibling) | ||
1648 | prev_sibling->sibling = dp; | ||
1649 | |||
1650 | if (!ret) | ||
1651 | ret = dp; | ||
1652 | prev_sibling = dp; | ||
1653 | |||
1643 | *(*nextp) = dp; | 1654 | *(*nextp) = dp; |
1644 | *nextp = &dp->allnext; | 1655 | *nextp = &dp->allnext; |
1645 | 1656 | ||
@@ -1648,10 +1659,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl | |||
1648 | 1659 | ||
1649 | dp->child = build_tree(dp, prom_getchild(node), nextp); | 1660 | dp->child = build_tree(dp, prom_getchild(node), nextp); |
1650 | 1661 | ||
1651 | dp->sibling = build_tree(parent, prom_getsibling(node), nextp); | 1662 | node = prom_getsibling(node); |
1652 | } | 1663 | } |
1653 | 1664 | ||
1654 | return dp; | 1665 | return ret; |
1655 | } | 1666 | } |
1656 | 1667 | ||
1657 | void __init prom_build_devicetree(void) | 1668 | void __init prom_build_devicetree(void) |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index da73205e54cd..0985193dc57d 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -92,6 +92,8 @@ struct uart_sunzilog_port { | |||
92 | #define SUNZILOG_FLAG_REGS_HELD 0x00000040 | 92 | #define SUNZILOG_FLAG_REGS_HELD 0x00000040 |
93 | #define SUNZILOG_FLAG_TX_STOPPED 0x00000080 | 93 | #define SUNZILOG_FLAG_TX_STOPPED 0x00000080 |
94 | #define SUNZILOG_FLAG_TX_ACTIVE 0x00000100 | 94 | #define SUNZILOG_FLAG_TX_ACTIVE 0x00000100 |
95 | #define SUNZILOG_FLAG_ESCC 0x00000200 | ||
96 | #define SUNZILOG_FLAG_ISR_HANDLER 0x00000400 | ||
95 | 97 | ||
96 | unsigned int cflag; | 98 | unsigned int cflag; |
97 | 99 | ||
@@ -174,9 +176,11 @@ static void sunzilog_clear_fifo(struct zilog_channel __iomem *channel) | |||
174 | /* This function must only be called when the TX is not busy. The UART | 176 | /* This function must only be called when the TX is not busy. The UART |
175 | * port lock must be held and local interrupts disabled. | 177 | * port lock must be held and local interrupts disabled. |
176 | */ | 178 | */ |
177 | static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs) | 179 | static int __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs) |
178 | { | 180 | { |
179 | int i; | 181 | int i; |
182 | int escc; | ||
183 | unsigned char r15; | ||
180 | 184 | ||
181 | /* Let pending transmits finish. */ | 185 | /* Let pending transmits finish. */ |
182 | for (i = 0; i < 1000; i++) { | 186 | for (i = 0; i < 1000; i++) { |
@@ -229,11 +233,25 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char * | |||
229 | write_zsreg(channel, R14, regs[R14]); | 233 | write_zsreg(channel, R14, regs[R14]); |
230 | 234 | ||
231 | /* External status interrupt control. */ | 235 | /* External status interrupt control. */ |
232 | write_zsreg(channel, R15, regs[R15]); | 236 | write_zsreg(channel, R15, (regs[R15] | WR7pEN) & ~FIFOEN); |
237 | |||
238 | /* ESCC Extension Register */ | ||
239 | r15 = read_zsreg(channel, R15); | ||
240 | if (r15 & 0x01) { | ||
241 | write_zsreg(channel, R7, regs[R7p]); | ||
242 | |||
243 | /* External status interrupt and FIFO control. */ | ||
244 | write_zsreg(channel, R15, regs[R15] & ~WR7pEN); | ||
245 | escc = 1; | ||
246 | } else { | ||
247 | /* Clear FIFO bit case it is an issue */ | ||
248 | regs[R15] &= ~FIFOEN; | ||
249 | escc = 0; | ||
250 | } | ||
233 | 251 | ||
234 | /* Reset external status interrupts. */ | 252 | /* Reset external status interrupts. */ |
235 | write_zsreg(channel, R0, RES_EXT_INT); | 253 | write_zsreg(channel, R0, RES_EXT_INT); /* First Latch */ |
236 | write_zsreg(channel, R0, RES_EXT_INT); | 254 | write_zsreg(channel, R0, RES_EXT_INT); /* Second Latch */ |
237 | 255 | ||
238 | /* Rewrite R3/R5, this time without enables masked. */ | 256 | /* Rewrite R3/R5, this time without enables masked. */ |
239 | write_zsreg(channel, R3, regs[R3]); | 257 | write_zsreg(channel, R3, regs[R3]); |
@@ -241,6 +259,8 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char * | |||
241 | 259 | ||
242 | /* Rewrite R1, this time without IRQ enabled masked. */ | 260 | /* Rewrite R1, this time without IRQ enabled masked. */ |
243 | write_zsreg(channel, R1, regs[R1]); | 261 | write_zsreg(channel, R1, regs[R1]); |
262 | |||
263 | return escc; | ||
244 | } | 264 | } |
245 | 265 | ||
246 | /* Reprogram the Zilog channel HW registers with the copies found in the | 266 | /* Reprogram the Zilog channel HW registers with the copies found in the |
@@ -731,7 +751,7 @@ static void sunzilog_enable_ms(struct uart_port *port) | |||
731 | up->curregs[R15] = new_reg; | 751 | up->curregs[R15] = new_reg; |
732 | 752 | ||
733 | /* NOTE: Not subject to 'transmitter active' rule. */ | 753 | /* NOTE: Not subject to 'transmitter active' rule. */ |
734 | write_zsreg(channel, R15, up->curregs[R15]); | 754 | write_zsreg(channel, R15, up->curregs[R15] & ~WR7pEN); |
735 | } | 755 | } |
736 | } | 756 | } |
737 | 757 | ||
@@ -861,44 +881,44 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag, | |||
861 | up->curregs[R14] = BRSRC | BRENAB; | 881 | up->curregs[R14] = BRSRC | BRENAB; |
862 | 882 | ||
863 | /* Character size, stop bits, and parity. */ | 883 | /* Character size, stop bits, and parity. */ |
864 | up->curregs[3] &= ~RxN_MASK; | 884 | up->curregs[R3] &= ~RxN_MASK; |
865 | up->curregs[5] &= ~TxN_MASK; | 885 | up->curregs[R5] &= ~TxN_MASK; |
866 | switch (cflag & CSIZE) { | 886 | switch (cflag & CSIZE) { |
867 | case CS5: | 887 | case CS5: |
868 | up->curregs[3] |= Rx5; | 888 | up->curregs[R3] |= Rx5; |
869 | up->curregs[5] |= Tx5; | 889 | up->curregs[R5] |= Tx5; |
870 | up->parity_mask = 0x1f; | 890 | up->parity_mask = 0x1f; |
871 | break; | 891 | break; |
872 | case CS6: | 892 | case CS6: |
873 | up->curregs[3] |= Rx6; | 893 | up->curregs[R3] |= Rx6; |
874 | up->curregs[5] |= Tx6; | 894 | up->curregs[R5] |= Tx6; |
875 | up->parity_mask = 0x3f; | 895 | up->parity_mask = 0x3f; |
876 | break; | 896 | break; |
877 | case CS7: | 897 | case CS7: |
878 | up->curregs[3] |= Rx7; | 898 | up->curregs[R3] |= Rx7; |
879 | up->curregs[5] |= Tx7; | 899 | up->curregs[R5] |= Tx7; |
880 | up->parity_mask = 0x7f; | 900 | up->parity_mask = 0x7f; |
881 | break; | 901 | break; |
882 | case CS8: | 902 | case CS8: |
883 | default: | 903 | default: |
884 | up->curregs[3] |= Rx8; | 904 | up->curregs[R3] |= Rx8; |
885 | up->curregs[5] |= Tx8; | 905 | up->curregs[R5] |= Tx8; |
886 | up->parity_mask = 0xff; | 906 | up->parity_mask = 0xff; |
887 | break; | 907 | break; |
888 | }; | 908 | }; |
889 | up->curregs[4] &= ~0x0c; | 909 | up->curregs[R4] &= ~0x0c; |
890 | if (cflag & CSTOPB) | 910 | if (cflag & CSTOPB) |
891 | up->curregs[4] |= SB2; | 911 | up->curregs[R4] |= SB2; |
892 | else | 912 | else |
893 | up->curregs[4] |= SB1; | 913 | up->curregs[R4] |= SB1; |
894 | if (cflag & PARENB) | 914 | if (cflag & PARENB) |
895 | up->curregs[4] |= PAR_ENAB; | 915 | up->curregs[R4] |= PAR_ENAB; |
896 | else | 916 | else |
897 | up->curregs[4] &= ~PAR_ENAB; | 917 | up->curregs[R4] &= ~PAR_ENAB; |
898 | if (!(cflag & PARODD)) | 918 | if (!(cflag & PARODD)) |
899 | up->curregs[4] |= PAR_EVEN; | 919 | up->curregs[R4] |= PAR_EVEN; |
900 | else | 920 | else |
901 | up->curregs[4] &= ~PAR_EVEN; | 921 | up->curregs[R4] &= ~PAR_EVEN; |
902 | 922 | ||
903 | up->port.read_status_mask = Rx_OVR; | 923 | up->port.read_status_mask = Rx_OVR; |
904 | if (iflag & INPCK) | 924 | if (iflag & INPCK) |
@@ -952,7 +972,9 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, | |||
952 | 972 | ||
953 | static const char *sunzilog_type(struct uart_port *port) | 973 | static const char *sunzilog_type(struct uart_port *port) |
954 | { | 974 | { |
955 | return "zs"; | 975 | struct uart_sunzilog_port *up = UART_ZILOG(port); |
976 | |||
977 | return (up->flags & SUNZILOG_FLAG_ESCC) ? "zs (ESCC)" : "zs"; | ||
956 | } | 978 | } |
957 | 979 | ||
958 | /* We do not request/release mappings of the registers here, this | 980 | /* We do not request/release mappings of the registers here, this |
@@ -1170,7 +1192,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1170 | 1192 | ||
1171 | spin_lock_irqsave(&up->port.lock, flags); | 1193 | spin_lock_irqsave(&up->port.lock, flags); |
1172 | 1194 | ||
1173 | up->curregs[R15] = BRKIE; | 1195 | up->curregs[R15] |= BRKIE; |
1174 | sunzilog_convert_to_zs(up, con->cflag, 0, brg); | 1196 | sunzilog_convert_to_zs(up, con->cflag, 0, brg); |
1175 | 1197 | ||
1176 | sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); | 1198 | sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); |
@@ -1229,7 +1251,7 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe | |||
1229 | baud = 4800; | 1251 | baud = 4800; |
1230 | } | 1252 | } |
1231 | 1253 | ||
1232 | up->curregs[R15] = BRKIE; | 1254 | up->curregs[R15] |= BRKIE; |
1233 | brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); | 1255 | brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); |
1234 | sunzilog_convert_to_zs(up, up->cflag, 0, brg); | 1256 | sunzilog_convert_to_zs(up, up->cflag, 0, brg); |
1235 | sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); | 1257 | sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); |
@@ -1283,8 +1305,18 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1283 | 1305 | ||
1284 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | | 1306 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | |
1285 | SUNZILOG_FLAG_CONS_MOUSE)) { | 1307 | SUNZILOG_FLAG_CONS_MOUSE)) { |
1308 | up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; | ||
1309 | up->curregs[R4] = PAR_EVEN | X16CLK | SB1; | ||
1310 | up->curregs[R3] = RxENAB | Rx8; | ||
1311 | up->curregs[R5] = TxENAB | Tx8; | ||
1312 | up->curregs[R6] = 0x00; /* SDLC Address */ | ||
1313 | up->curregs[R7] = 0x7E; /* SDLC Flag */ | ||
1314 | up->curregs[R9] = NV; | ||
1315 | up->curregs[R7p] = 0x00; | ||
1286 | sunzilog_init_kbdms(up, up->port.line); | 1316 | sunzilog_init_kbdms(up, up->port.line); |
1287 | up->curregs[R9] |= (NV | MIE); | 1317 | /* Only enable interrupts if an ISR handler available */ |
1318 | if (up->flags & SUNZILOG_FLAG_ISR_HANDLER) | ||
1319 | up->curregs[R9] |= MIE; | ||
1288 | write_zsreg(channel, R9, up->curregs[R9]); | 1320 | write_zsreg(channel, R9, up->curregs[R9]); |
1289 | } else { | 1321 | } else { |
1290 | /* Normal serial TTY. */ | 1322 | /* Normal serial TTY. */ |
@@ -1293,7 +1325,9 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1293 | up->curregs[R4] = PAR_EVEN | X16CLK | SB1; | 1325 | up->curregs[R4] = PAR_EVEN | X16CLK | SB1; |
1294 | up->curregs[R3] = RxENAB | Rx8; | 1326 | up->curregs[R3] = RxENAB | Rx8; |
1295 | up->curregs[R5] = TxENAB | Tx8; | 1327 | up->curregs[R5] = TxENAB | Tx8; |
1296 | up->curregs[R9] = NV | MIE; | 1328 | up->curregs[R6] = 0x00; /* SDLC Address */ |
1329 | up->curregs[R7] = 0x7E; /* SDLC Flag */ | ||
1330 | up->curregs[R9] = NV; | ||
1297 | up->curregs[R10] = NRZ; | 1331 | up->curregs[R10] = NRZ; |
1298 | up->curregs[R11] = TCBR | RCBR; | 1332 | up->curregs[R11] = TCBR | RCBR; |
1299 | baud = 9600; | 1333 | baud = 9600; |
@@ -1301,7 +1335,14 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1301 | up->curregs[R12] = (brg & 0xff); | 1335 | up->curregs[R12] = (brg & 0xff); |
1302 | up->curregs[R13] = (brg >> 8) & 0xff; | 1336 | up->curregs[R13] = (brg >> 8) & 0xff; |
1303 | up->curregs[R14] = BRSRC | BRENAB; | 1337 | up->curregs[R14] = BRSRC | BRENAB; |
1304 | __load_zsregs(channel, up->curregs); | 1338 | up->curregs[R15] = FIFOEN; /* Use FIFO if on ESCC */ |
1339 | up->curregs[R7p] = TxFIFO_LVL | RxFIFO_LVL; | ||
1340 | if (__load_zsregs(channel, up->curregs)) { | ||
1341 | up->flags |= SUNZILOG_FLAG_ESCC; | ||
1342 | } | ||
1343 | /* Only enable interrupts if an ISR handler available */ | ||
1344 | if (up->flags & SUNZILOG_FLAG_ISR_HANDLER) | ||
1345 | up->curregs[R9] |= MIE; | ||
1305 | write_zsreg(channel, R9, up->curregs[R9]); | 1346 | write_zsreg(channel, R9, up->curregs[R9]); |
1306 | } | 1347 | } |
1307 | 1348 | ||
@@ -1390,12 +1431,14 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1390 | return err; | 1431 | return err; |
1391 | } | 1432 | } |
1392 | } else { | 1433 | } else { |
1393 | printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) " | 1434 | printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) " |
1394 | "is a zs\n", | 1435 | "is a %s\n", |
1395 | op->dev.bus_id, up[0].port.mapbase, op->irqs[0]); | 1436 | op->dev.bus_id, up[0].port.mapbase, op->irqs[0], |
1396 | printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) " | 1437 | sunzilog_type (&up[0].port)); |
1397 | "is a zs\n", | 1438 | printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) " |
1398 | op->dev.bus_id, up[1].port.mapbase, op->irqs[0]); | 1439 | "is a %s\n", |
1440 | op->dev.bus_id, up[1].port.mapbase, op->irqs[0], | ||
1441 | sunzilog_type (&up[1].port)); | ||
1399 | } | 1442 | } |
1400 | 1443 | ||
1401 | dev_set_drvdata(&op->dev, &up[0]); | 1444 | dev_set_drvdata(&op->dev, &up[0]); |
@@ -1487,10 +1530,23 @@ static int __init sunzilog_init(void) | |||
1487 | goto out_unregister_uart; | 1530 | goto out_unregister_uart; |
1488 | 1531 | ||
1489 | if (zilog_irq != -1) { | 1532 | if (zilog_irq != -1) { |
1533 | struct uart_sunzilog_port *up = sunzilog_irq_chain; | ||
1490 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | 1534 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, |
1491 | "zs", sunzilog_irq_chain); | 1535 | "zs", sunzilog_irq_chain); |
1492 | if (err) | 1536 | if (err) |
1493 | goto out_unregister_driver; | 1537 | goto out_unregister_driver; |
1538 | |||
1539 | /* Enable Interrupts */ | ||
1540 | while (up) { | ||
1541 | struct zilog_channel __iomem *channel; | ||
1542 | |||
1543 | /* printk (KERN_INFO "Enable IRQ for ZILOG Hardware %p\n", up); */ | ||
1544 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
1545 | up->flags |= SUNZILOG_FLAG_ISR_HANDLER; | ||
1546 | up->curregs[R9] |= MIE; | ||
1547 | write_zsreg(channel, R9, up->curregs[R9]); | ||
1548 | up = up->next; | ||
1549 | } | ||
1494 | } | 1550 | } |
1495 | 1551 | ||
1496 | out: | 1552 | out: |
@@ -1515,6 +1571,20 @@ static void __exit sunzilog_exit(void) | |||
1515 | of_unregister_driver(&zs_driver); | 1571 | of_unregister_driver(&zs_driver); |
1516 | 1572 | ||
1517 | if (zilog_irq != -1) { | 1573 | if (zilog_irq != -1) { |
1574 | struct uart_sunzilog_port *up = sunzilog_irq_chain; | ||
1575 | |||
1576 | /* Disable Interrupts */ | ||
1577 | while (up) { | ||
1578 | struct zilog_channel __iomem *channel; | ||
1579 | |||
1580 | /* printk (KERN_INFO "Disable IRQ for ZILOG Hardware %p\n", up); */ | ||
1581 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
1582 | up->flags &= ~SUNZILOG_FLAG_ISR_HANDLER; | ||
1583 | up->curregs[R9] &= ~MIE; | ||
1584 | write_zsreg(channel, R9, up->curregs[R9]); | ||
1585 | up = up->next; | ||
1586 | } | ||
1587 | |||
1518 | free_irq(zilog_irq, sunzilog_irq_chain); | 1588 | free_irq(zilog_irq, sunzilog_irq_chain); |
1519 | zilog_irq = -1; | 1589 | zilog_irq = -1; |
1520 | } | 1590 | } |
diff --git a/drivers/serial/sunzilog.h b/drivers/serial/sunzilog.h index 7939b6d71270..5dec7b47cc38 100644 --- a/drivers/serial/sunzilog.h +++ b/drivers/serial/sunzilog.h | |||
@@ -13,7 +13,8 @@ struct zilog_layout { | |||
13 | struct zilog_channel channelA; | 13 | struct zilog_channel channelA; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #define NUM_ZSREGS 16 | 16 | #define NUM_ZSREGS 17 |
17 | #define R7p 16 /* Written as R7 with P15 bit 0 set */ | ||
17 | 18 | ||
18 | /* Conversion routines to/from brg time constants from/to bits | 19 | /* Conversion routines to/from brg time constants from/to bits |
19 | * per second. | 20 | * per second. |
@@ -127,6 +128,15 @@ struct zilog_layout { | |||
127 | 128 | ||
128 | /* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ | 129 | /* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ |
129 | 130 | ||
131 | /* Write Register 7' (ESCC Only) */ | ||
132 | #define AUTO_TxFLAG 1 /* Automatic Tx SDLC Flag */ | ||
133 | #define AUTO_EOM_RST 2 /* Automatic EOM Reset */ | ||
134 | #define AUTOnRTS 4 /* Automatic /RTS pin deactivation */ | ||
135 | #define RxFIFO_LVL 8 /* Receive FIFO interrupt level */ | ||
136 | #define nDTRnREQ 0x10 /* /DTR/REQ timing */ | ||
137 | #define TxFIFO_LVL 0x20 /* Transmit FIFO interrupt level */ | ||
138 | #define EXT_RD_EN 0x40 /* Extended read register enable */ | ||
139 | |||
130 | /* Write Register 8 (transmit buffer) */ | 140 | /* Write Register 8 (transmit buffer) */ |
131 | 141 | ||
132 | /* Write Register 9 (Master interrupt control) */ | 142 | /* Write Register 9 (Master interrupt control) */ |
@@ -135,6 +145,7 @@ struct zilog_layout { | |||
135 | #define DLC 4 /* Disable Lower Chain */ | 145 | #define DLC 4 /* Disable Lower Chain */ |
136 | #define MIE 8 /* Master Interrupt Enable */ | 146 | #define MIE 8 /* Master Interrupt Enable */ |
137 | #define STATHI 0x10 /* Status high */ | 147 | #define STATHI 0x10 /* Status high */ |
148 | #define SWIACK 0x20 /* Software Interrupt Ack (not on NMOS) */ | ||
138 | #define NORESET 0 /* No reset on write to R9 */ | 149 | #define NORESET 0 /* No reset on write to R9 */ |
139 | #define CHRB 0x40 /* Reset channel B */ | 150 | #define CHRB 0x40 /* Reset channel B */ |
140 | #define CHRA 0x80 /* Reset channel A */ | 151 | #define CHRA 0x80 /* Reset channel A */ |
@@ -187,7 +198,9 @@ struct zilog_layout { | |||
187 | #define SNRZI 0xe0 /* Set NRZI mode */ | 198 | #define SNRZI 0xe0 /* Set NRZI mode */ |
188 | 199 | ||
189 | /* Write Register 15 (external/status interrupt control) */ | 200 | /* Write Register 15 (external/status interrupt control) */ |
201 | #define WR7pEN 1 /* WR7' Enable (ESCC only) */ | ||
190 | #define ZCIE 2 /* Zero count IE */ | 202 | #define ZCIE 2 /* Zero count IE */ |
203 | #define FIFOEN 4 /* FIFO Enable (ESCC only) */ | ||
191 | #define DCDIE 8 /* DCD IE */ | 204 | #define DCDIE 8 /* DCD IE */ |
192 | #define SYNCIE 0x10 /* Sync/hunt IE */ | 205 | #define SYNCIE 0x10 /* Sync/hunt IE */ |
193 | #define CTSIE 0x20 /* CTS IE */ | 206 | #define CTSIE 0x20 /* CTS IE */ |
@@ -241,6 +254,10 @@ struct zilog_layout { | |||
241 | #define CHATxIP 0x10 /* Channel A Tx IP */ | 254 | #define CHATxIP 0x10 /* Channel A Tx IP */ |
242 | #define CHARxIP 0x20 /* Channel A Rx IP */ | 255 | #define CHARxIP 0x20 /* Channel A Rx IP */ |
243 | 256 | ||
257 | /* Read Register 6 (LSB frame byte count [Not on NMOS]) */ | ||
258 | |||
259 | /* Read Register 7 (MSB frame byte count and FIFO status [Not on NMOS]) */ | ||
260 | |||
244 | /* Read Register 8 (receive data register) */ | 261 | /* Read Register 8 (receive data register) */ |
245 | 262 | ||
246 | /* Read Register 10 (misc status bits) */ | 263 | /* Read Register 10 (misc status bits) */ |
diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h index e01b80559c93..26ec046715c8 100644 --- a/include/asm-sparc64/openprom.h +++ b/include/asm-sparc64/openprom.h | |||
@@ -177,7 +177,7 @@ struct linux_nodeops { | |||
177 | /* More fun PROM structures for device probing. */ | 177 | /* More fun PROM structures for device probing. */ |
178 | #define PROMREG_MAX 24 | 178 | #define PROMREG_MAX 24 |
179 | #define PROMVADDR_MAX 16 | 179 | #define PROMVADDR_MAX 16 |
180 | #define PROMINTR_MAX 15 | 180 | #define PROMINTR_MAX 32 |
181 | 181 | ||
182 | struct linux_prom_registers { | 182 | struct linux_prom_registers { |
183 | unsigned which_io; /* hi part of physical address */ | 183 | unsigned which_io; /* hi part of physical address */ |