0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/console.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012
0013 #include "8250.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define UNIPHIER_UART_REGSHIFT 2
0025
0026
0027 #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT))
0028
0029 #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT))
0030
0031 #define UNIPHIER_UART_DLR (9 << (UNIPHIER_UART_REGSHIFT))
0032
0033 struct uniphier8250_priv {
0034 int line;
0035 struct clk *clk;
0036 spinlock_t atomic_write_lock;
0037 };
0038
0039 #ifdef CONFIG_SERIAL_8250_CONSOLE
0040 static int __init uniphier_early_console_setup(struct earlycon_device *device,
0041 const char *options)
0042 {
0043 if (!device->port.membase)
0044 return -ENODEV;
0045
0046
0047 device->port.iotype = UPIO_MEM32;
0048 device->port.regshift = UNIPHIER_UART_REGSHIFT;
0049
0050
0051
0052
0053
0054 device->baud = 0;
0055
0056 return early_serial8250_setup(device, options);
0057 }
0058 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart",
0059 uniphier_early_console_setup);
0060 #endif
0061
0062
0063
0064
0065
0066 static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
0067 {
0068 unsigned int valshift = 0;
0069
0070 switch (offset) {
0071 case UART_SCR:
0072
0073 valshift = 8;
0074 offset = UNIPHIER_UART_CHAR_FCR;
0075 break;
0076 case UART_LCR:
0077 valshift = 8;
0078 fallthrough;
0079 case UART_MCR:
0080 offset = UNIPHIER_UART_LCR_MCR;
0081 break;
0082 default:
0083 offset <<= UNIPHIER_UART_REGSHIFT;
0084 break;
0085 }
0086
0087
0088
0089
0090
0091
0092 return (readl(p->membase + offset) >> valshift) & 0xff;
0093 }
0094
0095 static void uniphier_serial_out(struct uart_port *p, int offset, int value)
0096 {
0097 unsigned int valshift = 0;
0098 bool normal = false;
0099
0100 switch (offset) {
0101 case UART_SCR:
0102
0103 valshift = 8;
0104 fallthrough;
0105 case UART_FCR:
0106 offset = UNIPHIER_UART_CHAR_FCR;
0107 break;
0108 case UART_LCR:
0109 valshift = 8;
0110
0111 value &= ~UART_LCR_DLAB;
0112 fallthrough;
0113 case UART_MCR:
0114 offset = UNIPHIER_UART_LCR_MCR;
0115 break;
0116 default:
0117 offset <<= UNIPHIER_UART_REGSHIFT;
0118 normal = true;
0119 break;
0120 }
0121
0122 if (normal) {
0123 writel(value, p->membase + offset);
0124 } else {
0125
0126
0127
0128
0129
0130 struct uniphier8250_priv *priv = p->private_data;
0131 unsigned long flags;
0132 u32 tmp;
0133
0134 spin_lock_irqsave(&priv->atomic_write_lock, flags);
0135 tmp = readl(p->membase + offset);
0136 tmp &= ~(0xff << valshift);
0137 tmp |= value << valshift;
0138 writel(tmp, p->membase + offset);
0139 spin_unlock_irqrestore(&priv->atomic_write_lock, flags);
0140 }
0141 }
0142
0143
0144
0145
0146
0147
0148 static int uniphier_serial_dl_read(struct uart_8250_port *up)
0149 {
0150 return readl(up->port.membase + UNIPHIER_UART_DLR);
0151 }
0152
0153 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
0154 {
0155 writel(value, up->port.membase + UNIPHIER_UART_DLR);
0156 }
0157
0158 static int uniphier_uart_probe(struct platform_device *pdev)
0159 {
0160 struct device *dev = &pdev->dev;
0161 struct uart_8250_port up;
0162 struct uniphier8250_priv *priv;
0163 struct resource *regs;
0164 void __iomem *membase;
0165 int irq;
0166 int ret;
0167
0168 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0169 if (!regs) {
0170 dev_err(dev, "failed to get memory resource\n");
0171 return -EINVAL;
0172 }
0173
0174 membase = devm_ioremap(dev, regs->start, resource_size(regs));
0175 if (!membase)
0176 return -ENOMEM;
0177
0178 irq = platform_get_irq(pdev, 0);
0179 if (irq < 0)
0180 return irq;
0181
0182 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0183 if (!priv)
0184 return -ENOMEM;
0185
0186 memset(&up, 0, sizeof(up));
0187
0188 ret = of_alias_get_id(dev->of_node, "serial");
0189 if (ret < 0) {
0190 dev_err(dev, "failed to get alias id\n");
0191 return ret;
0192 }
0193 up.port.line = ret;
0194
0195 priv->clk = devm_clk_get(dev, NULL);
0196 if (IS_ERR(priv->clk)) {
0197 dev_err(dev, "failed to get clock\n");
0198 return PTR_ERR(priv->clk);
0199 }
0200
0201 ret = clk_prepare_enable(priv->clk);
0202 if (ret)
0203 return ret;
0204
0205 up.port.uartclk = clk_get_rate(priv->clk);
0206
0207 spin_lock_init(&priv->atomic_write_lock);
0208
0209 up.port.dev = dev;
0210 up.port.private_data = priv;
0211 up.port.mapbase = regs->start;
0212 up.port.mapsize = resource_size(regs);
0213 up.port.membase = membase;
0214 up.port.irq = irq;
0215
0216 up.port.type = PORT_16550A;
0217 up.port.iotype = UPIO_MEM32;
0218 up.port.fifosize = 64;
0219 up.port.regshift = UNIPHIER_UART_REGSHIFT;
0220 up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
0221 up.capabilities = UART_CAP_FIFO;
0222
0223 if (of_property_read_bool(dev->of_node, "auto-flow-control"))
0224 up.capabilities |= UART_CAP_AFE;
0225
0226 up.port.serial_in = uniphier_serial_in;
0227 up.port.serial_out = uniphier_serial_out;
0228 up.dl_read = uniphier_serial_dl_read;
0229 up.dl_write = uniphier_serial_dl_write;
0230
0231 ret = serial8250_register_8250_port(&up);
0232 if (ret < 0) {
0233 dev_err(dev, "failed to register 8250 port\n");
0234 clk_disable_unprepare(priv->clk);
0235 return ret;
0236 }
0237 priv->line = ret;
0238
0239 platform_set_drvdata(pdev, priv);
0240
0241 return 0;
0242 }
0243
0244 static int uniphier_uart_remove(struct platform_device *pdev)
0245 {
0246 struct uniphier8250_priv *priv = platform_get_drvdata(pdev);
0247
0248 serial8250_unregister_port(priv->line);
0249 clk_disable_unprepare(priv->clk);
0250
0251 return 0;
0252 }
0253
0254 static int __maybe_unused uniphier_uart_suspend(struct device *dev)
0255 {
0256 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
0257 struct uart_8250_port *up = serial8250_get_port(priv->line);
0258
0259 serial8250_suspend_port(priv->line);
0260
0261 if (!uart_console(&up->port) || console_suspend_enabled)
0262 clk_disable_unprepare(priv->clk);
0263
0264 return 0;
0265 }
0266
0267 static int __maybe_unused uniphier_uart_resume(struct device *dev)
0268 {
0269 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
0270 struct uart_8250_port *up = serial8250_get_port(priv->line);
0271 int ret;
0272
0273 if (!uart_console(&up->port) || console_suspend_enabled) {
0274 ret = clk_prepare_enable(priv->clk);
0275 if (ret)
0276 return ret;
0277 }
0278
0279 serial8250_resume_port(priv->line);
0280
0281 return 0;
0282 }
0283
0284 static const struct dev_pm_ops uniphier_uart_pm_ops = {
0285 SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume)
0286 };
0287
0288 static const struct of_device_id uniphier_uart_match[] = {
0289 { .compatible = "socionext,uniphier-uart" },
0290 { }
0291 };
0292 MODULE_DEVICE_TABLE(of, uniphier_uart_match);
0293
0294 static struct platform_driver uniphier_uart_platform_driver = {
0295 .probe = uniphier_uart_probe,
0296 .remove = uniphier_uart_remove,
0297 .driver = {
0298 .name = "uniphier-uart",
0299 .of_match_table = uniphier_uart_match,
0300 .pm = &uniphier_uart_pm_ops,
0301 },
0302 };
0303 module_platform_driver(uniphier_uart_platform_driver);
0304
0305 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
0306 MODULE_DESCRIPTION("UniPhier UART driver");
0307 MODULE_LICENSE("GPL");