All of lore.kernel.org
 help / color / mirror / Atom feed
From: Doug Anderson <dianders@chromium.org>
To: David Wu <david.wu@rock-chips.com>
Cc: "Heiko Stübner" <heiko@sntech.de>,
	"Wolfram Sang" <wsa@the-dreams.de>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Andy Shevchenko" <andy.shevchenko@gmail.com>,
	"Pawel Moll" <pawel.moll@arm.com>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Ian Campbell" <ijc+devicetree@hellion.org.uk>,
	"Kumar Gala" <galak@codeaurora.org>,
	"Brian Norris" <briannorris@google.com>,
	"David Riley" <davidriley@google.com>,
	"Tao Huang" <huangtao@rock-chips.com>,
	"Lin Huang" <hl@rock-chips.com>,
	"Jianqun Xu" <xjq@rock-chips.com>, Chris <zyw@rock-chips.com>,
	"Eddie Cai" <cf@rock-chips.com>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"open list:ARM/Rockchip SoC..."
	<linux-rockchip@lists.infradead.org>,
	"linux-i2c@vger.kernel.org" <linux-i2c@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v8 7/8] i2c: rk3x: add i2c support for rk3399 soc
Date: Wed, 11 May 2016 10:37:57 -0700	[thread overview]
Message-ID: <CAD=FV=Uf-U3RBpgFbR3LkPAJTWqz3d02+H7iyA-SS-y=r3cXjA@mail.gmail.com> (raw)
In-Reply-To: <1462908698-27284-1-git-send-email-david.wu@rock-chips.com>

Hi,

On Tue, May 10, 2016 at 12:31 PM, David Wu <david.wu@rock-chips.com> wrote:
>  static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
>  {
>         struct i2c_timings *t = &i2c->t;
>         struct rk3x_i2c_calced_timings calc;
>         u64 t_low_ns, t_high_ns;
> +       u32 val;
>         int ret;
>
> -       ret = rk3x_i2c_calc_divs(clk_rate, t, &calc);
> +       ret = i2c->soc_data->calc_timings(clk_rate, t, &calc);
>         WARN_ONCE(ret != 0, "Could not reach SCL freq %u", t->bus_freq_hz);
>
> -       clk_enable(i2c->clk);
> +       clk_enable(i2c->pclk);
> +
>         i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff),
>                    REG_CLKDIV);
> -       clk_disable(i2c->clk);
> +
> +       val = i2c_readl(i2c, REG_CON);
> +       val &= ~REG_CON_TUNING_MASK;
> +       val |= calc.tuning;
> +       i2c_writel(i2c, val, REG_CON);

Another subtle bug here.  You need to be holding the spinlock here
since you're doing a read-modify-write of a register that is also
touched by the interrupt handler.  We never needed it before because
the previous register update wasn't touched by anyone else and it was
a single atomic write.

Also: technically if we are midway through a transfer when all this
happens then there will be a very short period of time when the two
timing-related registers won't match with each other.  I have no idea
how much that would matter, but in the very least it seems wise to
minimize the time where they mismatch.  So I'd probably write:

       spin_lock_irqsave(&i2c->lock, flags);
       val = i2c_readl(i2c, REG_CON);
       val &= ~REG_CON_TUNING_MASK;
       val |= calc.tuning;
       i2c_writel(i2c, val, REG_CON);
       i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff),
                  REG_CLKDIV);
       spin_unlock_irqrestore(&i2c->lock, flags);

...if we really end up with on a system with a dynamically changing
clock that uses the new-style timing and we see real problems, we can
always try to come up with a way to avoid any problems.  Sound OK?


Otherwise, I think things look good to me.  Caesar's comments would
also be good to fix.


-Doug

WARNING: multiple messages have this Message-ID (diff)
From: dianders@chromium.org (Doug Anderson)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v8 7/8] i2c: rk3x: add i2c support for rk3399 soc
Date: Wed, 11 May 2016 10:37:57 -0700	[thread overview]
Message-ID: <CAD=FV=Uf-U3RBpgFbR3LkPAJTWqz3d02+H7iyA-SS-y=r3cXjA@mail.gmail.com> (raw)
In-Reply-To: <1462908698-27284-1-git-send-email-david.wu@rock-chips.com>

Hi,

On Tue, May 10, 2016 at 12:31 PM, David Wu <david.wu@rock-chips.com> wrote:
>  static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
>  {
>         struct i2c_timings *t = &i2c->t;
>         struct rk3x_i2c_calced_timings calc;
>         u64 t_low_ns, t_high_ns;
> +       u32 val;
>         int ret;
>
> -       ret = rk3x_i2c_calc_divs(clk_rate, t, &calc);
> +       ret = i2c->soc_data->calc_timings(clk_rate, t, &calc);
>         WARN_ONCE(ret != 0, "Could not reach SCL freq %u", t->bus_freq_hz);
>
> -       clk_enable(i2c->clk);
> +       clk_enable(i2c->pclk);
> +
>         i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff),
>                    REG_CLKDIV);
> -       clk_disable(i2c->clk);
> +
> +       val = i2c_readl(i2c, REG_CON);
> +       val &= ~REG_CON_TUNING_MASK;
> +       val |= calc.tuning;
> +       i2c_writel(i2c, val, REG_CON);

