2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-01 10:13:58 +08:00
linux-next/drivers/tty/serial/8250/8250_ingenic.c
Greg Kroah-Hartman 4793f2ebff tty: serial: Remove redundant license text
Now that the SPDX tag is in all tty files, that identifies the license
in a specific and legally-defined manner.  So the extra GPL text wording
can be removed as it is no longer needed at all.

This is done on a quest to remove the 700+ different ways that files in
the kernel describe the GPL license text.  And there's unneeded stuff
like the address (sometimes incorrect) for the FSF which is never
needed.

No copyright headers or other non-license-description text was removed.

Cc: Jiri Slaby <jslaby@suse.com>
Cc: Eric Anholt <eric@anholt.net>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>
Cc: Scott Branden <sbranden@broadcom.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Joachim Eastwood <manabian@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Pat Gefre <pfg@sgi.com>
Cc: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andy Gross <andy.gross@linaro.org>
Cc: David Brown <david.brown@linaro.org>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Peter Korsgaard <jacmet@sunsite.dk>
Cc: Timur Tabi <timur@tabi.org>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-08 13:08:12 +01:00

342 lines
8.2 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2010 Lars-Peter Clausen <lars@metafoo.de>
* Copyright (C) 2015 Imagination Technologies
*
* Ingenic SoC UART support
*/
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/libfdt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include "8250.h"
/** ingenic_uart_config: SOC specific config data. */
struct ingenic_uart_config {
int tx_loadsz;
int fifosize;
};
struct ingenic_uart_data {
struct clk *clk_module;
struct clk *clk_baud;
int line;
};
static const struct of_device_id of_match[];
#define UART_FCR_UME BIT(4)
#define UART_MCR_MDCE BIT(7)
#define UART_MCR_FCM BIT(6)
static struct earlycon_device *early_device;
static uint8_t early_in(struct uart_port *port, int offset)
{
return readl(port->membase + (offset << 2));
}
static void early_out(struct uart_port *port, int offset, uint8_t value)
{
writel(value, port->membase + (offset << 2));
}
static void ingenic_early_console_putc(struct uart_port *port, int c)
{
uint8_t lsr;
do {
lsr = early_in(port, UART_LSR);
} while ((lsr & UART_LSR_TEMT) == 0);
early_out(port, UART_TX, c);
}
static void ingenic_early_console_write(struct console *console,
const char *s, unsigned int count)
{
uart_console_write(&early_device->port, s, count,
ingenic_early_console_putc);
}
static void __init ingenic_early_console_setup_clock(struct earlycon_device *dev)
{
void *fdt = initial_boot_params;
const __be32 *prop;
int offset;
offset = fdt_path_offset(fdt, "/ext");
if (offset < 0)
return;
prop = fdt_getprop(fdt, offset, "clock-frequency", NULL);
if (!prop)
return;
dev->port.uartclk = be32_to_cpup(prop);
}
static int __init ingenic_early_console_setup(struct earlycon_device *dev,
const char *opt)
{
struct uart_port *port = &dev->port;
unsigned int baud, divisor;
if (!dev->port.membase)
return -ENODEV;
ingenic_early_console_setup_clock(dev);
baud = dev->baud ?: 115200;
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
early_out(port, UART_IER, 0);
early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
early_out(port, UART_DLL, 0);
early_out(port, UART_DLM, 0);
early_out(port, UART_LCR, UART_LCR_WLEN8);
early_out(port, UART_FCR, UART_FCR_UME | UART_FCR_CLEAR_XMIT |
UART_FCR_CLEAR_RCVR | UART_FCR_ENABLE_FIFO);
early_out(port, UART_MCR, UART_MCR_RTS | UART_MCR_DTR);
early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
early_out(port, UART_DLL, divisor & 0xff);
early_out(port, UART_DLM, (divisor >> 8) & 0xff);
early_out(port, UART_LCR, UART_LCR_WLEN8);
early_device = dev;
dev->con->write = ingenic_early_console_write;
return 0;
}
EARLYCON_DECLARE(jz4740_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart",
ingenic_early_console_setup);
EARLYCON_DECLARE(jz4775_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart",
ingenic_early_console_setup);
EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart",
ingenic_early_console_setup);
static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
{
int ier;
switch (offset) {
case UART_FCR:
/* UART module enable */
value |= UART_FCR_UME;
break;
case UART_IER:
/*
* Enable receive timeout interrupt with the receive line
* status interrupt.
*/
value |= (value & 0x4) << 2;
break;
case UART_MCR:
/*
* If we have enabled modem status IRQs we should enable
* modem mode.
*/
ier = p->serial_in(p, UART_IER);
if (ier & UART_IER_MSI)
value |= UART_MCR_MDCE | UART_MCR_FCM;
else
value &= ~(UART_MCR_MDCE | UART_MCR_FCM);
break;
default:
break;
}
writeb(value, p->membase + (offset << p->regshift));
}
static unsigned int ingenic_uart_serial_in(struct uart_port *p, int offset)
{
unsigned int value;
value = readb(p->membase + (offset << p->regshift));
/* Hide non-16550 compliant bits from higher levels */
switch (offset) {
case UART_FCR:
value &= ~UART_FCR_UME;
break;
case UART_MCR:
value &= ~(UART_MCR_MDCE | UART_MCR_FCM);
break;
default:
break;
}
return value;
}
static int ingenic_uart_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct ingenic_uart_data *data;
const struct ingenic_uart_config *cdata;
const struct of_device_id *match;
int err, line;
match = of_match_device(of_match, &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Error: No device match found\n");
return -ENODEV;
}
cdata = match->data;
if (!regs || !irq) {
dev_err(&pdev->dev, "no registers/irq defined\n");
return -EINVAL;
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
spin_lock_init(&uart.port.lock);
uart.port.type = PORT_16550A;
uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
uart.port.iotype = UPIO_MEM;
uart.port.mapbase = regs->start;
uart.port.regshift = 2;
uart.port.serial_out = ingenic_uart_serial_out;
uart.port.serial_in = ingenic_uart_serial_in;
uart.port.irq = irq->start;
uart.port.dev = &pdev->dev;
uart.port.fifosize = cdata->fifosize;
uart.tx_loadsz = cdata->tx_loadsz;
uart.capabilities = UART_CAP_FIFO | UART_CAP_RTOIE;
/* Check for a fixed line number */
line = of_alias_get_id(pdev->dev.of_node, "serial");
if (line >= 0)
uart.port.line = line;
uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
resource_size(regs));
if (!uart.port.membase)
return -ENOMEM;
data->clk_module = devm_clk_get(&pdev->dev, "module");
if (IS_ERR(data->clk_module)) {
err = PTR_ERR(data->clk_module);
if (err != -EPROBE_DEFER)
dev_err(&pdev->dev,
"unable to get module clock: %d\n", err);
return err;
}
data->clk_baud = devm_clk_get(&pdev->dev, "baud");
if (IS_ERR(data->clk_baud)) {
err = PTR_ERR(data->clk_baud);
if (err != -EPROBE_DEFER)
dev_err(&pdev->dev,
"unable to get baud clock: %d\n", err);
return err;
}
err = clk_prepare_enable(data->clk_module);
if (err) {
dev_err(&pdev->dev, "could not enable module clock: %d\n", err);
goto out;
}
err = clk_prepare_enable(data->clk_baud);
if (err) {
dev_err(&pdev->dev, "could not enable baud clock: %d\n", err);
goto out_disable_moduleclk;
}
uart.port.uartclk = clk_get_rate(data->clk_baud);
data->line = serial8250_register_8250_port(&uart);
if (data->line < 0) {
err = data->line;
goto out_disable_baudclk;
}
platform_set_drvdata(pdev, data);
return 0;
out_disable_baudclk:
clk_disable_unprepare(data->clk_baud);
out_disable_moduleclk:
clk_disable_unprepare(data->clk_module);
out:
return err;
}
static int ingenic_uart_remove(struct platform_device *pdev)
{
struct ingenic_uart_data *data = platform_get_drvdata(pdev);
serial8250_unregister_port(data->line);
clk_disable_unprepare(data->clk_module);
clk_disable_unprepare(data->clk_baud);
return 0;
}
static const struct ingenic_uart_config jz4740_uart_config = {
.tx_loadsz = 8,
.fifosize = 16,
};
static const struct ingenic_uart_config jz4760_uart_config = {
.tx_loadsz = 16,
.fifosize = 32,
};
static const struct ingenic_uart_config jz4780_uart_config = {
.tx_loadsz = 32,
.fifosize = 64,
};
static const struct of_device_id of_match[] = {
{ .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config },
{ .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4780-uart", .data = &jz4780_uart_config },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match);
static struct platform_driver ingenic_uart_platform_driver = {
.driver = {
.name = "ingenic-uart",
.of_match_table = of_match,
},
.probe = ingenic_uart_probe,
.remove = ingenic_uart_remove,
};
module_platform_driver(ingenic_uart_platform_driver);
MODULE_AUTHOR("Paul Burton");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Ingenic SoC UART driver");