]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/legacy_serial.c
powerpc: Correct DSCR during TM context switch
[karo-tx-linux.git] / arch / powerpc / kernel / legacy_serial.c
index 40bd7bd4e19a88ee9b573c37deea8bc8694375b9..936258881c98ccaee684998a3d05b2485c7fce0c 100644 (file)
@@ -48,6 +48,9 @@ static struct of_device_id legacy_serial_parents[] __initdata = {
 static unsigned int legacy_serial_count;
 static int legacy_serial_console = -1;
 
+static const upf_t legacy_port_flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+       UPF_SHARE_IRQ | UPF_FIXED_PORT;
+
 static unsigned int tsi_serial_in(struct uart_port *p, int offset)
 {
        unsigned int tmp;
@@ -71,8 +74,9 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
                                  phys_addr_t taddr, unsigned long irq,
                                  upf_t flags, int irq_check_parent)
 {
-       const __be32 *clk, *spd;
+       const __be32 *clk, *spd, *rs;
        u32 clock = BASE_BAUD * 16;
+       u32 shift = 0;
        int index;
 
        /* get clock freq. if present */
@@ -83,6 +87,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
        /* get default speed if present */
        spd = of_get_property(np, "current-speed", NULL);
 
+       /* get register shift if present */
+       rs = of_get_property(np, "reg-shift", NULL);
+       if (rs && *rs)
+               shift = be32_to_cpup(rs);
+
        /* If we have a location index, then try to use it */
        if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
                index = want_index;
@@ -126,6 +135,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
        legacy_serial_ports[index].uartclk = clock;
        legacy_serial_ports[index].irq = irq;
        legacy_serial_ports[index].flags = flags;
+       legacy_serial_ports[index].regshift = shift;
        legacy_serial_infos[index].taddr = taddr;
        legacy_serial_infos[index].np = of_node_get(np);
        legacy_serial_infos[index].clock = clock;
@@ -153,8 +163,6 @@ static int __init add_legacy_soc_port(struct device_node *np,
 {
        u64 addr;
        const __be32 *addrp;
-       upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ
-               | UPF_FIXED_PORT;
        struct device_node *tsi = of_get_parent(np);
 
        /* We only support ports that have a clock frequency properly
@@ -163,9 +171,8 @@ static int __init add_legacy_soc_port(struct device_node *np,
        if (of_get_property(np, "clock-frequency", NULL) == NULL)
                return -1;
 
-       /* if reg-shift or offset, don't try to use it */
-       if ((of_get_property(np, "reg-shift", NULL) != NULL) ||
-               (of_get_property(np, "reg-offset", NULL) != NULL))
+       /* if reg-offset don't try to use it */
+       if ((of_get_property(np, "reg-offset", NULL) != NULL))
                return -1;
 
        /* if rtas uses this device, don't try to use it as well */
@@ -185,9 +192,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
         * IO port value. It will be fixed up later along with the irq
         */
        if (tsi && !strcmp(tsi->type, "tsi-bridge"))
-               return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+               return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
+                                      NO_IRQ, legacy_port_flags, 0);
        else
-               return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+               return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
+                                      NO_IRQ, legacy_port_flags, 0);
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
@@ -233,7 +242,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
 
        /* Add port, irq will be dealt with later */
        return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]),
-                              taddr, NO_IRQ, UPF_BOOT_AUTOCONF, 0);
+                              taddr, NO_IRQ, legacy_port_flags, 0);
 
 }
 
@@ -306,7 +315,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
         * IO port value. It will be fixed up later along with the irq
         */
        return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
-                              UPF_BOOT_AUTOCONF, np != pci_dev);
+                              legacy_port_flags, np != pci_dev);
 }
 #endif
 
@@ -315,17 +324,20 @@ static void __init setup_legacy_serial_console(int console)
        struct legacy_serial_info *info = &legacy_serial_infos[console];
        struct plat_serial8250_port *port = &legacy_serial_ports[console];
        void __iomem *addr;
+       unsigned int stride;
+
+       stride = 1 << port->regshift;
 
        /* Check if a translated MMIO address has been found */
        if (info->taddr) {
                addr = ioremap(info->taddr, 0x1000);
                if (addr == NULL)
                        return;
-               udbg_uart_init_mmio(addr, 1);
+               udbg_uart_init_mmio(addr, stride);
        } else {
                /* Check if it's PIO and we support untranslated PIO */
                if (port->iotype == UPIO_PORT && isa_io_special)
-                       udbg_uart_init_pio(port->iobase, 1);
+                       udbg_uart_init_pio(port->iobase, stride);
                else
                        return;
        }