Another subtle bug here.  You need to be holding the spinlock here
since you're doing a read-modify-write of a register that is also
touched by the interrupt handler.  We never needed it before because
the previous register update wasn't touched by anyone else and it was
a single atomic write.

Also: technically if we are midway through a transfer when all this
happens then there will be a very short period of time when the two
timing-related registers won't match with each other.  I have no idea
how much that would matter, but in the very least it seems wise to
minimize the time where they mismatch.  So I'd probably write:

       spin_lock_irqsave(&i2c->lock, flags);
       val = i2c_readl(i2c, REG_CON);
       val &= ~REG_CON_TUNING_MASK;
       val |= calc.tuning;
       i2c_writel(i2c, val, REG_CON);
       i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff),
                  REG_CLKDIV);
       spin_unlock_irqrestore(&i2c->lock, flags);

...if we really end up with on a system with a dynamically changing
clock that uses the new-style timing and we see real problems, we can
always try to come up with a way to avoid any problems.  Sound OK?


Otherwise, I think things look good to me.  Caesar's comments would
also be good to fix.


-Doug

  parent reply	other threads:[~2016-05-11 17:38 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-10 19:24 [PATCH v8 0/8] add i2c driver supported for rk3399 David Wu
2016-05-10 19:24 ` David Wu
2016-05-10 19:24 ` [PATCH v8 1/8] i2c: rk3x: add documentation to fields in "struct rk3x_i2c" David Wu
2016-05-10 19:24   ` David Wu
2016-05-11 15:04   ` Heiko Stuebner
2016-05-11 15:04     ` Heiko Stuebner
2016-05-10 19:24 ` [PATCH v8 2/8] i2c: rk3x: use struct "rk3x_i2c_calced_timings" David Wu
2016-05-10 19:24   ` David Wu
2016-05-10 19:24 ` [PATCH v8 3/8] i2c: rk3x: Remove redundant rk3x_i2c_clean_ipd() David Wu
2016-05-10 19:24   ` David Wu
2016-05-11 18:26   ` Heiko Stuebner
2016-05-11 18:26     ` Heiko Stuebner
2016-05-12  1:11     ` David.Wu
2016-05-12  1:11       ` David.Wu
2016-05-10 19:24 ` [PATCH v8 4/8] i2c: rk3x: Change SoC data to not use array David Wu
2016-05-10 19:24   ` David Wu
2016-05-10 19:29 ` [PATCH v8 5/8] i2c: rk3x: Move spec timing data to "static const" structs David Wu
2016-05-10 19:29   ` David Wu
2016-05-10 19:30 ` [PATCH v8 6/8] dt-bindings: i2c: rk3x: add support for rk3399 David Wu
2016-05-10 19:30   ` David Wu
2016-05-10 19:30   ` David Wu
2016-05-11 16:35   ` Doug Anderson
2016-05-11 16:35     ` Doug Anderson
2016-05-12  1:14     ` David.Wu
2016-05-12  1:14       ` David.Wu
2016-05-11 18:20   ` Heiko Stuebner
2016-05-11 18:20     ` Heiko Stuebner
2016-05-10 19:31 ` [PATCH v8 7/8] i2c: rk3x: add i2c support for rk3399 soc David Wu
2016-05-10 19:31   ` David Wu
2016-05-11 11:43   ` Caesar Wang
2016-05-11 11:43     ` Caesar Wang
2016-05-11 17:37   ` Doug Anderson [this message]
2016-05-11 17:37     ` Doug Anderson
2016-05-12  1:08     ` David.Wu
2016-05-12  1:08       ` David.Wu
2016-05-12 15:07       ` David.Wu
2016-05-12 15:07         ` David.Wu
2016-05-12 21:09         ` Doug Anderson
2016-05-12 21:09           ` Doug Anderson
2016-05-12 21:09           ` Doug Anderson
2016-05-10 19:33 ` [PATCH v8 8/8] i2c: rk3x: support fast-mode plus for rk3399 David Wu
2016-05-10 19:33   ` David Wu
2016-05-11 11:44   ` Caesar Wang
2016-05-11 11:44     ` Caesar Wang
2016-05-11 21:09   ` Heiko Stuebner
2016-05-11 21:09     ` Heiko Stuebner
2016-05-11 23:41     ` Doug Anderson
2016-05-11 23:41       ` Doug Anderson
2016-05-11 23:41       ` Doug Anderson
2016-05-12  8:30       ` Heiko Stuebner
2016-05-12  8:30         ` Heiko Stuebner
2016-05-12  8:30         ` Heiko Stuebner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAD=FV=Uf-U3RBpgFbR3LkPAJTWqz3d02+H7iyA-SS-y=r3cXjA@mail.gmail.com' \
    --to=dianders@chromium.org \
    --cc=andy.shevchenko@gmail.com \
    --cc=briannorris@google.com \
    --cc=cf@rock-chips.com \
    --cc=david.wu@rock-chips.com \
    --cc=davidriley@google.com \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=heiko@sntech.de \
    --cc=hl@rock-chips.com \
    --cc=huangtao@rock-chips.com \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=pawel.moll@arm.com \
    --cc=robh+dt@kernel.org \
    --cc=wsa@the-dreams.de \
    --cc=xjq@rock-chips.com \
    --cc=zyw@rock-chips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.