Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9F4A7C61DA4 for ; Sat, 18 Feb 2023 23:30:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229663AbjBRXaB (ORCPT ); Sat, 18 Feb 2023 18:30:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229638AbjBRX37 (ORCPT ); Sat, 18 Feb 2023 18:29:59 -0500 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B4E11206F for ; Sat, 18 Feb 2023 15:29:57 -0800 (PST) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-53681cc6156so21701967b3.9 for ; Sat, 18 Feb 2023 15:29:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Vz5DzYr/Opa8OtY4Tzu39Y9aDuWD1hSn8O8cPqW8lso=; b=omb2A12qU7J8gN8cUyq0r2MdWs6Zk0tq96wdGCDEd/pf1ia4HVnj01jxwsB7Ktaf6t ch17n2ssXiWutDHJG1MGrT0NjO8sMVa5u0D93JgJhyyWuJCXHlioCCUnCcopD2gB0Kax FY/nAr2jFoFbaXNYj9SAa6wyDlTDcio1/bARURQ+FmM+1rEi6HjQ1j186Bp2qhNE2NX2 DEB49y2qVLbEaKv9ZmuQlllVQpI9GXjgWJYWWspsWMQCgGw6F/TYscrXtHT2zRjNRBie VTrcDdh/sRPeRzh6d1Vroz4ih0SFwpMOcEHwgTc0LVcsVF0j2jNu9845BOv5bIfYEtMS nCAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Vz5DzYr/Opa8OtY4Tzu39Y9aDuWD1hSn8O8cPqW8lso=; b=MuxhW96kFoNVgaAYQq2DUkovuGHl3/YjgOBAGw7seCuTOxnp3Rytw0atlJ/wOrOFHn stD4LIeeS9sec9YG2BjviBjRbj7q6pnWTPul9xWeepG53rqVx9gB5olSLi6pT/2R4/3/ HBURwdFWMOR89JhQlTRt/evUI2GXEgmr+lxY5MHVBEh9auAm+vr6o+zd6kTmcm0RHFYU wJAjL3MgJvSKN3bAdw1j9JOzPuzZGBedkAPR9lXCddse+U+N2yFS7R+vOq5rrY6vExeB 9kkp3BnJZcRTGXEjpLxZ6gz7uO2+dJyMNkswpt85R+yC1ucIAYr5GGj+DezYlxuGuoo+ IZJQ== X-Gm-Message-State: AO0yUKWqysNa8QmQcWpg40ARwQ8vCu+bTlAHgquZ77xGp5T/UAWVqLVO 6dP3fiHqnoFeWU+tXNXDXUIk2j3WlV+ZwEBv6bm8HA== X-Google-Smtp-Source: AK7set/olNwKNK7HfjBrvB6nqfSSaLih+5uqgsaTvGCT3Mx5SRBygrVNZ9jBq1XWy8aWrrVifm4XLTxRGdk/YB3HlUs= X-Received: by 2002:a0d:dfc1:0:b0:52e:d00a:263b with SMTP id i184-20020a0ddfc1000000b0052ed00a263bmr2152556ywe.35.1676762995905; Sat, 18 Feb 2023 15:29:55 -0800 (PST) MIME-Version: 1.0 References: <961a2164-640a-86b5-980f-73668eb161e4@microchip.com> <46dd4d9a-7dc8-48f9-69d4-d18ca6433acc@microchip.com> In-Reply-To: <46dd4d9a-7dc8-48f9-69d4-d18ca6433acc@microchip.com> From: Linus Walleij Date: Sun, 19 Feb 2023 00:29:43 +0100 Message-ID: Subject: Re: I2c GPIO Recovery with pinctrl strict mode To: Ryan.Wanner@microchip.com Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, alexandre.belloni@bootlin.com, Ludovic.Desroches@microchip.com, Nicolas.Ferre@microchip.com, Claudiu.Beznea@microchip.com Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Feb 17, 2023 at 6:36 PM wrote: > On 2/13/23 02:29, Linus Walleij wrote: > > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > > > > On Fri, Feb 10, 2023 at 4:21 PM wrote: > > > >> I am trying to enable .strict in the Atmel pinctrl driver, and that is > >> what is causing my issues. > > > > Strictly speaking (ha!) that flag is for when you *cannot* use a pin > > in GPIO mode at the same time as another mode. > > > > Example: if you use the pin in I2C mode, then reading the GPIO > > input register will *not* reflect the value on the electrical line, > > because it has been decoupled physically. Then .strict should > > be true. > > > > The strict mode was not intended for policy, i.e. stopping kernel > > developers from doing wrong things. They have enough tools to > > do wrong things anyway, one more or less doesn't matter. > > I understand, so .strict keeps the pins mapped to one ownership, > so if I2C has those pins GPIO could not have access to them. > > When it comes to I2c recovery, looking at the I2C generic recovery, > the pins are both being used by the I2C and the GPIO at the same time. > This cannot happen with strict mode. So since I am enabling strict mode > for pinctrl-atmel-pio4.c I2C recovery cannot work? I think it can, you just have to be more careful. You can move the pins between different states. E.g. state "A" and "B", so these states can be "GPIO mode" and "I2C mode". In "GPIO mode" the pins are muxed to the GPIO block, and in the "I2C mode" the pins are muxed to the I2C block. Whether one or other of these modes in practice has an opaque name like "default" or "init" (etc) is just confusing, the only reason these named states exist is for convenience. It is perfectly legal for a pin controller and driver to use states named "foo" or "bar" and never use any state called "default". (See further include/linux/pinctrl/pinctrl-state.h) So what you want in your driver is something like: struct pinctrl_state *gpio_state; struct pinctrl_state *i2c_state; (possibly more) And before normal operations you issue: pinctrl_select_state(p, i2c_state); And before recovery you issue: pinctrl_select_state(p, gpio_state); ... then you use GPIO abstractions to do the recovery followed by pinctrl_select_state(p, i2c_state); To get back to normal operations. This is the gist of it. The problem with using GPIO at the same time as pin control is that some pin controllers implement a "shortcut" which is the struct pinmux_ops callbacks .gpio_request_enable() .gpio_disable_free() .gpio_set_direction() These callbacks will bypass the state selection and mux pins directly as a byproduct of using gpiod_*() operations. For example qualcomm does not implement these callbacks, and all GPIO state setup is done explicitly for every single GPIO pin. This is quite good, but also a bit tedious for the common cases which is why the shortcuts exist. If the pin controller has implemented these operations you get a problem with recovery because the GPIO calls may start to conflict with the state-selected muxing. It can however be made to work also in that case as long as you think things over, but order of semantics will come into play: you probably need to get the GPIO *before* doing pinctrl_select_state(p, i2c_state); the first time, lest the gpio initialization will unselect the I2C state. You probably also shouldn't mess with calling any gpiod_direction_input/output in the recovery code. Hopefully that can be avoided or replaced by more explicit pin control states in that case. This becomes a bit complex, but recovery is a bit complex and out of the ordinary, so... Yours, Linus Walleij