162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci * IBM ASM Service Processor Device Driver
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) IBM Corporation, 2004
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Author: Max Asböck <amax@us.ibm.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/termios.h>
1262306a36Sopenharmony_ci#include <linux/tty.h>
1362306a36Sopenharmony_ci#include <linux/serial_core.h>
1462306a36Sopenharmony_ci#include <linux/serial_reg.h>
1562306a36Sopenharmony_ci#include <linux/serial_8250.h>
1662306a36Sopenharmony_ci#include "ibmasm.h"
1762306a36Sopenharmony_ci#include "lowlevel.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_civoid ibmasm_register_uart(struct service_processor *sp)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	struct uart_8250_port uart;
2362306a36Sopenharmony_ci	void __iomem *iomem_base;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	iomem_base = sp->base_address + SCOUT_COM_B_BASE;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* read the uart scratch register to determine if the UART
2862306a36Sopenharmony_ci	 * is dedicated to the service processor or if the OS can use it
2962306a36Sopenharmony_ci	 */
3062306a36Sopenharmony_ci	if (0 == readl(iomem_base + UART_SCR)) {
3162306a36Sopenharmony_ci		dev_info(sp->dev, "IBM SP UART not registered, owned by service processor\n");
3262306a36Sopenharmony_ci		sp->serial_line = -1;
3362306a36Sopenharmony_ci		return;
3462306a36Sopenharmony_ci	}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	memset(&uart, 0, sizeof(uart));
3762306a36Sopenharmony_ci	uart.port.irq		= sp->irq;
3862306a36Sopenharmony_ci	uart.port.uartclk	= 3686400;
3962306a36Sopenharmony_ci	uart.port.flags		= UPF_SHARE_IRQ;
4062306a36Sopenharmony_ci	uart.port.iotype	= UPIO_MEM;
4162306a36Sopenharmony_ci	uart.port.membase	= iomem_base;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	sp->serial_line = serial8250_register_8250_port(&uart);
4462306a36Sopenharmony_ci	if (sp->serial_line < 0) {
4562306a36Sopenharmony_ci		dev_err(sp->dev, "Failed to register serial port\n");
4662306a36Sopenharmony_ci		return;
4762306a36Sopenharmony_ci	}
4862306a36Sopenharmony_ci	enable_uart_interrupts(sp->base_address);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_civoid ibmasm_unregister_uart(struct service_processor *sp)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	if (sp->serial_line < 0)
5462306a36Sopenharmony_ci		return;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	disable_uart_interrupts(sp->base_address);
5762306a36Sopenharmony_ci	serial8250_unregister_port(sp->serial_line);
5862306a36Sopenharmony_ci}
59