From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752484AbbJFIyl (ORCPT ); Tue, 6 Oct 2015 04:54:41 -0400 Received: from mail-am1on0066.outbound.protection.outlook.com ([157.56.112.66]:12928 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751438AbbJFIyh (ORCPT ); Tue, 6 Oct 2015 04:54:37 -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: [v7] serial: 8250_dw: Add support for big-endian MMIO accesses Date: Tue, 6 Oct 2015 11:53:30 +0300 Message-ID: <1444121610-11832-2-git-send-email-noamc@ezchip.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1444121610-11832-1-git-send-email-noamc@ezchip.com> References: <1444113590-19722-1-git-send-email-noamc@ezchip.com> <1444121610-11832-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;AM1FFO11FD022;1:SH4v865kH7maFPzJdN+p6r+vPG61H/wpe8W1EkatNlU71KAFt4xWXeZrHLr6e3HbBzrs74lgZBZYbJZqbsRkEpaV3LR4ve46jXLsSaerwvu6p/PATFoTCV504Nv2TYuMZ+U4Eyv6R2oP38im9OSZUDeAL7GE1TzrN8m/rIHyK0E8vsxhhBmX5bkdqpxg/E1FgDMUueGwaeuujMYbVrSQ8XXtMnTPsp59D5CDC3Qrv+Ri/eSZd0vzve3CuWyOkQIQUc4X64i3ALPtz8POv0AI/Poal/IlsXH3MFfExqtKuLGIwGM4oqT+GRiPqLxi2q37fbe7skOkX9KQCSOEmk695rY/NcHLlhTuY0lDTcgysXRZB4oPqkPCFXNBdwiJaok/0PIpQzX39cSyrbsOuH52xg== X-Forefront-Antispam-Report: CIP:212.179.42.66;CTRY:IL;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1110001)(1109001)(339900001)(189002)(199003)(31014005)(47776003)(46102003)(50466002)(50986999)(48376002)(85426001)(5001970100001)(5007970100001)(87936001)(11100500001)(107886002)(64706001)(86362001)(19580395003)(49486002)(6806005)(19580405001)(189998001)(50226001)(76176999)(5008740100001)(77096005)(92566002)(36756003)(2950100001)(5003940100001)(106466001)(5001770100001)(104016004)(229853001)(105606002)(33646002)(4001430100001);DIR:OUT;SFP:1101;SCL:1;SRVR:HE1PR02MB1147;H:ezex10.ezchip.com;FPR:;SPF:Fail;PTR:ezmail.ezchip.com;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;HE1PR02MB1147;2:CmlaR31NWM/STdF1GHPzKVgxwuNyLVyoPIjIgh+vtl4LBUWbGcMjJPFyvNalWse1VJECE/df/Rv4TywGD8lFtxwLDSwj8i6awlrBxRPtv+oAAgC3QMeFdd1xsUi0WhyVLe7EX3t88kEBz55krRtCYkALPQHmRvx46NR4TDhMVh0=;3:kXJ4xYOd2n/ClrPohdn5qCOaE+oKBnv2SnmeBF2NEL3LeXYHC9ALXu0hyi0XTr4b5HU2ixNcO+YKQPNJU2Ft5enjNfSgW47pccOEDX7WKsWXQVrN5MnkW6A1bqfviMPaCx4Msl76Wc/bDoXyB+LOo8o0wG4p7OL7JIzGiFDIA56NJwa8tqte8sexv6K5gfTZRkbGUJw/AFvYF2QGmJag0QRBqWEqGzyYDmwJZ6S+tMc=;25:hU+EGwueM3LAT1c3HzkoOp8fAHgfNIx5u42u7KqE0yTKg4p68vW4usyx1o4FBz1+n6NwG9YJoTU0DBo42evG0TI2FwOXj2mGV9QnTicRx5Y6qzpxL5EvAqatY4XWaEB3vZYqCC3LcB/tIkp5AEWcw+QFvjG6IkVRtsukiPyMtIdH40zmYDzbE4cNVP1vv4d3jfYQ/KGWJ+AUbK8ntfQ5ul0mF/4kcdKdygmA24IroF/BBDA7giSmd3/BB7wnboLCIA7vKWwFO/EQIOK/CbZ0GA==;20:zUgNGRvJq13AQ1unHG0rPY0lJxmfpqbCFm8Tw8WeKwD4vQ0x0mjSNOT68D4AQHX+mc4b2ENZYWQQJebo2lYJ+jFhXw2od6tKXuE04mAMuwXwqguqLkGCVrDV7+YL4b1H64hgNGij6J+4EwCwj+sMSMcVWmrXkV0+r6KDOPHLgtE= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HE1PR02MB1147; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001);SRVR:HE1PR02MB1147;BCL:0;PCL:0;RULEID:;SRVR:HE1PR02MB1147; X-Microsoft-Exchange-Diagnostics: 1;HE1PR02MB1147;4:Ei7bpED1v8UgiUUpEd5sG33jN1OhCPo2ytnJsUXaUXzWCZlxYxczuMvoMAxMVygF1qfhItmIRVvONauwV9VXQfTIVbcL8lzeQNJwTvhNqal979mvJP1yRvN9Lvfo/7N/djTkV8gbO1A6RhJBRvamj3r+gNgx7cSAeiyP5P98wGfm/ReA6ryie2kHPsF3PymzWiDaaHFXw22BvIWec0VK2Z4cE4yiaWiv/ciPuyF2x9gJ03r//e4VtNNrXrhb8sXWo+XFHObsLXRjErcXmmzjUI6/7i4mo7vD6jDHn2g+gh+EYfqBr9MeC5s68ZrmqwsXINCkbSOsvSl4jVQCxRlnEEeEvjAWK7zzqivq6mwVj7g= X-Forefront-PRVS: 07215D0470 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HE1PR02MB1147;23:5B7EzsMrONBqJ5zX+MlgiFFnaODx7n/+Mqtr7yft6?= =?us-ascii?Q?nwVEcuK74SAKm/pYqF7CYNRAeQwYhmwrUCIef/DdqkiIfxFUtqATAhL5rYlm?= =?us-ascii?Q?Or5jqGX3MWXdQ0DH+sK1IKTKdaUyA81+m+4ir2BHgTLZfF/N1tLPJi4gKr8E?= =?us-ascii?Q?BA1Y6zRBTUslQIVuxvrx4cevkd1L/oZtl0WNNcEDudjEXzZhy1meR6P0Ltaj?= =?us-ascii?Q?u6RGltAPGplmUkVxJ5sZ0PqPkoLGT89rpExRdtnGoV8xQowGngy6wOnAH5dj?= =?us-ascii?Q?yAL6ODem4ogt1wuuJKVN/ou0R+7hCCsrUzaM4gV056ObvXNqEqQbfqfUB9fU?= =?us-ascii?Q?uC845mRN+Sxw3snXc24nmAilUj8eujkJGkdTPQtdmZS5P305avTc484co2ot?= =?us-ascii?Q?Ag7o32fQYdgJ05qDPurDSjL3xNx4Ko3w75fNqyTu1DrCVhAvUQpeSSb+sg9W?= =?us-ascii?Q?jcTsTUPYIbNBsUbEz9oxvviZ5vtFZz3JC+yBA8xdIEoVjKNmcG2csEBbpWc+?= =?us-ascii?Q?+z0ALWRDN11DsgAhUb/quegQF2CI9LWnXlomZlyiCpF6zw0DA2lfBwJCB4kU?= =?us-ascii?Q?TaP/DUB88wTassEwAyhPM4nuu1n/Z1J3Q7tH45jI946FEYdTD1Eu1LZ1IE+J?= =?us-ascii?Q?gdBNOrX9mpsLtcmAkOjncS/bGy6BY+KZhi9f8LmA/em5zbfSsXvWiPcYINqX?= =?us-ascii?Q?OVae39e/lTgydoLQqyIPaDoWwOBS206NrRFF579+uh/1AvK2EtG8NIhqib2F?= =?us-ascii?Q?jmoEE9HfJ5r3s/jkQPq+gFHUz7u8mxsCEW+WpQSLAv/7+Na6o0xfFbkbjHOT?= =?us-ascii?Q?SpjtyQdePRpK7nzBs5PrrW0NS2z1UOO5Yc3G0fHaU3kzhNdc0r22xJBXYWrN?= =?us-ascii?Q?L0QdwGJ7niooRCDMCBBxhe55Bj5tfZn21d7vpLWuSAJPQWNuWAbqdF/OYrtC?= =?us-ascii?Q?UgejLDLK6Q/uMqNHJnCwNkvOqj1BiAxc9yw2M5+0vSgbYq2CoRM2meR9snVM?= =?us-ascii?Q?h9BrQ/Nyk2LrAZqluMPEAl9CP7uFvHbfUnZ4JMxHrFInXrGlm8oVWBYfjFL/?= =?us-ascii?Q?x77TPNyxYss532gHWtMjraF6F6qd77MzmFjPfdrtIjKFIfwVou3WzRmytV7y?= =?us-ascii?Q?iV+6+q7m2Q=3D?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR02MB1147;5:z32fRQ+3oNpvqbPT1fmjq3CRZKdoPhIxhHP1rZvjCUtiWw9a52z3z0KUxU+xy5zLjQrGsJS0OnzFpARd7Z6bPK+DtulEY1cChrcS55mlgW2ad6WPA1n2VJzEZWnrGqR35i88WuY+q1axylNsKFGVqg==;24:UQJ9SIhbI1nNASnTcmmdO0nAQthQx/LG3WYeqlfeufAQzjYnVWIKc3MdfBXz0ZxoS7WYBA+wjE1Nys9NbmzEeodGtfiOY7Jqldu293BYze8=;20:y9YG3DwZ/6qom+ed8YGJouZt5IVcDOfvVguW1ccQWhcBhiQbzdDZKJuPv28YHyujLMWrSjHTJfpiBclxZ15BXg== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2015 08:54:27.2719 (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: HE1PR02MB1147 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..3beff92 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)(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(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(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