18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci/*
48c2ecf20Sopenharmony_ci * IBM ASM Service Processor Device Driver
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) IBM Corporation, 2004
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Author: Max Asböck <amax@us.ibm.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/termios.h>
128c2ecf20Sopenharmony_ci#include <linux/tty.h>
138c2ecf20Sopenharmony_ci#include <linux/serial_core.h>
148c2ecf20Sopenharmony_ci#include <linux/serial_reg.h>
158c2ecf20Sopenharmony_ci#include <linux/serial_8250.h>
168c2ecf20Sopenharmony_ci#include "ibmasm.h"
178c2ecf20Sopenharmony_ci#include "lowlevel.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_civoid ibmasm_register_uart(struct service_processor *sp)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	struct uart_8250_port uart;
238c2ecf20Sopenharmony_ci	void __iomem *iomem_base;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	iomem_base = sp->base_address + SCOUT_COM_B_BASE;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	/* read the uart scratch register to determine if the UART
288c2ecf20Sopenharmony_ci	 * is dedicated to the service processor or if the OS can use it
298c2ecf20Sopenharmony_ci	 */
308c2ecf20Sopenharmony_ci	if (0 == readl(iomem_base + UART_SCR)) {
318c2ecf20Sopenharmony_ci		dev_info(sp->dev, "IBM SP UART not registered, owned by service processor\n");
328c2ecf20Sopenharmony_ci		sp->serial_line = -1;
338c2ecf20Sopenharmony_ci		return;
348c2ecf20Sopenharmony_ci	}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	memset(&uart, 0, sizeof(uart));
378c2ecf20Sopenharmony_ci	uart.port.irq		= sp->irq;
388c2ecf20Sopenharmony_ci	uart.port.uartclk	= 3686400;
398c2ecf20Sopenharmony_ci	uart.port.flags		= UPF_SHARE_IRQ;
408c2ecf20Sopenharmony_ci	uart.port.iotype	= UPIO_MEM;
418c2ecf20Sopenharmony_ci	uart.port.membase	= iomem_base;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	sp->serial_line = serial8250_register_8250_port(&uart);
448c2ecf20Sopenharmony_ci	if (sp->serial_line < 0) {
458c2ecf20Sopenharmony_ci		dev_err(sp->dev, "Failed to register serial port\n");
468c2ecf20Sopenharmony_ci		return;
478c2ecf20Sopenharmony_ci	}
488c2ecf20Sopenharmony_ci	enable_uart_interrupts(sp->base_address);
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_civoid ibmasm_unregister_uart(struct service_processor *sp)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	if (sp->serial_line < 0)
548c2ecf20Sopenharmony_ci		return;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	disable_uart_interrupts(sp->base_address);
578c2ecf20Sopenharmony_ci	serial8250_unregister_port(sp->serial_line);
588c2ecf20Sopenharmony_ci}
59