From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752415AbbJFHOA (ORCPT ); Tue, 6 Oct 2015 03:14:00 -0400 Received: from mail-db3on0074.outbound.protection.outlook.com ([157.55.234.74]:7526 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752278AbbJFHNx (ORCPT ); Tue, 6 Oct 2015 03:13:53 -0400 Authentication-Results: spf=fail (sender IP is 212.179.42.66) smtp.mailfrom=ezchip.com; gmail.com; dkim=none (message not signed) header.d=none;gmail.com; dmarc=none action=none header.from=ezchip.com; From: Noam Camus To: , CC: , , , , , , Noam Camus Subject: [v6] serial: 8250_dw: Add support for big-endian MMIO accesses Date: Tue, 6 Oct 2015 09:39:50 +0300 Message-ID: <1444113590-19722-2-git-send-email-noamc@ezchip.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1444113590-19722-1-git-send-email-noamc@ezchip.com> References: <1440493029-28760-2-git-send-email-noamc@ezchip.com> <1444113590-19722-1-git-send-email-noamc@ezchip.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-11.0.0.1191-8.000.1202-21860.005 X-TM-AS-Result: No--5.867900-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;DB3FFO11FD050;1:CRw4aWkFfhfw2OaFWwrYr5yfXW/1tnhd6J8wK4a7ib+TpPRfReBrp3xcwn3QCy+HLDFo3R2xawfJIwUdR87wXNG9fz88GKhBmiIbzWaO5tWodM6u+oUtcqztNnSRI35LNoWQh75aC4JLr571+enS1upGBPO9XegNeW2q1ggostCu84pfJLWWpNOkJAIox6rsQz0I6maJZY2mO+PLxbuj9XUkYB2MprzOM/d0XZ04eEVrAVpa7qinNVv2hoKERZwsXwspXWuXVcoZ7eWU+V02yf6jctggkvi6nS1R29bfFLrTmbMOFy1JH1loWB6owPgkd5PSODtvZFyVsV9bWOaCs8aBgKJLyyEHOKTz0IdmI6f482WSIY7tADSDWw2crIr6nkBUOP7xmv4hGovHEJDZ2A== X-Forefront-Antispam-Report: CIP:212.179.42.66;CTRY:IL;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(199003)(31014005)(189002)(50986999)(48376002)(189998001)(105606002)(5001770100001)(106466001)(5001970100001)(2950100001)(229853001)(5003940100001)(104016004)(5007970100001)(5008740100001)(33646002)(92566002)(50466002)(76176999)(50226001)(87936001)(46102003)(19580405001)(19580395003)(47776003)(77096005)(107886002)(11100500001)(6806005)(36756003)(85426001)(49486002)(86362001)(64706001)(4001430100001);DIR:OUT;SFP:1101;SCL:1;SRVR:DB4PR02MB191;H:ezex10.ezchip.com;FPR:;SPF:Fail;PTR:ezmail.ezchip.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;DB4PR02MB191;2:vu5+A2D0GKXi7fH5hQ2oLw0jVP1uK3CQWam1SrdGo3cxxcpDVb0a0hcRGB6p5DbGshEovyEO3qcTP3l4zHNgL6z/uCc1mNLcOwEQcQDu8dgEmTQvU0ATKm16qf5yynefqoiDMie5sblFoBDQP08Uh/3segJXYxbqKnedt0DYcPs=;3:r4T3I0JNlm9i7eNuP9pgjPEbu3AYl/DqclR2SFgO9kXMQJv4ETuYGKfJwrcm2u2CT1oyn/zbFRO02G8VdSgR3kjpkW+qkRkn1Q5v4MnaZABLYHzZMVcQPsj5W+EQ5T9hrKm4s1rhOVcEZVEqShP9NPVOdVkUI2gaB/WHblJzR/Mh18K6r4QunlzQlcuHfDTQU6H6DEs0xDX5jQXTZdcoJpWY5hTcsY022t2CKnCiK78=;25:lPu1YEx/52j7Oq9zHdzn1ItlgRbxIXMBITgM+JLWl1pCMe2kQFDAR+Ymtkp9FkXgjImidIWjsoQAjuVoi4KuNyAS+ktFIona9UmyFiYpECPFojwWtR8Lg9zoir0+czRFDMfaL4V+2p5+qo54AX6MiPqRfM0T2DJmMx9lUjz+COGPzGtruWv7sHOBbKpxSzY1hnLWVpW5ukn7ixy9MEA1h4BJu5IpaKqB4w7PrgSIx/+1OP19bL+If6YNCliHZ9oaA782QoTcQ9W926Itg4gihw==;20:2wqaNQLReh2YlWXozCBsvlv84nMIcl6h4vDZgVbeD0EK7g7Zhu87oXxwpZjueJFvR32wqNTW0FuVF5Hv3/mowGNR5px6yVshjpgGLG+HRjxUk9EZef3J9uFeX/W4/8431EdHQzYVBM83eXs3aTGCBVus2giYXKfsGb5Ziv35oOQ= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB4PR02MB191; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(520078)(3002001);SRVR:DB4PR02MB191;BCL:0;PCL:0;RULEID:;SRVR:DB4PR02MB191; X-Microsoft-Exchange-Diagnostics: 1;DB4PR02MB191;4:u0iZlQhuKFxi8X5Nzd0qaIsA5pc293tFc1wx2i1lMtz9KCfK1OIE0ouKWH+5ekLaDlk6ncivO6sN2mi1eO+0NRJWfUC+/mDvfDoSubm/0YYXJE9MtsDpq3y+gkuxY7bh3BnUwWhZn5+T/lyJXKyHf8ypLVr0Q9i/d06U7xBrujf4xrVFmwKI5iOeDG5qoX1gctBGfHWhc+lKVRSFahXD/uIYjraIBkXm5Pw4L7L3Hm2Ysy0uOPJLqV3p5HUL10aYouLIEPNqUVcRRv+xR2RuKjzWv06RdL5+thRs1wKLb51Y/jx/kRijR+VBllD3sfoHNG9nf+zhnByE3aZAnXPtkvhdfz2wvQsde7rz8Aqn7W0= X-Forefront-PRVS: 07215D0470 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB4PR02MB191;23:QeABFgHqm3uQpbDdoQ5mvXdscenq0qMQt8JB8zxVyY?= =?us-ascii?Q?4DDQsvW9o7NM81eERx5cS3kz+6Oqp30qK/Ry7fFXHU5zr/qQgRj9gyRo5EZc?= =?us-ascii?Q?R1u+uWoiDgW/ez2stQt85luttweJ8ltl+SqvQ07pULsVcNxIDCr4pJ9d9gKa?= =?us-ascii?Q?3FjopBusq+euXjIKn+AkoZ4ZTa4aCTv29QMC6KkDotqaeUwOUcEbmeOGlPCz?= =?us-ascii?Q?hZJcitM2nZkHs3DO/DwIQXeOhBUsImcFH6sI6SYjCTrAHr3ILAf204PHTn+a?= =?us-ascii?Q?y0Hex5FHD8ycRdlfn4C5Vr7eJ6PJnAZCmlUBEzdH3tJZzC5x+jnk1S2hmW3z?= =?us-ascii?Q?yCp1WlQKGvy7TKYG5iKmALXJ8Jt+a3UpsX+oIOLjvgTEtlawqLo/5L631FHL?= =?us-ascii?Q?/a3BSELQF4SNSAbAXh6gTvv61THQBTMdIQRkmBeKqL/taee2X3eXjGmM4Nwb?= =?us-ascii?Q?UX6caMLZ5u/WvccI+bNBTfeQRsa2KQU+c0bNq1Rl+ZRqcp7h8hlm9DDfrxex?= =?us-ascii?Q?1ilxjEknlJBOwLwYV5L1EPRUN0EQaMfJ/hysgWm7TdoFXYzQ3Fa7n2LSg+TK?= =?us-ascii?Q?XAQEEr/zdrVDEaulx9OjYuASWc6jAfvY5xByjLu5qJ32TozqkixsO6tYMrGI?= =?us-ascii?Q?fzC0ypOfHdxovG24UvjLPm1Af4nF/6E212kQuOgWjgKs/IULqKJ0Wr5gui6a?= =?us-ascii?Q?N9F3fIQvUhOTs9S+CqvyMLFubvqa61tGhxzpgGUi6aj1CNVauVZ7KqCmogWu?= =?us-ascii?Q?W3Vb0tfypz2ds+M1APX5b3viNw0IU/VwfDKrfCXvYUNgcSe1FytMG0CuBy7M?= =?us-ascii?Q?AxmJfrxh+dhlVTzFxiOkOoMcIYQMiILo22eBuacxB4Li200q2xAiDPWiKuIq?= =?us-ascii?Q?TxA9qxj5OThFW5UIx7mjXi56UwVZQgjPWIRsmfOklXz2D6R7zaRpTIdL2v6/?= =?us-ascii?Q?ZJadWYi2irqwrObfvkgKljGWqqt1qP/ET9nz/gVxli/IZV7zK3MuOKJgMGnF?= =?us-ascii?Q?TF9OQRT4lX1AC5QMzgKbAT99dwH9BrskRCz0ZKMiTFUJTkSJLiP5VtzlN314?= =?us-ascii?Q?+tagL7kP+YxOsx4ElNt8mAdkMFjKtaijkesgApQHLIsNfhEklV5hENxD1Qal?= =?us-ascii?Q?MK24HhkFo=3D?= X-Microsoft-Exchange-Diagnostics: 1;DB4PR02MB191;5:VGxs64U9CxaRmmN+esNHz7zFiglKxNmya2tsBDoq8w3jeHzZVefBPIOHla4RCUS/J0Q0B0TXUoIDSKB1V4XaUuabZwVNZAkJ+4tpnCe8Xdg3k9Jjjf0FFDtycp0qY5T9btsjU05Yp1Nr9YWpRd9OQQ==;24:AMY/a9kPoCzS7UsQOv+JrCVajvHG/SAxzQ8VO+srgSO+IkY7JXRwuj5+0Zv6l6wV5NCdXvWerncAmH2JGP0fXBIxK8P/zVeezj8DCk5qbiE=;20:kJtLbEvfN2cOgZh6+R0E/wApaW9QlaKFSlGQPdf6l7FgsFc5WmhzFKrhdvOgXzFfRhPP0n7Xvc26iM83q0JDYQ== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2015 06:40:51.0965 (UTC) X-MS-Exchange-CrossTenant-Id: 0fc16e0a-3cd3-4092-8b2f-0a42cff122c3 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0fc16e0a-3cd3-4092-8b2f-0a42cff122c3;Ip=[212.179.42.66];Helo=[ezex10.ezchip.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB4PR02MB191 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Noam Camus Add support for UPIO_MEM32BE in addition to UPIO_MEM32. dw8250_serial_out32() extra functionality that is not part of the 8250 core driver was moved to new function called dw8250_check_LCR(). For big endian we use 2 new accessors similar to little endian, called dw8250_serial_out32be() and dw8250_serial_in32be(). Both little and big endian accessors use dw8250_check_LCR() for their dw8250_serial_out32{,be}(). In addition I added another 2 accessors inside private_data field of uart_port. This second level accessors are set during probe in private_data field of uart_port. Now any direct call to readl/writel is replaced with those accessors which are endianness aware. Last issue: readl() for UCV and CPR will not work for port type UPIO_MEM32BE. Instead we use the serial_in32() accessor which is initialized properly according to endianness. Signed-off-by: Noam Camus --- drivers/tty/serial/8250/8250_dw.c | 72 ++++++++++++++++++++++++++++++++---- 1 files changed, 64 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 06324f1..2cb62cf 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -63,6 +63,9 @@ struct dw8250_data { struct clk *pclk; struct reset_control *rst; struct uart_8250_dma dma; + unsigned int (*serial_in)(const void __iomem *addr); + void (*serial_out)(unsigned int value, + void __iomem *addr); }; #define BYT_PRV_CLK 0x800 @@ -156,9 +159,9 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value) } #endif /* CONFIG_64BIT */ -static void dw8250_serial_out32(struct uart_port *p, int offset, int value) +static void dw8250_check_LCR(struct uart_port *p, int offset, int value) { - writel(value, p->membase + (offset << p->regshift)); + struct dw8250_data *d = p->private_data; /* Make sure LCR write wasn't ignored */ if (offset == UART_LCR) { @@ -168,7 +171,8 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value) if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) return; dw8250_force_idle(p); - writel(value, p->membase + (UART_LCR << p->regshift)); + d->serial_out(value, + p->membase + (UART_LCR << p->regshift)); } /* * FIXME: this deadlocks if port->lock is already held @@ -177,6 +181,22 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value) } } +static void _dw8250_serial_out32(unsigned int value, void __iomem *addr) +{ + writel(value, addr); +} + +static unsigned int _dw8250_serial_in32(const void __iomem *addr) +{ + return readl(addr); +} + +static void dw8250_serial_out32(struct uart_port *p, int offset, int value) +{ + writel(value, p->membase + (offset << p->regshift)); + dw8250_check_LCR(p, offset, value); +} + static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) { unsigned int value = readl(p->membase + (offset << p->regshift)); @@ -184,6 +204,29 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) return dw8250_modify_msr(p, offset, value); } +static void _dw8250_serial_out32be(unsigned int value, void __iomem *addr) +{ + iowrite32be(value, addr); +} + +static unsigned int _dw8250_serial_in32be(const void __iomem *addr) +{ + return ioread32be(addr); +} + +static void dw8250_serial_out32be(struct uart_port *p, int offset, int value) +{ + iowrite32be(value, p->membase + (offset << p->regshift)); + dw8250_check_LCR(p, offset, value); +} + +static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset) +{ + unsigned int value = ioread32be(p->membase + (offset << p->regshift)); + + return dw8250_modify_msr(p, offset, value); +} + static int dw8250_handle_irq(struct uart_port *p) { struct dw8250_data *d = p->private_data; @@ -252,7 +295,8 @@ static bool dw8250_dma_filter(struct dma_chan *chan, void *param) static void dw8250_setup_port(struct uart_8250_port *up) { struct uart_port *p = &up->port; - u32 reg = readl(p->membase + DW_UART_UCV); + struct dw8250_data *d = p->private_data; + u32 reg = d->serial_in(p->membase + DW_UART_UCV); /* * If the Component Version Register returns zero, we know that @@ -264,7 +308,7 @@ static void dw8250_setup_port(struct uart_8250_port *up) dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); - reg = readl(p->membase + DW_UART_CPR); + reg = d->serial_in(p->membase + DW_UART_CPR); if (!reg) return; @@ -305,9 +349,19 @@ static int dw8250_probe_of(struct uart_port *p, case 1: break; case 4: - p->iotype = UPIO_MEM32; - p->serial_in = dw8250_serial_in32; - p->serial_out = dw8250_serial_out32; + p->iotype = of_device_is_big_endian(np) ? + UPIO_MEM32BE : UPIO_MEM32; + if (p->iotype == UPIO_MEM32) { + p->serial_in = dw8250_serial_in32; + p->serial_out = dw8250_serial_out32; + data->serial_in = _dw8250_serial_in32; + data->serial_out = _dw8250_serial_out32; + } else { + p->serial_in = dw8250_serial_in32be; + p->serial_out = dw8250_serial_out32be; + data->serial_in = _dw8250_serial_in32be; + data->serial_out = _dw8250_serial_out32be; + } break; default: dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); @@ -487,6 +541,8 @@ static int dw8250_probe(struct platform_device *pdev) data->dma.rx_param = data; data->dma.tx_param = data; data->dma.fn = dw8250_dma_filter; + data->serial_in = _dw8250_serial_in32; + data->serial_out = _dw8250_serial_out32; uart.port.iotype = UPIO_MEM; uart.port.serial_in = dw8250_serial_in; -- 1.7.1