Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp2333634pxv; Sat, 17 Jul 2021 10:29:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWw4S/FFE4gXCP/yieFGYB7+vmqak3NAcWGYsQxMC/NXXkVkuFKOkOOt8F9k/T+FZG7/+X X-Received: by 2002:a02:9508:: with SMTP id y8mr13949641jah.28.1626542960900; Sat, 17 Jul 2021 10:29:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626542960; cv=none; d=google.com; s=arc-20160816; b=r7iusJk3gMScl5dZpltROY90dQ3HRHADO6cRJ09x+6UEDSxOvvTbalXq9v1I2vtTf8 hRqL3lgv+LwEGQYnKpFgbtDToBWtXfwtuluTV+Gs9zGMwmeA2Ouz1fD4+2M/QKmQauR8 tpEjWZKfVYYarsKwOpB3oaluOqY9yZOpkrriYWWs+kb/m8yEKwSWa6gqXVO2TXy+Ajb6 Qt6cSKJ4i1BNE1HwRRszs7e+2YFyQeqp5PRZE8dl0lVgFVSQMdeLfut6z1dEz+zPKha2 MUGcc3RFl39BdvWEcVmUpFN+Rz4AQvR4ahdjmiZAlt4YOPexFaLoEA1j7DS7b+KVtBti nYkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=JHiMbsp05pbGMAUABzAHsB0xUjHxzmh4UHPPdbARD7U=; b=MxD6Mt2GVtr/VSnNU4etEQy4JA9IJgP3T5YH8X0nCD3cPuriT8Q2JBXbeTo64EiPAu z22V/3pmoHfDFWWVg6gSdq3I90MlcQ+S6b6vdiVKPEIVSXRLp8Ay15fnJswnmKvJF57c 4UtPPG7kyCTowBVpBCNlxL7TI1kMYvCBfBPxzlL0tHX1dknXTvBbIvu/lekJQToucbb/ EPT1xQs5RpTn6I7XQdImctIigOOUeuqm9bMq8JnLo31jlfLPzGyKoiw4XC6ZxrAtZTi8 8xKLuSWUXZUX9rxwfNJ9mwynS9Bfp17TSeVNCtzbwDeB58urPC+Nl6mSnhUotizGS49U XVXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lunn.ch header.s=20171124 header.b=kcYCaWUa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g5si12651688ilb.152.2021.07.17.10.29.07; Sat, 17 Jul 2021 10:29:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@lunn.ch header.s=20171124 header.b=kcYCaWUa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232924AbhGQRaA (ORCPT + 99 others); Sat, 17 Jul 2021 13:30:00 -0400 Received: from vps0.lunn.ch ([185.16.172.187]:59922 "EHLO vps0.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232010AbhGQR36 (ORCPT ); Sat, 17 Jul 2021 13:29:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lunn.ch; s=20171124; h=In-Reply-To:Content-Transfer-Encoding:Content-Disposition: Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:From: Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Content-Disposition: In-Reply-To:References; bh=JHiMbsp05pbGMAUABzAHsB0xUjHxzmh4UHPPdbARD7U=; b=kc YCaWUaoFG8tUNAUF++VCslkyByjSaaAWsQzrmC1jXnzwsSL4hA9BkmFgJ5JovrTmWGkmrYhbmXEf7 nJnhND6SgI1xfIt1pr21UC6jhy4H3ScNJ7eLXsO5fcvyzGzIVdJfOfNwUPHKfL8r7N+UG9P+0c9I1 lE3zjbDC8Q5t2RQ=; Received: from andrew by vps0.lunn.ch with local (Exim 4.94.2) (envelope-from ) id 1m4o5T-00DkJo-MT; Sat, 17 Jul 2021 19:26:51 +0200 Date: Sat, 17 Jul 2021 19:26:51 +0200 From: Andrew Lunn To: Pali =?iso-8859-1?Q?Roh=E1r?= Cc: Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman , Gregory Clement , Sebastian Hesselbarth , Vladimir Vid , Marek =?iso-8859-1?Q?Beh=FAn?= , Geert Uytterhoeven , linux-clk@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v3 2/5] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Message-ID: References: <20210624224909.6350-1-pali@kernel.org> <20210717123829.5201-1-pali@kernel.org> <20210717123829.5201-3-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20210717123829.5201-3-pali@kernel.org> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Jul 17, 2021 at 02:38:26PM +0200, Pali Roh?r wrote: > @@ -445,6 +472,7 @@ static void mvebu_uart_shutdown(struct uart_port *port) > static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) > { > unsigned int d_divisor, m_divisor; > + unsigned long flags; > u32 brdv, osamp; > > if (!port->uartclk) > @@ -463,10 +491,12 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) > m_divisor = OSAMP_DEFAULT_DIVISOR; > d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor); > > + spin_lock_irqsave(&mvebu_uart_lock, flags); Hi Pali You only need spin_lock_irqsave() if you plan on taking the spinlock in an interrupt handler. It seems unlikely the baud rate will be changed in interrupt context? Please check, and then swap to plain spin_lock(). > brdv = readl(port->membase + UART_BRDV); > brdv &= ~BRDV_BAUD_MASK; > brdv |= d_divisor; > writel(brdv, port->membase + UART_BRDV); > + spin_unlock_irqrestore(&mvebu_uart_lock, flags); > > osamp = readl(port->membase + UART_OSAMP); > osamp &= ~OSAMP_DIVISORS_MASK; > + /* Recalculate UART1 divisor so UART1 baudrate does not change */ > + if (prev_clock_rate) { > + divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * > + parent_clock_rate * prev_d1d2, > + prev_clock_rate * d1 * d2); > + if (divisor < 1) > + divisor = 1; > + else if (divisor > BRDV_BAUD_MAX) > + divisor = BRDV_BAUD_MAX; > + val = (val & ~BRDV_BAUD_MASK) | divisor; > + } I don't see any range checks in the patch which verifies the requested baud rate is actually possible. With code like this, it seems like the baud rate change will be successful, but the actual baud rate will not be what is requested. > + /* Recalculate UART2 divisor so UART2 baudrate does not change */ > + if (prev_clock_rate) { > + val = readl(uart_clock_base->reg2); > + divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * > + parent_clock_rate * prev_d1d2, > + prev_clock_rate * d1 * d2); > + if (divisor < 1) > + divisor = 1; > + else if (divisor > BRDV_BAUD_MAX) > + divisor = BRDV_BAUD_MAX; > + val = (val & ~BRDV_BAUD_MASK) | divisor; > + writel(val, uart_clock_base->reg2); Here it looks like UART1 could request a baud rate change, which ends up setting the clocks so that UART2 is out of range? Could the change for UART1 be successful, but you end up breaking UART2? I'm thinking when you are at opposite ends of the scale. UART2 is running at 110baud and UART1 at 230400baud. Andrew