0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/acpi.h>
0021 #include <linux/serial_reg.h>
0022 #include <linux/serial_8250.h>
0023
0024 #include "8250.h"
0025
0026 int fsl8250_handle_irq(struct uart_port *port)
0027 {
0028 unsigned long flags;
0029 u16 lsr, orig_lsr;
0030 unsigned int iir;
0031 struct uart_8250_port *up = up_to_u8250p(port);
0032
0033 spin_lock_irqsave(&up->port.lock, flags);
0034
0035 iir = port->serial_in(port, UART_IIR);
0036 if (iir & UART_IIR_NO_INT) {
0037 spin_unlock(&up->port.lock);
0038 return 0;
0039 }
0040
0041
0042 if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
0043 up->lsr_saved_flags &= ~UART_LSR_BI;
0044 port->serial_in(port, UART_RX);
0045 spin_unlock(&up->port.lock);
0046 return 1;
0047 }
0048
0049 lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
0050
0051
0052 if ((lsr & (UART_LSR_DR | UART_LSR_BI)) &&
0053 (up->ier & (UART_IER_RLSI | UART_IER_RDI))) {
0054 lsr = serial8250_rx_chars(up, lsr);
0055 }
0056
0057
0058 if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
0059 unsigned long delay;
0060
0061 up->ier = port->serial_in(port, UART_IER);
0062 if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
0063 port->ops->stop_rx(port);
0064 } else {
0065
0066
0067
0068 cancel_delayed_work(&up->overrun_backoff);
0069 }
0070
0071 delay = msecs_to_jiffies(up->overrun_backoff_time_ms);
0072 schedule_delayed_work(&up->overrun_backoff, delay);
0073 }
0074
0075 serial8250_modem_status(up);
0076
0077 if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
0078 serial8250_tx_chars(up);
0079
0080 up->lsr_saved_flags |= orig_lsr & UART_LSR_BI;
0081
0082 uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);
0083
0084 return 1;
0085 }
0086 EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
0087
0088 #ifdef CONFIG_ACPI
0089 struct fsl8250_data {
0090 int line;
0091 };
0092
0093 static int fsl8250_acpi_probe(struct platform_device *pdev)
0094 {
0095 struct fsl8250_data *data;
0096 struct uart_8250_port port8250;
0097 struct device *dev = &pdev->dev;
0098 struct resource *regs;
0099
0100 int ret, irq;
0101
0102 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0103 if (!regs) {
0104 dev_err(dev, "no registers defined\n");
0105 return -EINVAL;
0106 }
0107
0108 irq = platform_get_irq(pdev, 0);
0109 if (irq < 0)
0110 return irq;
0111
0112 memset(&port8250, 0, sizeof(port8250));
0113
0114 ret = device_property_read_u32(dev, "clock-frequency",
0115 &port8250.port.uartclk);
0116 if (ret)
0117 return ret;
0118
0119 spin_lock_init(&port8250.port.lock);
0120
0121 port8250.port.mapbase = regs->start;
0122 port8250.port.irq = irq;
0123 port8250.port.handle_irq = fsl8250_handle_irq;
0124 port8250.port.type = PORT_16550A;
0125 port8250.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
0126 | UPF_FIXED_PORT | UPF_IOREMAP
0127 | UPF_FIXED_TYPE;
0128 port8250.port.dev = dev;
0129 port8250.port.mapsize = resource_size(regs);
0130 port8250.port.iotype = UPIO_MEM;
0131 port8250.port.irqflags = IRQF_SHARED;
0132
0133 port8250.port.membase = devm_ioremap(dev, port8250.port.mapbase,
0134 port8250.port.mapsize);
0135 if (!port8250.port.membase)
0136 return -ENOMEM;
0137
0138 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0139 if (!data)
0140 return -ENOMEM;
0141
0142 data->line = serial8250_register_8250_port(&port8250);
0143 if (data->line < 0)
0144 return data->line;
0145
0146 platform_set_drvdata(pdev, data);
0147 return 0;
0148 }
0149
0150 static int fsl8250_acpi_remove(struct platform_device *pdev)
0151 {
0152 struct fsl8250_data *data = platform_get_drvdata(pdev);
0153
0154 serial8250_unregister_port(data->line);
0155 return 0;
0156 }
0157
0158 static const struct acpi_device_id fsl_8250_acpi_id[] = {
0159 { "NXP0018", 0 },
0160 { },
0161 };
0162 MODULE_DEVICE_TABLE(acpi, fsl_8250_acpi_id);
0163
0164 static struct platform_driver fsl8250_platform_driver = {
0165 .driver = {
0166 .name = "fsl-16550-uart",
0167 .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
0168 },
0169 .probe = fsl8250_acpi_probe,
0170 .remove = fsl8250_acpi_remove,
0171 };
0172
0173 module_platform_driver(fsl8250_platform_driver);
0174 #endif