Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp3941715imm; Mon, 4 Jun 2018 11:52:06 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJjJzSN0N9LDGFcN1NGNZgD6bB81RZ13hI1BNxA8iGhYQQJ/8FwqiBvrmEQCepFL6N01l4d X-Received: by 2002:a17:902:28ab:: with SMTP id f40-v6mr23072711plb.208.1528138326098; Mon, 04 Jun 2018 11:52:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528138326; cv=none; d=google.com; s=arc-20160816; b=J9o3ywcDuvCjW6RIiDykuyJ5bY2FW1/B1xopDolkL4GrIRwcdLixIB58DR7t681/9y 4l9zaqe6MlvI69CUqLp3YQIGCnN62GshC+XeqG9wEYKWfpO7Z/ml9Kpsuc1ZA6KDfU6A mu8F77GAKN1IBtc2wRak/wnRXcx4FLgwSAeIwO+jzJt5OEjXJ4s/byRAqiUxg2jbHEwI vHWqPOGsBik60sVzQH6LvIi87jYznr7vYzyGjRkCak7tAhnkHb2kr0uMZyDoCDEu2MBG KLSuQSaYz+7C+2CRuzz3xxB950NyzDtjEPEyYfkdLwlDPar1MNo6Dp2SayErdE9jIe68 DLuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=FvjN8j9fkLYARSi7x1WcsP1duGneqjeJMdnmQXedi0Q=; b=A+v5EGdhGK50se8Dd4sOC6dP7d0Gk9K94gCt6vMDCV2U3MLqI5oYSc7qWpnUQ8xX9Z SDUPjZN7f17VjRduzmZVBLL1dHHDll7VuWdLi2ni6dpBqkjgZKc/3ZLGQ1JVVjTuzvBr zkeQdXmvZvNCS60Mf08ScwaKU56QdOf6Tc8Cad9dUuANNwmyzIYo99ltW82Sw2k4Nup5 rfpRkqBc32QL5YYmOh8uQAbSwibVAJ42IiR3Cd2sjRlZ4VcVlDxDQm1x+pQK69UspX+T 7+4n1Pjx6REBIllTUtr6f15JnPAp49aWoBBYDljZrQg3t78QJHWLFAAuwPDnejzjdrFV LT0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=temperror (no key for signature) header.i=@micronovasrl.com header.s=dkim header.b=CT04ZG18; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s4-v6si3136766pfs.157.2018.06.04.11.51.33; Mon, 04 Jun 2018 11:52:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=temperror (no key for signature) header.i=@micronovasrl.com header.s=dkim header.b=CT04ZG18; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751396AbeFDSuI (ORCPT + 99 others); Mon, 4 Jun 2018 14:50:08 -0400 Received: from mail.micronovasrl.com ([212.103.203.10]:60364 "EHLO mail.micronovasrl.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751042AbeFDSuF (ORCPT ); Mon, 4 Jun 2018 14:50:05 -0400 Received: from mail.micronovasrl.com (mail.micronovasrl.com [127.0.0.1]) by mail.micronovasrl.com (Postfix) with ESMTP id A806DB00721 for ; Mon, 4 Jun 2018 20:50:03 +0200 (CEST) Authentication-Results: mail.micronovasrl.com (amavisd-new); dkim=pass reason="pass (just generated, assumed good)" header.d=micronovasrl.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=micronovasrl.com; h=content-transfer-encoding:content-language:content-type :content-type:in-reply-to:mime-version:user-agent:date:date :message-id:from:from:references:to:subject:subject; s=dkim; t= 1528138203; x=1529002204; bh=5WS4qv/3SLywHwFP9YbHFXa29XgRk1bg7pX Vc61gprY=; b=CT04ZG18/EYNBck/oG3PodHmglgc74nuHnjpkaFOU3LKTKOv13E 9wQrAw0kvhnSuQIUQ5MkCmdDmyzgsMxChJmG9piyOx9HQxUxCv8zqt2jtPuAu6iW Xk+/JAaH97Nhn0ExyT7BgfFNO3umd8QCqCI7KpJCyVBjtqXL1bINN/cA= X-Virus-Scanned: Debian amavisd-new at mail.micronovasrl.com X-Spam-Flag: NO X-Spam-Score: -2.9 X-Spam-Level: X-Spam-Status: No, score=-2.9 tagged_above=-10 required=4.5 tests=[ALL_TRUSTED=-1, BAYES_00=-1.9] autolearn=unavailable autolearn_force=no Received: from mail.micronovasrl.com ([127.0.0.1]) by mail.micronovasrl.com (mail.micronovasrl.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id EGEHZ-g5HoEK for ; Mon, 4 Jun 2018 20:50:03 +0200 (CEST) Received: from [192.168.2.109] (62-11-51-166.dialup.tiscali.it [62.11.51.166]) by mail.micronovasrl.com (Postfix) with ESMTPSA id 23212B0029C; Mon, 4 Jun 2018 20:50:00 +0200 (CEST) Subject: Re: [PATCH 4/8] serial: 8250: Handle case port doesn't have TEMT interrupt using em485. To: "Matwey V. Kornilov" , Greg Kroah-Hartman Cc: Jiri Slaby , Andy Shevchenko , Kees Cook , Matthias Brugger , Allen Pais , Sean Young , Ed Blake , Stefan Potyra , Philipp Zabel , Joshua Scott , Vignesh R , Rolf Evers-Fischer , Aaron Sierra , Rafael Gago , Joel Stanley , Sean Wang , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org References: <20180601124021.102970-1-giulio.benetti@micronovasrl.com> <20180601124021.102970-5-giulio.benetti@micronovasrl.com> From: Giulio Benetti Message-ID: Date: Mon, 4 Jun 2018 20:50:01 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: it Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Il 04/06/2018 19:40, Matwey V. Kornilov ha scritto: > 01.06.2018 15:40, Giulio Benetti пишет: >> Some 8250 ports only have TEMT interrupt, so current implementation >> can't work for ports without it. The only chance to make it work is to >> loop-read on LSR register. >> >> With NO TEMT interrupt check if both TEMT and THRE are set looping on >> LSR register. >> >> Signed-off-by: Giulio Benetti >> --- >> drivers/tty/serial/8250/8250.h | 2 +- >> drivers/tty/serial/8250/8250_dw.c | 2 +- >> drivers/tty/serial/8250/8250_omap.c | 2 +- >> drivers/tty/serial/8250/8250_port.c | 26 ++++++++++++++++++-------- >> include/linux/serial_8250.h | 1 + >> 5 files changed, 22 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h >> index ebfb0bd5bef5..5c6ae5f69432 100644 >> --- a/drivers/tty/serial/8250/8250.h >> +++ b/drivers/tty/serial/8250/8250.h >> @@ -136,7 +136,7 @@ void serial8250_rpm_put(struct uart_8250_port *p); >> void serial8250_rpm_get_tx(struct uart_8250_port *p); >> void serial8250_rpm_put_tx(struct uart_8250_port *p); >> >> -int serial8250_em485_init(struct uart_8250_port *p); >> +int serial8250_em485_init(struct uart_8250_port *p, bool has_temt_isr); >> void serial8250_em485_destroy(struct uart_8250_port *p); >> >> static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) >> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c >> index 0f8b4da03d4e..888280ff5451 100644 >> --- a/drivers/tty/serial/8250/8250_dw.c >> +++ b/drivers/tty/serial/8250/8250_dw.c >> @@ -330,7 +330,7 @@ static int dw8250_rs485_config(struct uart_port *p, >> * are idempotent >> */ >> if (rs485->flags & SER_RS485_ENABLED) { >> - int ret = serial8250_em485_init(up); >> + int ret = serial8250_em485_init(up, false); >> >> if (ret) { >> rs485->flags &= ~SER_RS485_ENABLED; >> diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c >> index 624b501fd253..ab483c8b30c8 100644 >> --- a/drivers/tty/serial/8250/8250_omap.c >> +++ b/drivers/tty/serial/8250/8250_omap.c >> @@ -725,7 +725,7 @@ static int omap_8250_rs485_config(struct uart_port *port, >> * are idempotent >> */ >> if (rs485->flags & SER_RS485_ENABLED) { >> - int ret = serial8250_em485_init(up); >> + int ret = serial8250_em485_init(up, true); >> >> if (ret) { >> rs485->flags &= ~SER_RS485_ENABLED; >> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c >> index 95833cbc4338..e14badbbf181 100644 >> --- a/drivers/tty/serial/8250/8250_port.c >> +++ b/drivers/tty/serial/8250/8250_port.c >> @@ -599,15 +599,16 @@ EXPORT_SYMBOL_GPL(serial8250_rpm_put); >> /** >> * serial8250_em485_init() - put uart_8250_port into rs485 emulating >> * @p: uart_8250_port port instance >> + * @p: bool specify if 8250 port has TEMT interrupt or not >> * >> * The function is used to start rs485 software emulating on the >> * &struct uart_8250_port* @p. Namely, RTS is switched before/after >> * transmission. The function is idempotent, so it is safe to call it >> * multiple times. >> * >> - * The caller MUST enable interrupt on empty shift register before >> - * calling serial8250_em485_init(). This interrupt is not a part of >> - * 8250 standard, but implementation defined. >> + * If has_temt_isr is passed as true, the caller MUST enable interrupt >> + * on empty shift register before calling serial8250_em485_init(). >> + * This interrupt is not a part of 8250 standard, but implementation defined. >> * >> * The function is supposed to be called from .rs485_config callback >> * or from any other callback protected with p->port.lock spinlock. >> @@ -616,7 +617,7 @@ EXPORT_SYMBOL_GPL(serial8250_rpm_put); >> * >> * Return 0 - success, -errno - otherwise >> */ >> -int serial8250_em485_init(struct uart_8250_port *p) >> +int serial8250_em485_init(struct uart_8250_port *p, bool has_temt_isr) >> { >> if (p->em485) >> return 0; >> @@ -633,6 +634,7 @@ int serial8250_em485_init(struct uart_8250_port *p) >> p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx; >> p->em485->port = p; >> p->em485->active_timer = NULL; >> + p->em485->has_temt_isr = has_temt_isr; >> serial8250_em485_rts_after_send(p); >> >> return 0; >> @@ -1517,11 +1519,19 @@ static inline void __stop_tx(struct uart_8250_port *p) >> /* >> * To provide required timeing and allow FIFO transfer, >> * __stop_tx_rs485() must be called only when both FIFO and >> - * shift register are empty. It is for device driver to enable >> - * interrupt on TEMT. >> + * shift register are empty. If 8250 port supports it, >> + * it is for device driver to enable interrupt on TEMT. >> + * Otherwise must loop-read until TEMT and THRE flags are set. >> */ >> - if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) >> - return; >> + if (em485->has_temt_isr) { >> + if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) >> + return; >> + } else { >> + while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) { >> + lsr = serial_in(p, UART_LSR); >> + cpu_relax(); >> + } > > What happens if TEMP never be empty after interruption occurring? > I've added the field has_temt_isr to identify if peripheral provides or not TEMT interrupt. In DW case, differentely from OMAP case, there is not TEMT interrupt, at least on Datasheet I've found. At this time I don't have access to latest Datasheet. Specifying has_temt_isr = false during serial8250_em485_init(), I assume TEMT interrupt is not available and also is not enabled. IMHO the only possible case to loop inside there is if shift register is costantly filled, but soon or late it will get empty(hope I didn't miss something). -- Giulio Benetti CTO MICRONOVA SRL Sede: Via A. Niedda 3 - 35010 Vigonza (PD) Tel. 049/8931563 - Fax 049/8931346 Cod.Fiscale - P.IVA 02663420285 Capitale Sociale € 26.000 i.v. Iscritta al Reg. Imprese di Padova N. 02663420285 Numero R.E.A. 258642