From patchwork Sun Jul 15 02:44:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Domenico Andreoli X-Patchwork-Id: 1198421 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id B077DDF28B for ; Sun, 15 Jul 2012 03:07:35 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SqF4l-0003fp-Di; Sun, 15 Jul 2012 03:00:51 +0000 Received: from mail-wi0-f171.google.com ([209.85.212.171]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SqEqd-0008VU-9W for linux-arm-kernel@lists.infradead.org; Sun, 15 Jul 2012 02:46:48 +0000 Received: by wibhq4 with SMTP id hq4so1332955wib.0 for ; Sat, 14 Jul 2012 19:46:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:user-agent:date:from:to:cc:subject:references :content-disposition; bh=Agtfyx58wFb0/m4tnRmHb7cyi4l3bC8aBw97fBbaZz4=; b=UobRCRvYeN8L9uvBceSFEfcxrs6ie65ss3KrlUbzPV1+4h+MQbaau2EeWawqJn+M2D R/vNrah7nfFd1rPl5uSiAh0weFrSIwpdCQfSLpDwWhR4BAbBsRofTUzdKfc/mGYN8xjO 89/EIOslo7jqEX/PO1YmHHbX3XQdnIUJ/fNnqiCf3MStAgJAWleubu+rOn/7dxr1cMGB yxmf9UT1u9LQeza1/eZLWj8443y9V3RmxQYe82Wb/Ovg5QA7/bUuOMUs2F3dIfLwnfSX +/YpPkjTpT04C3Vs/cm7uf8kE6+G/gyssuua5+8gAVsnokwVjA8TiFOiwPcUGRsBLhux KN9Q== Received: by 10.216.27.7 with SMTP id d7mr3289056wea.187.1342320373158; Sat, 14 Jul 2012 19:46:13 -0700 (PDT) Received: from raptus.dandreoli.com (178-85-163-250.dynamic.upc.nl. [178.85.163.250]) by mx.google.com with ESMTPS id t7sm19279632wix.6.2012.07.14.19.46.11 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 14 Jul 2012 19:46:12 -0700 (PDT) Received: by raptus.dandreoli.com (Postfix, from userid 1000) id CD82F37B9FF; Sun, 15 Jul 2012 04:46:11 +0200 (CEST) Message-Id: <20120715024611.543242732@gmail.com> User-Agent: quilt/0.60-1 Date: Sun, 15 Jul 2012 04:44:19 +0200 From: Domenico Andreoli To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH 11/12] ARM: Decompressor support for Samsung UARTs References: <20120715024408.747946928@gmail.com> Content-Disposition: inline; filename=decomp-console-uart-samsung.patch X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.212.171 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (cavokz[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Domenico Andreoli , Russell King - ARM Linux , Arnd Bergmann X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Domenico Andreoli This driver is also taken from the existing Samsung's uncompress.h header file. Note how we use samsung specific struct samsung_decomp_console to specify parameters on a per-SoC basis. The intent is to have a single console data definition per SoC. So we can have one line for each board file using the s5p6450: DECOMP_CONSOLE_SOC(SOME6450, decomp_console_soc_s5p6450); Signed-off-by: Domenico Andreoli --- arch/arm/mach-s5p64x0/mach-smdk6450.c | 4 + drivers/tty/serial/Makefile | 2 drivers/tty/serial/samsung-decomp.c | 140 ++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) Index: b/drivers/tty/serial/Makefile =================================================================== --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o -obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o +obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o samsung-decomp.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o Index: b/drivers/tty/serial/samsung-decomp.c =================================================================== --- /dev/null +++ b/drivers/tty/serial/samsung-decomp.c @@ -0,0 +1,140 @@ +/* + * Decompressor support for Samsung UARTs + * + * Copyright (C) 2012 Domenico Andreoli + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ + +#include +#include +#include + +static const char samsung_drvname[] __decomp_archdata = "samsung-uart"; + +#define DECOMP_CONSOLE_SAMSUNG(_soc, _data) \ + DECOMP_CONSOLE_DATA(decomp_console_soc_##_soc, samsung_drvname, _data); + +struct samsung_decomp_console { + unsigned long base; + unsigned int fifo_mask; + unsigned int fifo_max; +}; + +/* s5p6450 serial ports */ +static const struct samsung_decomp_console + __decomp_console_data_s5p6450[] __decomp_archdata = { + { 0xec800000, }, + { 0xec800400, }, + { 0xec800800, }, + { 0xec800c00, }, +}; +DECOMP_CONSOLE_SAMSUNG(s5p6450, __decomp_console_data_s5p6450); + +static inline unsigned int uart_rd(unsigned long base, unsigned int reg) +{ + volatile unsigned int *p = (volatile unsigned int *) (base + reg); + return *p; +} + +static inline void uart_wr(unsigned long base, unsigned int reg, unsigned int val) +{ + volatile unsigned int *p = (volatile unsigned int *) (base + reg); + *p = val; +} + +#define samsung_decomp_console(_drv) ((struct samsung_decomp_console *) (_drv)->devdata) + +static int __decomp_arch samsung_decomp_probe(struct decomp_console_drv *drv) +{ + struct samsung_decomp_console *console = samsung_decomp_console(drv); + u32 fifocon; + int retries = 1000; + + /* this driver doesn't support probing of the base address */ + if (!console->base) + return -EINVAL; + + /* Enable the UART FIFOs if they are not enabled and our + * configuration says we should turn them on. + */ + if (console->fifo_mask && console->fifo_max && + IS_ENABLED(CONFIG_S3C_BOOT_UART_FORCE_FIFO)) { + fifocon = uart_rd(console->base, S3C2410_UFCON); + + if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { + fifocon |= S3C2410_UFCON_RESETBOTH; + uart_wr(console->base, S3C2410_UFCON, fifocon); + + /* wait for fifo reset to complete */ + while (retries--) { + fifocon = uart_rd(console->base, S3C2410_UFCON); + if (!(fifocon & S3C2410_UFCON_RESETBOTH)) + break; + barrier(); + } + } + } + + return retries ? 0 : -EBUSY; +} + +/* we can deal with the case the UARTs are being run + * in FIFO mode, so that we don't hold up our execution + * waiting for tx to happen... +*/ +static void __decomp_arch samsung_decomp_putc(struct decomp_console_drv *drv, int ch) +{ + struct samsung_decomp_console *console = samsung_decomp_console(drv); + + if (console->fifo_mask && console->fifo_max && + uart_rd(console->base, S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { + while (1) { + int level = uart_rd(console->base, S3C2410_UFSTAT); + level &= console->fifo_mask; + + if (level < console->fifo_max) + break; + } + } else { + /* not using fifos */ + while ((uart_rd(console->base, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) + barrier(); + } + + /* write byte to transmission register */ + uart_wr(console->base, S3C2410_UTXH, ch); +} + +static void __decomp_arch samsung_decomp_flush(struct decomp_console_drv *drv) +{ + struct samsung_decomp_console *console = samsung_decomp_console(drv); + + /* FIXME: not using fifos */ + while ((uart_rd(console->base, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) + barrier(); +} + +static const char samsung_dt_compat[][16] __decomp_archdata = { + "samsung-uart", + "", +}; + +DECOMP_CONSOLE_START("ttySAC") + .probe = samsung_decomp_probe, + .putc = samsung_decomp_putc, + .flush = samsung_decomp_flush, + .dt_compat = samsung_dt_compat, +DECOMP_CONSOLE_END Index: b/arch/arm/mach-s5p64x0/mach-smdk6450.c =================================================================== --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -26,6 +26,8 @@ #include #include +#include + #include