diff options
author | Scott Wood <scottwood@freescale.com> | 2013-12-14 01:15:24 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-12-14 01:15:24 (GMT) |
commit | b7c81aa3ab2ac2c140e278b6d0e9a0b95112cf0b (patch) | |
tree | 87828aaf5f82c7042bfc0307bc4ac499e10f93fb /arch/powerpc/kernel/udbg_16550.c | |
parent | 22c782a4b14773fab7eab3c1db54ad7ad077e9b8 (diff) | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-b7c81aa3ab2ac2c140e278b6d0e9a0b95112cf0b.tar.xz |
Merge remote-tracking branch 'linus/master' into merge
Conflicts:
Documentation/hwmon/ina2xx
arch/powerpc/Kconfig
arch/powerpc/boot/dts/b4860emu.dts
arch/powerpc/boot/dts/b4qds.dtsi
arch/powerpc/boot/dts/fsl/b4si-post.dtsi
arch/powerpc/boot/dts/fsl/qoriq-sec6.0-0.dtsi
arch/powerpc/boot/dts/p1023rdb.dts
arch/powerpc/boot/dts/t4240emu.dts
arch/powerpc/boot/dts/t4240qds.dts
arch/powerpc/configs/85xx/p1023_defconfig
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/device.h
arch/powerpc/include/asm/epapr_hcalls.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/mpic.h
arch/powerpc/include/asm/pci.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/kernel/epapr_paravirt.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/swsusp_asm64.S
arch/powerpc/kernel/swsusp_booke.S
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/booke.h
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500.h
arch/powerpc/kvm/e500_emulate.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/perf/e6500-pmu.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/b4_qds.c
arch/powerpc/platforms/85xx/c293pcie.c
arch/powerpc/platforms/85xx/corenet_ds.c
arch/powerpc/platforms/85xx/corenet_ds.h
arch/powerpc/platforms/85xx/p1023_rds.c
arch/powerpc/platforms/85xx/p2041_rdb.c
arch/powerpc/platforms/85xx/p3041_ds.c
arch/powerpc/platforms/85xx/p4080_ds.c
arch/powerpc/platforms/85xx/p5020_ds.c
arch/powerpc/platforms/85xx/p5040_ds.c
arch/powerpc/platforms/85xx/smp.c
arch/powerpc/platforms/85xx/t4240_qds.c
arch/powerpc/platforms/Kconfig
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mpic_timer.c
drivers/Kconfig
drivers/clk/Kconfig
drivers/clk/clk-ppc-corenet.c
drivers/cpufreq/Kconfig.powerpc
drivers/cpufreq/Makefile
drivers/cpufreq/ppc-corenet-cpufreq.c
drivers/crypto/caam/Kconfig
drivers/crypto/caam/Makefile
drivers/crypto/caam/ctrl.c
drivers/crypto/caam/desc_constr.h
drivers/crypto/caam/intern.h
drivers/crypto/caam/jr.c
drivers/crypto/caam/regs.h
drivers/dma/fsldma.c
drivers/hwmon/ina2xx.c
drivers/iommu/Kconfig
drivers/iommu/fsl_pamu.c
drivers/iommu/fsl_pamu.h
drivers/iommu/fsl_pamu_domain.c
drivers/iommu/fsl_pamu_domain.h
drivers/misc/Makefile
drivers/mmc/card/block.c
drivers/mmc/core/core.c
drivers/mmc/host/sdhci-esdhc.h
drivers/mmc/host/sdhci-pltfm.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h
drivers/net/ethernet/freescale/gianfar_ethtool.c
drivers/net/phy/at803x.c
drivers/net/phy/phy_device.c
drivers/net/phy/vitesse.c
drivers/pci/msi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio.c
drivers/usb/host/ehci-fsl.c
drivers/vfio/Kconfig
drivers/vfio/Makefile
include/crypto/algapi.h
include/linux/iommu.h
include/linux/mmc/sdhci.h
include/linux/msi.h
include/linux/netdev_features.h
include/linux/phy.h
include/linux/skbuff.h
include/net/ip.h
include/uapi/linux/vfio.h
net/core/ethtool.c
net/ipv4/route.c
net/ipv6/route.c
Diffstat (limited to 'arch/powerpc/kernel/udbg_16550.c')
-rw-r--r-- | arch/powerpc/kernel/udbg_16550.c | 370 |
1 files changed, 164 insertions, 206 deletions
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 6837f83..75702e2 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -18,23 +18,19 @@ extern void real_writeb(u8 data, volatile u8 __iomem *addr); extern u8 real_205_readb(volatile u8 __iomem *addr); extern void real_205_writeb(u8 data, volatile u8 __iomem *addr); -struct NS16550 { - /* this struct must be packed */ - unsigned char rbr; /* 0 */ - unsigned char ier; /* 1 */ - unsigned char fcr; /* 2 */ - unsigned char lcr; /* 3 */ - unsigned char mcr; /* 4 */ - unsigned char lsr; /* 5 */ - unsigned char msr; /* 6 */ - unsigned char scr; /* 7 */ -}; - -#define thr rbr -#define iir fcr -#define dll rbr -#define dlm ier -#define dlab lcr +#define UART_RBR 0 +#define UART_IER 1 +#define UART_FCR 2 +#define UART_LCR 3 +#define UART_MCR 4 +#define UART_LSR 5 +#define UART_MSR 6 +#define UART_SCR 7 +#define UART_THR UART_RBR +#define UART_IIR UART_FCR +#define UART_DLL UART_RBR +#define UART_DLM UART_IER +#define UART_DLAB UART_LCR #define LSR_DR 0x01 /* Data ready */ #define LSR_OE 0x02 /* Overrun */ @@ -47,52 +43,62 @@ struct NS16550 { #define LCR_DLAB 0x80 -static struct NS16550 __iomem *udbg_comport; +static u8 (*udbg_uart_in)(unsigned int reg); +static void (*udbg_uart_out)(unsigned int reg, u8 data); -static void udbg_550_flush(void) +static void udbg_uart_flush(void) { - if (udbg_comport) { - while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + if (!udbg_uart_in) + return; + + /* wait for idle */ + while ((udbg_uart_in(UART_LSR) & LSR_THRE) == 0) + cpu_relax(); } -static void udbg_550_putc(char c) +static void udbg_uart_putc(char c) { - if (udbg_comport) { - if (c == '\n') - udbg_550_putc('\r'); - udbg_550_flush(); - out_8(&udbg_comport->thr, c); - } + if (!udbg_uart_out) + return; + + if (c == '\n') + udbg_uart_putc('\r'); + udbg_uart_flush(); + udbg_uart_out(UART_THR, c); } -static int udbg_550_getc_poll(void) +static int udbg_uart_getc_poll(void) { - if (udbg_comport) { - if ((in_8(&udbg_comport->lsr) & LSR_DR) != 0) - return in_8(&udbg_comport->rbr); - else - return -1; - } + if (!udbg_uart_in || !(udbg_uart_in(UART_LSR) & LSR_DR)) + return udbg_uart_in(UART_RBR); return -1; } -static int udbg_550_getc(void) +static int udbg_uart_getc(void) { - if (udbg_comport) { - while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0) - /* wait for char */; - return in_8(&udbg_comport->rbr); - } - return -1; + if (!udbg_uart_in) + return -1; + /* wait for char */ + while (!(udbg_uart_in(UART_LSR) & LSR_DR)) + cpu_relax(); + return udbg_uart_in(UART_RBR); +} + +static void udbg_use_uart(void) +{ + udbg_putc = udbg_uart_putc; + udbg_flush = udbg_uart_flush; + udbg_getc = udbg_uart_getc; + udbg_getc_poll = udbg_uart_getc_poll; } -void udbg_init_uart(void __iomem *comport, unsigned int speed, - unsigned int clock) +void udbg_uart_setup(unsigned int speed, unsigned int clock) { unsigned int dll, base_bauds; + if (!udbg_uart_out) + return; + if (clock == 0) clock = 1843200; if (speed == 0) @@ -101,51 +107,43 @@ void udbg_init_uart(void __iomem *comport, unsigned int speed, base_bauds = clock / 16; dll = base_bauds / speed; - if (comport) { - udbg_comport = (struct NS16550 __iomem *)comport; - out_8(&udbg_comport->lcr, 0x00); - out_8(&udbg_comport->ier, 0xff); - out_8(&udbg_comport->ier, 0x00); - out_8(&udbg_comport->lcr, LCR_DLAB); - out_8(&udbg_comport->dll, dll & 0xff); - out_8(&udbg_comport->dlm, dll >> 8); - /* 8 data, 1 stop, no parity */ - out_8(&udbg_comport->lcr, 0x03); - /* RTS/DTR */ - out_8(&udbg_comport->mcr, 0x03); - /* Clear & enable FIFOs */ - out_8(&udbg_comport->fcr ,0x07); - udbg_putc = udbg_550_putc; - udbg_flush = udbg_550_flush; - udbg_getc = udbg_550_getc; - udbg_getc_poll = udbg_550_getc_poll; - } + udbg_uart_out(UART_LCR, 0x00); + udbg_uart_out(UART_IER, 0xff); + udbg_uart_out(UART_IER, 0x00); + udbg_uart_out(UART_LCR, LCR_DLAB); + udbg_uart_out(UART_DLL, dll & 0xff); + udbg_uart_out(UART_DLM, dll >> 8); + /* 8 data, 1 stop, no parity */ + udbg_uart_out(UART_LCR, 0x3); + /* RTS/DTR */ + udbg_uart_out(UART_MCR, 0x3); + /* Clear & enable FIFOs */ + udbg_uart_out(UART_FCR, 0x7); } -unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) +unsigned int udbg_probe_uart_speed(unsigned int clock) { unsigned int dll, dlm, divisor, prescaler, speed; u8 old_lcr; - struct NS16550 __iomem *port = comport; - old_lcr = in_8(&port->lcr); + old_lcr = udbg_uart_in(UART_LCR); /* select divisor latch registers. */ - out_8(&port->lcr, LCR_DLAB); + udbg_uart_out(UART_LCR, old_lcr | LCR_DLAB); /* now, read the divisor */ - dll = in_8(&port->dll); - dlm = in_8(&port->dlm); + dll = udbg_uart_in(UART_DLL); + dlm = udbg_uart_in(UART_DLM); divisor = dlm << 8 | dll; /* check prescaling */ - if (in_8(&port->mcr) & 0x80) + if (udbg_uart_in(UART_MCR) & 0x80) prescaler = 4; else prescaler = 1; /* restore the LCR */ - out_8(&port->lcr, old_lcr); + udbg_uart_out(UART_LCR, old_lcr); /* calculate speed */ speed = (clock / prescaler) / (divisor * 16); @@ -157,195 +155,155 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) return speed; } -#ifdef CONFIG_PPC_MAPLE -void udbg_maple_real_flush(void) +static union { + unsigned char __iomem *mmio_base; + unsigned long pio_base; +} udbg_uart; + +static unsigned int udbg_uart_stride = 1; + +static u8 udbg_uart_in_pio(unsigned int reg) { - if (udbg_comport) { - while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + return inb(udbg_uart.pio_base + (reg * udbg_uart_stride)); } -void udbg_maple_real_putc(char c) +static void udbg_uart_out_pio(unsigned int reg, u8 data) { - if (udbg_comport) { - if (c == '\n') - udbg_maple_real_putc('\r'); - udbg_maple_real_flush(); - real_writeb(c, &udbg_comport->thr); eieio(); - } + outb(data, udbg_uart.pio_base + (reg * udbg_uart_stride)); } -void __init udbg_init_maple_realmode(void) +void udbg_uart_init_pio(unsigned long port, unsigned int stride) { - udbg_comport = (struct NS16550 __iomem *)0xf40003f8; - - udbg_putc = udbg_maple_real_putc; - udbg_flush = udbg_maple_real_flush; - udbg_getc = NULL; - udbg_getc_poll = NULL; + if (!port) + return; + udbg_uart.pio_base = port; + udbg_uart_stride = stride; + udbg_uart_in = udbg_uart_in_pio; + udbg_uart_out = udbg_uart_out_pio; + udbg_use_uart(); } -#endif /* CONFIG_PPC_MAPLE */ -#ifdef CONFIG_PPC_PASEMI -void udbg_pas_real_flush(void) +static u8 udbg_uart_in_mmio(unsigned int reg) { - if (udbg_comport) { - while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + return in_8(udbg_uart.mmio_base + (reg * udbg_uart_stride)); } -void udbg_pas_real_putc(char c) +static void udbg_uart_out_mmio(unsigned int reg, u8 data) { - if (udbg_comport) { - if (c == '\n') - udbg_pas_real_putc('\r'); - udbg_pas_real_flush(); - real_205_writeb(c, &udbg_comport->thr); eieio(); - } + out_8(udbg_uart.mmio_base + (reg * udbg_uart_stride), data); } -void udbg_init_pas_realmode(void) -{ - udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL; - udbg_putc = udbg_pas_real_putc; - udbg_flush = udbg_pas_real_flush; - udbg_getc = NULL; - udbg_getc_poll = NULL; +void udbg_uart_init_mmio(void __iomem *addr, unsigned int stride) +{ + if (!addr) + return; + udbg_uart.mmio_base = addr; + udbg_uart_stride = stride; + udbg_uart_in = udbg_uart_in_mmio; + udbg_uart_out = udbg_uart_out_mmio; + udbg_use_uart(); } -#endif /* CONFIG_PPC_MAPLE */ -#ifdef CONFIG_PPC_EARLY_DEBUG_44x -#include <platforms/44x/44x.h> +#ifdef CONFIG_PPC_MAPLE + +#define UDBG_UART_MAPLE_ADDR ((void __iomem *)0xf40003f8) -static void udbg_44x_as1_flush(void) +static u8 udbg_uart_in_maple(unsigned int reg) { - if (udbg_comport) { - while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + return real_readb(UDBG_UART_MAPLE_ADDR + reg); } -static void udbg_44x_as1_putc(char c) +static void udbg_uart_out_maple(unsigned int reg, u8 val) { - if (udbg_comport) { - if (c == '\n') - udbg_44x_as1_putc('\r'); - udbg_44x_as1_flush(); - as1_writeb(c, &udbg_comport->thr); eieio(); - } + real_writeb(val, UDBG_UART_MAPLE_ADDR + reg); } -static int udbg_44x_as1_getc(void) +void __init udbg_init_maple_realmode(void) { - if (udbg_comport) { - while ((as1_readb(&udbg_comport->lsr) & LSR_DR) == 0) - ; /* wait for char */ - return as1_readb(&udbg_comport->rbr); - } - return -1; + udbg_uart_in = udbg_uart_in_maple; + udbg_uart_out = udbg_uart_out_maple; + udbg_use_uart(); } -void __init udbg_init_44x_as1(void) -{ - udbg_comport = - (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; +#endif /* CONFIG_PPC_MAPLE */ - udbg_putc = udbg_44x_as1_putc; - udbg_flush = udbg_44x_as1_flush; - udbg_getc = udbg_44x_as1_getc; -} -#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ +#ifdef CONFIG_PPC_PASEMI -#ifdef CONFIG_PPC_EARLY_DEBUG_40x -static void udbg_40x_real_flush(void) +#define UDBG_UART_PAS_ADDR ((void __iomem *)0xfcff03f8UL) + +static u8 udbg_uart_in_pas(unsigned int reg) { - if (udbg_comport) { - while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + return real_205_readb(UDBG_UART_PAS_ADDR + reg); } -static void udbg_40x_real_putc(char c) +static void udbg_uart_out_pas(unsigned int reg, u8 val) { - if (udbg_comport) { - if (c == '\n') - udbg_40x_real_putc('\r'); - udbg_40x_real_flush(); - real_writeb(c, &udbg_comport->thr); eieio(); - } + real_205_writeb(val, UDBG_UART_PAS_ADDR + reg); } -static int udbg_40x_real_getc(void) +void __init udbg_init_pas_realmode(void) { - if (udbg_comport) { - while ((real_readb(&udbg_comport->lsr) & LSR_DR) == 0) - ; /* wait for char */ - return real_readb(&udbg_comport->rbr); - } - return -1; + udbg_uart_in = udbg_uart_in_pas; + udbg_uart_out = udbg_uart_out_pas; + udbg_use_uart(); } -void __init udbg_init_40x_realmode(void) -{ - udbg_comport = (struct NS16550 __iomem *) - CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR; +#endif /* CONFIG_PPC_PASEMI */ + +#ifdef CONFIG_PPC_EARLY_DEBUG_44x - udbg_putc = udbg_40x_real_putc; - udbg_flush = udbg_40x_real_flush; - udbg_getc = udbg_40x_real_getc; - udbg_getc_poll = NULL; +#include <platforms/44x/44x.h> + +static u8 udbg_uart_in_44x_as1(unsigned int reg) +{ + return as1_readb((void __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR + reg); } -#endif /* CONFIG_PPC_EARLY_DEBUG_40x */ -#ifdef CONFIG_PPC_EARLY_DEBUG_WSP -static void udbg_wsp_flush(void) +static void udbg_uart_out_44x_as1(unsigned int reg, u8 val) { - if (udbg_comport) { - while ((readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - } + as1_writeb(val, (void __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR + reg); } -static void udbg_wsp_putc(char c) +void __init udbg_init_44x_as1(void) { - if (udbg_comport) { - if (c == '\n') - udbg_wsp_putc('\r'); - udbg_wsp_flush(); - writeb(c, &udbg_comport->thr); eieio(); - } + udbg_uart_in = udbg_uart_in_44x_as1; + udbg_uart_out = udbg_uart_out_44x_as1; + udbg_use_uart(); } -static int udbg_wsp_getc(void) +#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ + +#ifdef CONFIG_PPC_EARLY_DEBUG_40x + +static u8 udbg_uart_in_40x(unsigned int reg) { - if (udbg_comport) { - while ((readb(&udbg_comport->lsr) & LSR_DR) == 0) - ; /* wait for char */ - return readb(&udbg_comport->rbr); - } - return -1; + return real_readb((void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR + + reg); } -static int udbg_wsp_getc_poll(void) +static void udbg_uart_out_40x(unsigned int reg, u8 val) { - if (udbg_comport) - if (readb(&udbg_comport->lsr) & LSR_DR) - return readb(&udbg_comport->rbr); - return -1; + real_writeb(val, (void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR + + reg); } -void __init udbg_init_wsp(void) +void __init udbg_init_40x_realmode(void) { - udbg_comport = (struct NS16550 __iomem *)WSP_UART_VIRT; + udbg_uart_in = udbg_uart_in_40x; + udbg_uart_out = udbg_uart_out_40x; + udbg_use_uart(); +} - udbg_init_uart(udbg_comport, 57600, 50000000); +#endif /* CONFIG_PPC_EARLY_DEBUG_40x */ + + +#ifdef CONFIG_PPC_EARLY_DEBUG_WSP - udbg_putc = udbg_wsp_putc; - udbg_flush = udbg_wsp_flush; - udbg_getc = udbg_wsp_getc; - udbg_getc_poll = udbg_wsp_getc_poll; +void __init udbg_init_wsp(void) +{ + udbg_uart_init_mmio((void *)WSP_UART_VIRT, 1); + udbg_uart_setup(57600, 50000000); } + #endif /* CONFIG_PPC_EARLY_DEBUG_WSP */ |