17cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa/* 27cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * 8250/16550-type serial ports prom_putchar() 37cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * 47cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * Copyright (C) 2010 Yoichi Yuasa <yuasa@linux-mips.org> 57cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * 67cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * This program is free software; you can redistribute it and/or modify 77cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * it under the terms of the GNU General Public License as published by 87cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * the Free Software Foundation; either version 2 of the License, or 97cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * (at your option) any later version. 107cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * 117cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * This program is distributed in the hope that it will be useful, 127cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * but WITHOUT ANY WARRANTY; without even the implied warranty of 137cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 147cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * GNU General Public License for more details. 157cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * 167cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * You should have received a copy of the GNU General Public License 177cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * along with this program; if not, write to the Free Software 187cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 197cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa */ 207cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa#include <linux/io.h> 217cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa#include <linux/serial_core.h> 227cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa#include <linux/serial_reg.h> 237cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 247cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasastatic void __iomem *serial8250_base; 257cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasastatic unsigned int serial8250_reg_shift; 267cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasastatic unsigned int serial8250_tx_timeout; 277cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 287cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasavoid setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift, 297cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa unsigned int timeout) 307cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa{ 317cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa serial8250_base = (void __iomem *)base; 327cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa serial8250_reg_shift = reg_shift; 337cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa serial8250_tx_timeout = timeout; 347cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa} 357cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 367cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasastatic inline u8 serial_in(int offset) 377cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa{ 387cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa return readb(serial8250_base + (offset << serial8250_reg_shift)); 397cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa} 407cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 417cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasastatic inline void serial_out(int offset, char value) 427cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa{ 437cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa writeb(value, serial8250_base + (offset << serial8250_reg_shift)); 447cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa} 457cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 467cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasavoid prom_putchar(char c) 477cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa{ 487cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa unsigned int timeout; 497cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa int status, bits; 507cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 517cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa if (!serial8250_base) 527cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa return; 537cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 547cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa timeout = serial8250_tx_timeout; 557cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa bits = UART_LSR_TEMT | UART_LSR_THRE; 567cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 577cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa do { 587cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa status = serial_in(UART_LSR); 597cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 607cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa if (--timeout == 0) 617cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa break; 627cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa } while ((status & bits) != bits); 637cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa 647cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa if (timeout) 657cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa serial_out(UART_TX, c); 667cd93b893567906d9c9e9e1121667600b4cebbafYoichi Yuasa} 67