Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6286767a authored by Alexander Shiyan's avatar Alexander Shiyan Committed by Greg Kroah-Hartman
Browse files

serial: max310x: Register UART driver at module_init



This patch moves UART registration at module_init initcall,
so this should helps to add multiple chip support in the future.

Signed-off-by: default avatarAlexander Shiyan <shc_work@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0e8cc7c2
Loading
Loading
Loading
Loading
+48 −31
Original line number Diff line number Diff line
/*
 *  Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver
 *
 *  Copyright (C) 2012-2014 Alexander Shiyan <shc_work@mail.ru>
 *  Copyright (C) 2012-2016 Alexander Shiyan <shc_work@mail.ru>
 *
 *  Based on max3100.c, by Christian Pellegrin <chripell@evolware.org>
 *  Based on max3110.c, by Feng Tang <feng.tang@intel.com>
@@ -32,6 +32,7 @@
#define MAX310X_NAME			"max310x"
#define MAX310X_MAJOR			204
#define MAX310X_MINOR			209
#define MAX310X_UART_NR			4

/* MAX310X register definitions */
#define MAX310X_RHR_REG			(0x00) /* RX FIFO */
@@ -266,7 +267,6 @@ struct max310x_one {
};

struct max310x_port {
	struct uart_driver	uart;
	struct max310x_devtype	*devtype;
	struct regmap		*regmap;
	struct mutex		mutex;
@@ -277,6 +277,15 @@ struct max310x_port {
	struct max310x_one	p[0];
};

static struct uart_driver max310x_uart = {
	.owner		= THIS_MODULE,
	.driver_name	= MAX310X_NAME,
	.dev_name	= "ttyMAX",
	.major		= MAX310X_MAJOR,
	.minor		= MAX310X_MINOR,
	.nr		= MAX310X_UART_NR,
};

static u8 max310x_port_read(struct uart_port *port, u8 reg)
{
	struct max310x_port *s = dev_get_drvdata(port->dev);
@@ -716,13 +725,13 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
{
	struct max310x_port *s = (struct max310x_port *)dev_id;

	if (s->uart.nr > 1) {
	if (s->devtype->nr > 1) {
		do {
			unsigned int val = ~0;

			WARN_ON_ONCE(regmap_read(s->regmap,
						 MAX310X_GLOBALIRQ_REG, &val));
			val = ((1 << s->uart.nr) - 1) & ~val;
			val = ((1 << s->devtype->nr) - 1) & ~val;
			if (!val)
				break;
			max310x_port_irq(s, fls(val) - 1);
@@ -1019,8 +1028,8 @@ static int __maybe_unused max310x_suspend(struct device *dev)
	struct max310x_port *s = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < s->uart.nr; i++) {
		uart_suspend_port(&s->uart, &s->p[i].port);
	for (i = 0; i < s->devtype->nr; i++) {
		uart_suspend_port(&max310x_uart, &s->p[i].port);
		s->devtype->power(&s->p[i].port, 0);
	}

@@ -1032,9 +1041,9 @@ static int __maybe_unused max310x_resume(struct device *dev)
	struct max310x_port *s = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < s->uart.nr; i++) {
	for (i = 0; i < s->devtype->nr; i++) {
		s->devtype->power(&s->p[i].port, 1);
		uart_resume_port(&s->uart, &s->p[i].port);
		uart_resume_port(&max310x_uart, &s->p[i].port);
	}

	return 0;
@@ -1169,18 +1178,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
	uartclk = max310x_set_ref_clk(s, freq, xtal);
	dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);

	/* Register UART driver */
	s->uart.owner		= THIS_MODULE;
	s->uart.dev_name	= "ttyMAX";
	s->uart.major		= MAX310X_MAJOR;
	s->uart.minor		= MAX310X_MINOR;
	s->uart.nr		= devtype->nr;
	ret = uart_register_driver(&s->uart);
	if (ret) {
		dev_err(dev, "Registering UART driver failed\n");
		goto out_clk;
	}

#ifdef CONFIG_GPIOLIB
	/* Setup GPIO cotroller */
	s->gpio.owner		= THIS_MODULE;
@@ -1194,10 +1191,8 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
	s->gpio.ngpio		= devtype->nr * 4;
	s->gpio.can_sleep	= 1;
	ret = devm_gpiochip_add_data(dev, &s->gpio, s);
	if (ret) {
		uart_unregister_driver(&s->uart);
	if (ret)
		goto out_clk;
	}
#endif

	mutex_init(&s->mutex);
@@ -1231,7 +1226,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
		/* Initialize queue for changing RS485 mode */
		INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
		/* Register port */
		uart_add_one_port(&s->uart, &s->p[i].port);
		uart_add_one_port(&max310x_uart, &s->p[i].port);
		/* Go to suspend mode */
		devtype->power(&s->p[i].port, 0);
	}
@@ -1246,8 +1241,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,

	mutex_destroy(&s->mutex);

	uart_unregister_driver(&s->uart);

out_clk:
	clk_disable_unprepare(s->clk);

@@ -1259,16 +1252,15 @@ static int max310x_remove(struct device *dev)
	struct max310x_port *s = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < s->uart.nr; i++) {
	for (i = 0; i < s->devtype->nr; i++) {
		cancel_work_sync(&s->p[i].tx_work);
		cancel_work_sync(&s->p[i].md_work);
		cancel_work_sync(&s->p[i].rs_work);
		uart_remove_one_port(&s->uart, &s->p[i].port);
		uart_remove_one_port(&max310x_uart, &s->p[i].port);
		s->devtype->power(&s->p[i].port, 0);
	}

	mutex_destroy(&s->mutex);
	uart_unregister_driver(&s->uart);
	clk_disable_unprepare(s->clk);

	return 0;
@@ -1341,7 +1333,7 @@ static const struct spi_device_id max310x_id_table[] = {
};
MODULE_DEVICE_TABLE(spi, max310x_id_table);

static struct spi_driver max310x_uart_driver = {
static struct spi_driver max310x_spi_driver = {
	.driver = {
		.name		= MAX310X_NAME,
		.of_match_table	= of_match_ptr(max310x_dt_ids),
@@ -1351,9 +1343,34 @@ static struct spi_driver max310x_uart_driver = {
	.remove		= max310x_spi_remove,
	.id_table	= max310x_id_table,
};
module_spi_driver(max310x_uart_driver);
#endif

static int __init max310x_uart_init(void)
{
	int ret;

	ret = uart_register_driver(&max310x_uart);
	if (ret)
		return ret;

#ifdef CONFIG_SPI_MASTER
	spi_register_driver(&max310x_spi_driver);
#endif

	return 0;
}
module_init(max310x_uart_init);

static void __exit max310x_uart_exit(void)
{
#ifdef CONFIG_SPI_MASTER
	spi_unregister_driver(&max310x_spi_driver);
#endif

	uart_unregister_driver(&max310x_uart);
}
module_exit(max310x_uart_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
MODULE_DESCRIPTION("MAX310X serial driver");