680 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Mediatek 8250 driver.4 *5 * Copyright (c) 2014 MundoReader S.L.6 * Author: Matthias Brugger <matthias.bgg@gmail.com>7 */8#include <linux/clk.h>9#include <linux/io.h>10#include <linux/module.h>11#include <linux/of_irq.h>12#include <linux/of_platform.h>13#include <linux/pinctrl/consumer.h>14#include <linux/platform_device.h>15#include <linux/pm_runtime.h>16#include <linux/serial_8250.h>17#include <linux/serial_reg.h>18#include <linux/console.h>19#include <linux/dma-mapping.h>20#include <linux/tty.h>21#include <linux/tty_flip.h>22 23#include "8250.h"24 25#define MTK_UART_HIGHS 0x09 /* Highspeed register */26#define MTK_UART_SAMPLE_COUNT 0x0a /* Sample count register */27#define MTK_UART_SAMPLE_POINT 0x0b /* Sample point register */28#define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */29#define MTK_UART_ESCAPE_DAT 0x10 /* Escape Character register */30#define MTK_UART_ESCAPE_EN 0x11 /* Escape Enable register */31#define MTK_UART_DMA_EN 0x13 /* DMA Enable register */32#define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */33#define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */34#define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */35#define MTK_UART_DEBUG0 0x1836#define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */37#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */38#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */39 40#define MTK_UART_EFR 38 /* I/O: Extended Features Register */41#define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */42#define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */43#define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */44#define MTK_UART_EFR_NO_SW_FC 0x0 /* no sw flow control */45#define MTK_UART_EFR_XON1_XOFF1 0xa /* XON1/XOFF1 as sw flow control */46#define MTK_UART_EFR_XON2_XOFF2 0x5 /* XON2/XOFF2 as sw flow control */47#define MTK_UART_EFR_SW_FC_MASK 0xf /* Enable CTS Modem status interrupt */48#define MTK_UART_EFR_HW_FC (MTK_UART_EFR_RTS | MTK_UART_EFR_CTS)49#define MTK_UART_DMA_EN_TX 0x250#define MTK_UART_DMA_EN_RX 0x551 52#define MTK_UART_ESCAPE_CHAR 0x77 /* Escape char added under sw fc */53#define MTK_UART_RX_SIZE 0x800054#define MTK_UART_TX_TRIGGER 155#define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE56 57#define MTK_UART_XON1 40 /* I/O: Xon character 1 */58#define MTK_UART_XOFF1 42 /* I/O: Xoff character 1 */59 60#ifdef CONFIG_SERIAL_8250_DMA61enum dma_rx_status {62 DMA_RX_START = 0,63 DMA_RX_RUNNING = 1,64 DMA_RX_SHUTDOWN = 2,65};66#endif67 68struct mtk8250_data {69 int line;70 unsigned int rx_pos;71 unsigned int clk_count;72 struct clk *uart_clk;73 struct clk *bus_clk;74 struct uart_8250_dma *dma;75#ifdef CONFIG_SERIAL_8250_DMA76 enum dma_rx_status rx_status;77#endif78 int rx_wakeup_irq;79};80 81/* flow control mode */82enum {83 MTK_UART_FC_NONE,84 MTK_UART_FC_SW,85 MTK_UART_FC_HW,86};87 88#ifdef CONFIG_SERIAL_8250_DMA89static void mtk8250_rx_dma(struct uart_8250_port *up);90 91static void mtk8250_dma_rx_complete(void *param)92{93 struct uart_8250_port *up = param;94 struct uart_8250_dma *dma = up->dma;95 struct mtk8250_data *data = up->port.private_data;96 struct tty_port *tty_port = &up->port.state->port;97 struct dma_tx_state state;98 int copied, total, cnt;99 unsigned char *ptr;100 unsigned long flags;101 102 if (data->rx_status == DMA_RX_SHUTDOWN)103 return;104 105 uart_port_lock_irqsave(&up->port, &flags);106 107 dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);108 total = dma->rx_size - state.residue;109 cnt = total;110 111 if ((data->rx_pos + cnt) > dma->rx_size)112 cnt = dma->rx_size - data->rx_pos;113 114 ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);115 copied = tty_insert_flip_string(tty_port, ptr, cnt);116 data->rx_pos += cnt;117 118 if (total > cnt) {119 ptr = (unsigned char *)(dma->rx_buf);120 cnt = total - cnt;121 copied += tty_insert_flip_string(tty_port, ptr, cnt);122 data->rx_pos = cnt;123 }124 125 up->port.icount.rx += copied;126 127 tty_flip_buffer_push(tty_port);128 129 mtk8250_rx_dma(up);130 131 uart_port_unlock_irqrestore(&up->port, flags);132}133 134static void mtk8250_rx_dma(struct uart_8250_port *up)135{136 struct uart_8250_dma *dma = up->dma;137 struct dma_async_tx_descriptor *desc;138 139 desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,140 dma->rx_size, DMA_DEV_TO_MEM,141 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);142 if (!desc) {143 pr_err("failed to prepare rx slave single\n");144 return;145 }146 147 desc->callback = mtk8250_dma_rx_complete;148 desc->callback_param = up;149 150 dma->rx_cookie = dmaengine_submit(desc);151 152 dma_async_issue_pending(dma->rxchan);153}154 155static void mtk8250_dma_enable(struct uart_8250_port *up)156{157 struct uart_8250_dma *dma = up->dma;158 struct mtk8250_data *data = up->port.private_data;159 int lcr = serial_in(up, UART_LCR);160 161 if (data->rx_status != DMA_RX_START)162 return;163 164 dma->rxconf.src_port_window_size = dma->rx_size;165 dma->rxconf.src_addr = dma->rx_addr;166 167 dma->txconf.dst_port_window_size = UART_XMIT_SIZE;168 dma->txconf.dst_addr = dma->tx_addr;169 170 serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |171 UART_FCR_CLEAR_XMIT);172 serial_out(up, MTK_UART_DMA_EN,173 MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX);174 175 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);176 serial_out(up, MTK_UART_EFR, UART_EFR_ECB);177 serial_out(up, UART_LCR, lcr);178 179 if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0)180 pr_err("failed to configure rx dma channel\n");181 if (dmaengine_slave_config(dma->txchan, &dma->txconf) != 0)182 pr_err("failed to configure tx dma channel\n");183 184 data->rx_status = DMA_RX_RUNNING;185 data->rx_pos = 0;186 mtk8250_rx_dma(up);187}188#endif189 190static int mtk8250_startup(struct uart_port *port)191{192#ifdef CONFIG_SERIAL_8250_DMA193 struct uart_8250_port *up = up_to_u8250p(port);194 struct mtk8250_data *data = port->private_data;195 196 /* disable DMA for console */197 if (uart_console(port))198 up->dma = NULL;199 200 if (up->dma) {201 data->rx_status = DMA_RX_START;202 kfifo_reset(&port->state->port.xmit_fifo);203 }204#endif205 memset(&port->icount, 0, sizeof(port->icount));206 207 return serial8250_do_startup(port);208}209 210static void mtk8250_shutdown(struct uart_port *port)211{212 struct uart_8250_port *up = up_to_u8250p(port);213 struct mtk8250_data *data = port->private_data;214 int irq = data->rx_wakeup_irq;215 216#ifdef CONFIG_SERIAL_8250_DMA217 if (up->dma)218 data->rx_status = DMA_RX_SHUTDOWN;219#endif220 221 serial8250_do_shutdown(port);222 223 if (irq >= 0)224 serial8250_do_set_mctrl(&up->port, TIOCM_RTS);225}226 227static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask)228{229 /* Port locked to synchronize UART_IER access against the console. */230 lockdep_assert_held_once(&up->port.lock);231 232 serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask));233}234 235static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask)236{237 /* Port locked to synchronize UART_IER access against the console. */238 lockdep_assert_held_once(&up->port.lock);239 240 serial_out(up, UART_IER, serial_in(up, UART_IER) | mask);241}242 243static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)244{245 struct uart_port *port = &up->port;246 int lcr = serial_in(up, UART_LCR);247 248 /* Port locked to synchronize UART_IER access against the console. */249 lockdep_assert_held_once(&port->lock);250 251 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);252 serial_out(up, MTK_UART_EFR, UART_EFR_ECB);253 serial_out(up, UART_LCR, lcr);254 lcr = serial_in(up, UART_LCR);255 256 switch (mode) {257 case MTK_UART_FC_NONE:258 serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);259 serial_out(up, MTK_UART_ESCAPE_EN, 0x00);260 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);261 serial_out(up, MTK_UART_EFR, serial_in(up, MTK_UART_EFR) &262 (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)));263 serial_out(up, UART_LCR, lcr);264 mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI |265 MTK_UART_IER_RTSI | MTK_UART_IER_CTSI);266 break;267 268 case MTK_UART_FC_HW:269 serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);270 serial_out(up, MTK_UART_ESCAPE_EN, 0x00);271 serial_out(up, UART_MCR, UART_MCR_RTS);272 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);273 274 /*enable hw flow control*/275 serial_out(up, MTK_UART_EFR, MTK_UART_EFR_HW_FC |276 (serial_in(up, MTK_UART_EFR) &277 (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));278 279 serial_out(up, UART_LCR, lcr);280 mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI);281 mtk8250_enable_intrs(up, MTK_UART_IER_CTSI | MTK_UART_IER_RTSI);282 break;283 284 case MTK_UART_FC_SW: /*MTK software flow control */285 serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);286 serial_out(up, MTK_UART_ESCAPE_EN, 0x01);287 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);288 289 /*enable sw flow control */290 serial_out(up, MTK_UART_EFR, MTK_UART_EFR_XON1_XOFF1 |291 (serial_in(up, MTK_UART_EFR) &292 (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));293 294 serial_out(up, MTK_UART_XON1, START_CHAR(port->state->port.tty));295 serial_out(up, MTK_UART_XOFF1, STOP_CHAR(port->state->port.tty));296 serial_out(up, UART_LCR, lcr);297 mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI);298 mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI);299 break;300 default:301 break;302 }303}304 305static void306mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,307 const struct ktermios *old)308{309 static const unsigned short fraction_L_mapping[] = {310 0, 1, 0x5, 0x15, 0x55, 0x57, 0x57, 0x77, 0x7F, 0xFF, 0xFF311 };312 static const unsigned short fraction_M_mapping[] = {313 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3314 };315 struct uart_8250_port *up = up_to_u8250p(port);316 unsigned int baud, quot, fraction;317 unsigned long flags;318 int mode;319 320#ifdef CONFIG_SERIAL_8250_DMA321 if (up->dma) {322 if (uart_console(port)) {323 devm_kfree(up->port.dev, up->dma);324 up->dma = NULL;325 } else {326 mtk8250_dma_enable(up);327 }328 }329#endif330 331 /*332 * Store the requested baud rate before calling the generic 8250333 * set_termios method. Standard 8250 port expects bauds to be334 * no higher than (uartclk / 16) so the baud will be clamped if it335 * gets out of that bound. Mediatek 8250 port supports speed336 * higher than that, therefore we'll get original baud rate back337 * after calling the generic set_termios method and recalculate338 * the speed later in this method.339 */340 baud = tty_termios_baud_rate(termios);341 342 serial8250_do_set_termios(port, termios, NULL);343 344 tty_termios_encode_baud_rate(termios, baud, baud);345 346 /*347 * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)348 *349 * We need to recalcualte the quot register, as the claculation depends350 * on the vaule in the highspeed register.351 *352 * Some baudrates are not supported by the chip, so we use the next353 * lower rate supported and update termios c_flag.354 *355 * If highspeed register is set to 3, we need to specify sample count356 * and sample point to increase accuracy. If not, we reset the357 * registers to their default values.358 */359 baud = uart_get_baud_rate(port, termios, old,360 port->uartclk / 16 / UART_DIV_MAX,361 port->uartclk);362 363 if (baud < 115200) {364 serial_port_out(port, MTK_UART_HIGHS, 0x0);365 quot = uart_get_divisor(port, baud);366 } else {367 serial_port_out(port, MTK_UART_HIGHS, 0x3);368 quot = DIV_ROUND_UP(port->uartclk, 256 * baud);369 }370 371 /*372 * Ok, we're now changing the port state. Do it with373 * interrupts disabled.374 */375 uart_port_lock_irqsave(port, &flags);376 377 /*378 * Update the per-port timeout.379 */380 uart_update_timeout(port, termios->c_cflag, baud);381 382 /* set DLAB we have cval saved in up->lcr from the call to the core */383 serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);384 serial_dl_write(up, quot);385 386 /* reset DLAB */387 serial_port_out(port, UART_LCR, up->lcr);388 389 if (baud >= 115200) {390 unsigned int tmp;391 392 tmp = (port->uartclk / (baud * quot)) - 1;393 serial_port_out(port, MTK_UART_SAMPLE_COUNT, tmp);394 serial_port_out(port, MTK_UART_SAMPLE_POINT,395 (tmp >> 1) - 1);396 397 /*count fraction to set fractoin register */398 fraction = ((port->uartclk * 100) / baud / quot) % 100;399 fraction = DIV_ROUND_CLOSEST(fraction, 10);400 serial_port_out(port, MTK_UART_FRACDIV_L,401 fraction_L_mapping[fraction]);402 serial_port_out(port, MTK_UART_FRACDIV_M,403 fraction_M_mapping[fraction]);404 } else {405 serial_port_out(port, MTK_UART_SAMPLE_COUNT, 0x00);406 serial_port_out(port, MTK_UART_SAMPLE_POINT, 0xff);407 serial_port_out(port, MTK_UART_FRACDIV_L, 0x00);408 serial_port_out(port, MTK_UART_FRACDIV_M, 0x00);409 }410 411 if ((termios->c_cflag & CRTSCTS) && (!(termios->c_iflag & CRTSCTS)))412 mode = MTK_UART_FC_HW;413 else if (termios->c_iflag & CRTSCTS)414 mode = MTK_UART_FC_SW;415 else416 mode = MTK_UART_FC_NONE;417 418 mtk8250_set_flow_ctrl(up, mode);419 420 if (uart_console(port))421 up->port.cons->cflag = termios->c_cflag;422 423 uart_port_unlock_irqrestore(port, flags);424 /* Don't rewrite B0 */425 if (tty_termios_baud_rate(termios))426 tty_termios_encode_baud_rate(termios, baud, baud);427}428 429static int __maybe_unused mtk8250_runtime_suspend(struct device *dev)430{431 struct mtk8250_data *data = dev_get_drvdata(dev);432 struct uart_8250_port *up = serial8250_get_port(data->line);433 434 /* wait until UART in idle status */435 while436 (serial_in(up, MTK_UART_DEBUG0));437 438 clk_disable_unprepare(data->bus_clk);439 440 return 0;441}442 443static int __maybe_unused mtk8250_runtime_resume(struct device *dev)444{445 struct mtk8250_data *data = dev_get_drvdata(dev);446 447 clk_prepare_enable(data->bus_clk);448 449 return 0;450}451 452static void453mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)454{455 if (!state)456 pm_runtime_get_sync(port->dev);457 458 serial8250_do_pm(port, state, old);459 460 if (state)461 pm_runtime_put_sync_suspend(port->dev);462}463 464#ifdef CONFIG_SERIAL_8250_DMA465static bool mtk8250_dma_filter(struct dma_chan *chan, void *param)466{467 return false;468}469#endif470 471static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p,472 struct mtk8250_data *data)473{474#ifdef CONFIG_SERIAL_8250_DMA475 int dmacnt;476#endif477 478 data->uart_clk = devm_clk_get(&pdev->dev, "baud");479 if (IS_ERR(data->uart_clk)) {480 /*481 * For compatibility with older device trees try unnamed482 * clk when no baud clk can be found.483 */484 data->uart_clk = devm_clk_get(&pdev->dev, NULL);485 if (IS_ERR(data->uart_clk)) {486 dev_warn(&pdev->dev, "Can't get uart clock\n");487 return PTR_ERR(data->uart_clk);488 }489 490 return 0;491 }492 493 data->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");494 if (IS_ERR(data->bus_clk))495 return PTR_ERR(data->bus_clk);496 497 data->dma = NULL;498#ifdef CONFIG_SERIAL_8250_DMA499 dmacnt = of_property_count_strings(pdev->dev.of_node, "dma-names");500 if (dmacnt == 2) {501 data->dma = devm_kzalloc(&pdev->dev, sizeof(*data->dma),502 GFP_KERNEL);503 if (!data->dma)504 return -ENOMEM;505 506 data->dma->fn = mtk8250_dma_filter;507 data->dma->rx_size = MTK_UART_RX_SIZE;508 data->dma->rxconf.src_maxburst = MTK_UART_RX_TRIGGER;509 data->dma->txconf.dst_maxburst = MTK_UART_TX_TRIGGER;510 }511#endif512 513 return 0;514}515 516static int mtk8250_probe(struct platform_device *pdev)517{518 struct uart_8250_port uart = {};519 struct mtk8250_data *data;520 struct resource *regs;521 int irq, err;522 523 irq = platform_get_irq(pdev, 0);524 if (irq < 0)525 return irq;526 527 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);528 if (!regs) {529 dev_err(&pdev->dev, "no registers defined\n");530 return -EINVAL;531 }532 533 uart.port.membase = devm_ioremap(&pdev->dev, regs->start,534 resource_size(regs));535 if (!uart.port.membase)536 return -ENOMEM;537 538 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);539 if (!data)540 return -ENOMEM;541 542 data->clk_count = 0;543 544 if (pdev->dev.of_node) {545 err = mtk8250_probe_of(pdev, &uart.port, data);546 if (err)547 return err;548 } else549 return -ENODEV;550 551 spin_lock_init(&uart.port.lock);552 uart.port.mapbase = regs->start;553 uart.port.irq = irq;554 uart.port.pm = mtk8250_do_pm;555 uart.port.type = PORT_16550;556 uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;557 uart.port.dev = &pdev->dev;558 uart.port.iotype = UPIO_MEM32;559 uart.port.regshift = 2;560 uart.port.private_data = data;561 uart.port.shutdown = mtk8250_shutdown;562 uart.port.startup = mtk8250_startup;563 uart.port.set_termios = mtk8250_set_termios;564 uart.port.uartclk = clk_get_rate(data->uart_clk);565#ifdef CONFIG_SERIAL_8250_DMA566 if (data->dma)567 uart.dma = data->dma;568#endif569 570 /* Disable Rate Fix function */571 writel(0x0, uart.port.membase +572 (MTK_UART_RATE_FIX << uart.port.regshift));573 574 platform_set_drvdata(pdev, data);575 576 data->line = serial8250_register_8250_port(&uart);577 if (data->line < 0)578 return data->line;579 580 data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);581 582 pm_runtime_set_active(&pdev->dev);583 pm_runtime_enable(&pdev->dev);584 585 return 0;586}587 588static void mtk8250_remove(struct platform_device *pdev)589{590 struct mtk8250_data *data = platform_get_drvdata(pdev);591 592 pm_runtime_get_sync(&pdev->dev);593 594 serial8250_unregister_port(data->line);595 596 pm_runtime_disable(&pdev->dev);597 pm_runtime_put_noidle(&pdev->dev);598}599 600static int __maybe_unused mtk8250_suspend(struct device *dev)601{602 struct mtk8250_data *data = dev_get_drvdata(dev);603 int irq = data->rx_wakeup_irq;604 int err;605 606 serial8250_suspend_port(data->line);607 608 pinctrl_pm_select_sleep_state(dev);609 if (irq >= 0) {610 err = enable_irq_wake(irq);611 if (err) {612 dev_err(dev,613 "failed to enable irq wake on IRQ %d: %d\n",614 irq, err);615 pinctrl_pm_select_default_state(dev);616 serial8250_resume_port(data->line);617 return err;618 }619 }620 621 return 0;622}623 624static int __maybe_unused mtk8250_resume(struct device *dev)625{626 struct mtk8250_data *data = dev_get_drvdata(dev);627 int irq = data->rx_wakeup_irq;628 629 if (irq >= 0)630 disable_irq_wake(irq);631 pinctrl_pm_select_default_state(dev);632 633 serial8250_resume_port(data->line);634 635 return 0;636}637 638static const struct dev_pm_ops mtk8250_pm_ops = {639 SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume)640 SET_RUNTIME_PM_OPS(mtk8250_runtime_suspend, mtk8250_runtime_resume,641 NULL)642};643 644static const struct of_device_id mtk8250_of_match[] = {645 { .compatible = "mediatek,mt6577-uart" },646 { /* Sentinel */ }647};648MODULE_DEVICE_TABLE(of, mtk8250_of_match);649 650static struct platform_driver mtk8250_platform_driver = {651 .driver = {652 .name = "mt6577-uart",653 .pm = &mtk8250_pm_ops,654 .of_match_table = mtk8250_of_match,655 },656 .probe = mtk8250_probe,657 .remove_new = mtk8250_remove,658};659module_platform_driver(mtk8250_platform_driver);660 661#ifdef CONFIG_SERIAL_8250_CONSOLE662static int __init early_mtk8250_setup(struct earlycon_device *device,663 const char *options)664{665 if (!device->port.membase)666 return -ENODEV;667 668 device->port.iotype = UPIO_MEM32;669 device->port.regshift = 2;670 671 return early_serial8250_setup(device, NULL);672}673 674OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup);675#endif676 677MODULE_AUTHOR("Matthias Brugger");678MODULE_LICENSE("GPL");679MODULE_DESCRIPTION("Mediatek 8250 serial port driver");680