diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-11-28 19:21:59 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 22:50:58 -0500 |
commit | 8dacaedf04467e32c50148751a96150e73323cdc (patch) | |
tree | 74e8406ee6a78c7cf232858994ee49547c273042 /arch/powerpc/kernel/legacy_serial.c | |
parent | 1c3eb629102bd4e327cc8b08fb9cdae4a985e841 (diff) |
[PATCH] powerpc: More serial probe fixes (#2)
This fixes the new serial probe code with some PCI MMIO UARTs, and fixes
CHRP build with ARCH=powerpc.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/legacy_serial.c')
-rw-r--r-- | arch/powerpc/kernel/legacy_serial.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 7a685cae81ed..83023bb59ad9 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -38,15 +38,13 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
38 | int iotype, phys_addr_t base, | 38 | int iotype, phys_addr_t base, |
39 | phys_addr_t taddr, unsigned long irq) | 39 | phys_addr_t taddr, unsigned long irq) |
40 | { | 40 | { |
41 | u32 *clk, *spd, clock; | 41 | u32 *clk, *spd, clock = BASE_BAUD * 16; |
42 | int index; | 42 | int index; |
43 | 43 | ||
44 | /* get clock freq. if present */ | 44 | /* get clock freq. if present */ |
45 | clk = (u32 *)get_property(np, "clock-frequency", NULL); | 45 | clk = (u32 *)get_property(np, "clock-frequency", NULL); |
46 | if (clk && *clk) | 46 | if (clk && *clk) |
47 | clock = *clk; | 47 | clock = *clk; |
48 | else | ||
49 | clock = BASE_BAUD * 16; | ||
50 | 48 | ||
51 | /* get default speed if present */ | 49 | /* get default speed if present */ |
52 | spd = (u32 *)get_property(np, "current-speed", NULL); | 50 | spd = (u32 *)get_property(np, "current-speed", NULL); |
@@ -88,7 +86,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
88 | if (iotype == UPIO_PORT) | 86 | if (iotype == UPIO_PORT) |
89 | legacy_serial_ports[index].iobase = base; | 87 | legacy_serial_ports[index].iobase = base; |
90 | else | 88 | else |
91 | legacy_serial_ports[index].membase = (void __iomem *)base; | 89 | legacy_serial_ports[index].mapbase = base; |
92 | legacy_serial_ports[index].iotype = iotype; | 90 | legacy_serial_ports[index].iotype = iotype; |
93 | legacy_serial_ports[index].uartclk = clock; | 91 | legacy_serial_ports[index].uartclk = clock; |
94 | legacy_serial_ports[index].irq = irq; | 92 | legacy_serial_ports[index].irq = irq; |
@@ -148,17 +146,17 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
148 | { | 146 | { |
149 | phys_addr_t addr, base; | 147 | phys_addr_t addr, base; |
150 | u32 *addrp; | 148 | u32 *addrp; |
151 | int iotype, index = -1; | 149 | int iotype, index = -1, lindex = 0; |
152 | 150 | ||
153 | #if 0 | ||
154 | /* We only support ports that have a clock frequency properly | 151 | /* We only support ports that have a clock frequency properly |
155 | * encoded in the device-tree (that is have an fcode). Anything | 152 | * encoded in the device-tree (that is have an fcode). Anything |
156 | * else can't be used that early and will be normally probed by | 153 | * else can't be used that early and will be normally probed by |
157 | * the generic 8250_pci driver later on. | 154 | * the generic 8250_pci driver later on. The reason is that 8250 |
155 | * compatible UARTs on PCI need all sort of quirks (port offsets | ||
156 | * etc...) that this code doesn't know about | ||
158 | */ | 157 | */ |
159 | if (get_property(np, "clock-frequency", NULL) == NULL) | 158 | if (get_property(np, "clock-frequency", NULL) == NULL) |
160 | return -1; | 159 | return -1; |
161 | #endif | ||
162 | 160 | ||
163 | /* Get the PCI address. Assume BAR 0 */ | 161 | /* Get the PCI address. Assume BAR 0 */ |
164 | addrp = of_get_pci_address(pci_dev, 0, NULL); | 162 | addrp = of_get_pci_address(pci_dev, 0, NULL); |
@@ -183,7 +181,23 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
183 | if (np != pci_dev) { | 181 | if (np != pci_dev) { |
184 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | 182 | u32 *reg = (u32 *)get_property(np, "reg", NULL); |
185 | if (reg && (*reg < 4)) | 183 | if (reg && (*reg < 4)) |
186 | index = legacy_serial_count + *reg; | 184 | index = lindex = *reg; |
185 | } | ||
186 | |||
187 | /* Local index means it's the Nth port in the PCI chip. Unfortunately | ||
188 | * the offset to add here is device specific. We know about those | ||
189 | * EXAR ports and we default to the most common case. If your UART | ||
190 | * doesn't work for these settings, you'll have to add your own special | ||
191 | * cases here | ||
192 | */ | ||
193 | if (device_is_compatible(pci_dev, "pci13a8,152") || | ||
194 | device_is_compatible(pci_dev, "pci13a8,154") || | ||
195 | device_is_compatible(pci_dev, "pci13a8,158")) { | ||
196 | addr += 0x200 * lindex; | ||
197 | base += 0x200 * lindex; | ||
198 | } else { | ||
199 | addr += 8 * lindex; | ||
200 | base += 8 * lindex; | ||
187 | } | 201 | } |
188 | 202 | ||
189 | /* Add port, irq will be dealt with later. We passed a translated | 203 | /* Add port, irq will be dealt with later. We passed a translated |
@@ -264,7 +278,6 @@ void __init find_legacy_serial_ports(void) | |||
264 | DBG("legacy_serial_console = %d\n", legacy_serial_console); | 278 | DBG("legacy_serial_console = %d\n", legacy_serial_console); |
265 | 279 | ||
266 | /* udbg is 64 bits only for now, that will change soon though ... */ | 280 | /* udbg is 64 bits only for now, that will change soon though ... */ |
267 | #ifdef CONFIG_PPC64 | ||
268 | while (legacy_serial_console >= 0) { | 281 | while (legacy_serial_console >= 0) { |
269 | struct legacy_serial_info *info = | 282 | struct legacy_serial_info *info = |
270 | &legacy_serial_infos[legacy_serial_console]; | 283 | &legacy_serial_infos[legacy_serial_console]; |
@@ -281,7 +294,6 @@ void __init find_legacy_serial_ports(void) | |||
281 | udbg_init_uart(addr, info->speed, info->clock); | 294 | udbg_init_uart(addr, info->speed, info->clock); |
282 | break; | 295 | break; |
283 | } | 296 | } |
284 | #endif /* CONFIG_PPC64 */ | ||
285 | 297 | ||
286 | DBG(" <- find_legacy_serial_port()\n"); | 298 | DBG(" <- find_legacy_serial_port()\n"); |
287 | } | 299 | } |
@@ -343,6 +355,15 @@ static void __init fixup_port_pio(int index, | |||
343 | } | 355 | } |
344 | } | 356 | } |
345 | 357 | ||
358 | static void __init fixup_port_mmio(int index, | ||
359 | struct device_node *np, | ||
360 | struct plat_serial8250_port *port) | ||
361 | { | ||
362 | DBG("fixup_port_mmio(%d)\n", index); | ||
363 | |||
364 | port->membase = ioremap(port->mapbase, 0x100); | ||
365 | } | ||
366 | |||
346 | /* | 367 | /* |
347 | * This is called as an arch initcall, hopefully before the PCI bus is | 368 | * This is called as an arch initcall, hopefully before the PCI bus is |
348 | * probed and/or the 8250 driver loaded since we need to register our | 369 | * probed and/or the 8250 driver loaded since we need to register our |
@@ -377,6 +398,8 @@ static int __init serial_dev_init(void) | |||
377 | fixup_port_irq(i, np, port); | 398 | fixup_port_irq(i, np, port); |
378 | if (port->iotype == UPIO_PORT) | 399 | if (port->iotype == UPIO_PORT) |
379 | fixup_port_pio(i, np, port); | 400 | fixup_port_pio(i, np, port); |
401 | if (port->iotype == UPIO_MEM) | ||
402 | fixup_port_mmio(i, np, port); | ||
380 | } | 403 | } |
381 | 404 | ||
382 | DBG("Registering platform serial ports\n"); | 405 | DBG("Registering platform serial ports\n"); |