Merge tag 'gpio-v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 May 2019 14:54:43 +0000 (10:54 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 May 2019 14:54:43 +0000 (10:54 -0400)
Pull gpio updates from Linus Walleij:
 "This is the bulk of the GPIO changes for the v5.2 kernel cycle. A bit
  later than usual because I was ironing out my own mistakes. I'm
  holding some stuff back for the next kernel as a result, and this
  should be a healthy and well tested batch.

  Core changes:

   - The gpiolib MMIO driver has been enhanced to handle two direction
     registers, i.e. one register to set lines as input and one register
     to set lines as output. It turns out some silicon engineer thinks
     the ability to configure a line as input and output at the same
     time makes sense, this can be debated but includes a lot of analog
     electronics reasoning, and the registers are there and need to be
     handled consistently. Unsurprisingly, we enforce the lines to be
     either inputs or outputs in such schemes.

   - Send in the proper argument value to .set_config() dispatched to
     the pin control subsystem. Nobody used it before, now someone does,
     so fix it to work as expected.

   - The ACPI gpiolib portions can now handle pin bias setting (pull up
     or pull down). This has been in the ACPI spec for years and we
     finally have it properly integrated with Linux GPIOs. It was based
     on an observation from Andy Schevchenko that Thomas Petazzoni's
     changes to the core for biasing the PCA950x GPIO expander actually
     happen to fit hand-in-glove with what the ACPI core needed. Such
     nice synergies happen sometimes.

  New drivers:

   - A new driver for the Mellanox BlueField GPIO controller. This is
     using 64bit MMIO registers and can configure lines as inputs and
     outputs at the same time and after improving the MMIO library we
     handle it just fine. Interesting.

   - A new IXP4xx proper gpiochip driver with hierarchical interrupts
     should be coming in from the ARM SoC tree as well.

  Driver enhancements:

   - The PCA053x driver handles the CAT9554 GPIO expander.

   - The PCA053x driver handles the NXP PCAL6416 GPIO expander.

   - Wake-up support on PCA053x GPIO lines.

   - OMAP now does a nice asynchronous IRQ handling on wake-ups by
     letting everything wake up on edges, and this makes runtime PM work
     as expected too.

  Misc:

   - Several cleanups such as devres fixes.

   - Get rid of some languager comstructs that cause problems when
     compiling with LLVMs clang.

   - Documentation review and update"

* tag 'gpio-v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (85 commits)
  gpio: Update documentation
  docs: gpio: convert docs to ReST and rename to *.rst
  gpio: sch: Remove write-only core_base
  gpio: pxa: Make two symbols static
  gpiolib: acpi: Respect pin bias setting
  gpiolib: acpi: Add acpi_gpio_update_gpiod_lookup_flags() helper
  gpiolib: acpi: Set pin value, based on bias, more accurately
  gpiolib: acpi: Change type of dflags
  gpiolib: Introduce GPIO_LOOKUP_FLAGS_DEFAULT
  gpiolib: Make use of enum gpio_lookup_flags consistent
  gpiolib: Indent entry values of enum gpio_lookup_flags
  gpio: pca953x: add support for pca6416
  dt-bindings: gpio: pca953x: document the nxp,pca6416
  gpio: pca953x: add pcal6416 to the of_device_id table
  gpio: gpio-omap: Remove conditional pm_runtime handling for GPIO interrupts
  gpio: gpio-omap: configure edge detection for level IRQs for idle wakeup
  tracing: stop making gpio tracing configurable
  gpio: pca953x: Configure wake-up path when wake-up is enabled
  gpio: of: Optimize quirk checks
  gpio: mmio: Drop bgpio_dir_inverted
  ...

1  2 
arch/arm/configs/aspeed_g4_defconfig
arch/arm/configs/aspeed_g5_defconfig
drivers/gpio/Kconfig
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
drivers/pinctrl/pinctrl-mcp23s08.c
include/linux/gpio/driver.h

@@@ -23,6 -23,7 +23,6 @@@ CONFIG_SLAB_FREELIST_RANDOM=
  CONFIG_JUMP_LABEL=y
  CONFIG_STRICT_KERNEL_RWX=y
  CONFIG_GCC_PLUGINS=y
 -# CONFIG_LBDAF is not set
  # CONFIG_BLK_DEV_BSG is not set
  # CONFIG_BLK_DEBUG_FS is not set
  # CONFIG_IOSCHED_DEADLINE is not set
@@@ -247,7 -248,6 +247,6 @@@ CONFIG_PANIC_TIMEOUT=-
  # CONFIG_SCHED_DEBUG is not set
  CONFIG_SCHED_STACK_END_CHECK=y
  CONFIG_FUNCTION_TRACER=y
- # CONFIG_TRACING_EVENTS_GPIO is not set
  # CONFIG_RUNTIME_TESTING_MENU is not set
  CONFIG_DEBUG_WX=y
  CONFIG_DEBUG_USER=y
@@@ -23,6 -23,7 +23,6 @@@ CONFIG_SLAB_FREELIST_RANDOM=
  CONFIG_JUMP_LABEL=y
  CONFIG_STRICT_KERNEL_RWX=y
  CONFIG_GCC_PLUGINS=y
 -# CONFIG_LBDAF is not set
  # CONFIG_BLK_DEV_BSG is not set
  # CONFIG_BLK_DEBUG_FS is not set
  # CONFIG_IOSCHED_DEADLINE is not set
@@@ -247,7 -248,6 +247,6 @@@ CONFIG_PANIC_TIMEOUT=-
  # CONFIG_SCHED_DEBUG is not set
  CONFIG_SCHED_STACK_END_CHECK=y
  CONFIG_FUNCTION_TRACER=y
- # CONFIG_TRACING_EVENTS_GPIO is not set
  # CONFIG_RUNTIME_TESTING_MENU is not set
  CONFIG_DEBUG_WX=y
  CONFIG_DEBUG_USER=y
diff --combined drivers/gpio/Kconfig
@@@ -12,6 -12,7 +12,6 @@@ config ARCH_HAVE_CUSTOM_GPIO_
  
  menuconfig GPIOLIB
        bool "GPIO Support"
 -      select ANON_INODES
        help
          This enables GPIO support through the generic GPIO library.
          You only need to enable this, if you also want to enable
@@@ -26,12 -27,12 +26,12 @@@ config GPIOLIB_FASTPATH_LIMI
        range 32 512
        default 512
        help
-          This adjusts the point at which certain APIs will switch from
-          using a stack allocated buffer to a dynamically allocated buffer.
+         This adjusts the point at which certain APIs will switch from
+         using a stack allocated buffer to a dynamically allocated buffer.
  
-          You shouldn't need to change this unless you really need to
-          optimize either stack space or performance. Change this carefully
-          since setting an incorrect value could cause stack corruption.
+         You shouldn't need to change this unless you really need to
+         optimize either stack space or performance. Change this carefully
+         since setting an incorrect value could cause stack corruption.
  
  config OF_GPIO
        def_bool y
@@@ -319,7 -320,7 +319,7 @@@ config GPIO_MENZ12
        depends on MCB
        select GPIO_GENERIC
        help
-        Say yes here to support the MEN 16Z127 GPIO Controller
+         Say yes here to support the MEN 16Z127 GPIO Controller
  
  config GPIO_MM_LANTIQ
        bool "Lantiq Memory mapped GPIOs"
          (EBU) found on Lantiq SoCs. The gpios are output only as they are
          created by attaching a 16bit latch to the bus.
  
- config GPIO_MOCKUP
-       tristate "GPIO Testing Driver"
-       depends on GPIOLIB && SYSFS
-       select GPIO_SYSFS
-       select GPIOLIB_IRQCHIP
-       select IRQ_SIM
-       help
-         This enables GPIO Testing driver, which provides a way to test GPIO
-         subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS
-         must be selected for this test.
-         User could use it through the script in
-         tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in
-         it.
  config GPIO_MPC5200
        def_bool y
        depends on PPC_MPC52xx
@@@ -861,11 -848,11 +847,11 @@@ config GPIO_MAX732
          Input and Output (designed by 'P'). The combinations are listed
          below:
  
-         8 bits:       max7319 (8I), max7320 (8O), max7321 (8P),
-                       max7322 (4I4O), max7323 (4P4O)
+         8 bits:       max7319 (8I), max7320 (8O), max7321 (8P),
+                       max7322 (4I4O), max7323 (4P4O)
  
-         16 bits:      max7324 (8I8O), max7325 (8P8O),
-                       max7326 (4I12O), max7327 (4P12O)
+         16 bits:      max7324 (8I8O), max7325 (8P8O),
+                       max7326 (4I12O), max7327 (4P12O)
  
          Board setup code must specify the model to use, and the start
          number for these GPIOs.
@@@ -892,17 -879,17 +878,17 @@@ config GPIO_PCA953
          SMBus I/O expanders, made mostly by NXP or TI.  Compatible
          models include:
  
-         4 bits:       pca9536, pca9537
+         4 bits:       pca9536, pca9537
  
-         8 bits:       max7310, max7315, pca6107, pca9534, pca9538, pca9554,
-                       pca9556, pca9557, pca9574, tca6408, tca9554, xra1202
+         8 bits:       max7310, max7315, pca6107, pca9534, pca9538, pca9554,
+                       pca9556, pca9557, pca9574, tca6408, tca9554, xra1202
  
-         16 bits:      max7312, max7313, pca9535, pca9539, pca9555, pca9575,
-                       tca6416
+         16 bits:      max7312, max7313, pca9535, pca9539, pca9555, pca9575,
+                       tca6416
  
-         24 bits:      tca6424
+         24 bits:      tca6424
  
-         40 bits:      pca9505, pca9698
+         40 bits:      pca9505, pca9698
  
  config GPIO_PCA953X_IRQ
        bool "Interrupt controller support for PCA953x"
@@@ -924,7 -911,7 +910,7 @@@ config GPIO_PCF857
  
          8 bits:   pcf8574, pcf8574a, pca8574, pca8574a,
                    pca9670, pca9672, pca9674, pca9674a,
-                   max7328, max7329
+                   max7328, max7329
  
          16 bits:  pcf8575, pcf8575c, pca8575,
                    pca9671, pca9673, pca9675
@@@ -1046,9 -1033,9 +1032,9 @@@ config HTC_EGPI
        bool "HTC EGPIO support"
        depends on GPIOLIB && ARM
        help
-           This driver supports the CPLD egpio chip present on
-           several HTC phones.  It provides basic support for input
-           pins, output pins, and irqs.
+         This driver supports the CPLD egpio chip present on
+         several HTC phones.  It provides basic support for input
+         pins, output pins, and irqs.
  
  config GPIO_JANZ_TTL
        tristate "Janz VMOD-TTL Digital IO Module"
@@@ -1084,7 -1071,7 +1070,7 @@@ config GPIO_LP873
          on LP873X PMICs.
  
          This driver can also be built as a module. If so, the module will be
-           called gpio-lp873x.
+         called gpio-lp873x.
  
  config GPIO_LP87565
        tristate "TI LP87565 GPIO"
@@@ -1315,6 -1302,13 +1301,13 @@@ config GPIO_MERRIFIEL
        help
          Say Y here to support Intel Merrifield GPIO.
  
+ config GPIO_MLXBF
+       tristate "Mellanox BlueField SoC GPIO"
+       depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && COMPILE_TEST)
+       select GPIO_GENERIC
+       help
+         Say Y here if you want GPIO support on Mellanox BlueField SoC.
  config GPIO_ML_IOH
        tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
        depends on X86 || COMPILE_TEST
@@@ -1435,10 -1429,22 +1428,22 @@@ config GPIO_VIPERBOAR
          Say yes here to access the GPIO signals of Nano River
          Technologies Viperboard. There are two GPIO chips on the
          board: gpioa and gpiob.
-           See viperboard API specification and Nano
-           River Tech's viperboard.h for detailed meaning
-           of the module parameters.
+         See viperboard API specification and Nano
+         River Tech's viperboard.h for detailed meaning
+         of the module parameters.
  
  endmenu
  
+ config GPIO_MOCKUP
+       tristate "GPIO Testing Driver"
+       depends on GPIOLIB
+       select IRQ_SIM
+       help
+         This enables GPIO Testing driver, which provides a way to test GPIO
+         subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS
+         must be selected for this test.
+         User could use it through the script in
+         tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in
+         it.
  endif
diff --combined drivers/gpio/gpiolib.c
@@@ -1379,7 -1379,7 +1379,7 @@@ int gpiochip_add_data_with_key(struct g
  
        status = gpiochip_add_irqchip(chip, lock_key, request_key);
        if (status)
 -              goto err_remove_chip;
 +              goto err_free_gpiochip_mask;
  
        status = of_gpiochip_add(chip);
        if (status)
  
        status = gpiochip_init_valid_mask(chip);
        if (status)
 -              goto err_remove_chip;
 +              goto err_remove_of_chip;
  
        for (i = 0; i < chip->ngpio; i++) {
                struct gpio_desc *desc = &gdev->descs[i];
        if (gpiolib_initialized) {
                status = gpiochip_setup_dev(gdev);
                if (status)
 -                      goto err_remove_chip;
 +                      goto err_remove_acpi_chip;
        }
        return 0;
  
 -err_remove_chip:
 +err_remove_acpi_chip:
        acpi_gpiochip_remove(chip);
 +err_remove_of_chip:
        gpiochip_free_hogs(chip);
        of_gpiochip_remove(chip);
 +err_remove_chip:
 +      gpiochip_irqchip_remove(chip);
 +err_free_gpiochip_mask:
        gpiochip_free_valid_mask(chip);
  err_remove_irqchip_mask:
        gpiochip_irqchip_free_valid_mask(chip);
@@@ -2519,6 -2515,7 +2519,7 @@@ struct gpio_desc *gpiochip_request_own_
                                            const char *label,
                                            enum gpiod_flags flags)
  {
+       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);
        int err;
  
        if (err < 0)
                return ERR_PTR(err);
  
-       err = gpiod_configure_flags(desc, label, 0, flags);
+       err = gpiod_configure_flags(desc, label, lflags, flags);
        if (err) {
                chip_err(chip, "setup of own GPIO %s failed\n", label);
                gpiod_free_commit(desc);
@@@ -2569,8 -2566,20 +2570,20 @@@ EXPORT_SYMBOL_GPL(gpiochip_free_own_des
  static int gpio_set_config(struct gpio_chip *gc, unsigned offset,
                           enum pin_config_param mode)
  {
-       unsigned long config = { PIN_CONF_PACKED(mode, 0) };
+       unsigned long config;
+       unsigned arg;
  
+       switch (mode) {
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_PULL_UP:
+               arg = 1;
+               break;
+       default:
+               arg = 0;
+       }
+       config = PIN_CONF_PACKED(mode, arg);
        return gc->set_config ? gc->set_config(gc, offset, config) : -ENOTSUPP;
  }
  
@@@ -3915,8 -3924,7 +3928,7 @@@ found
  }
  
  static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
-                                   unsigned int idx,
-                                   enum gpio_lookup_flags *flags)
+                                   unsigned int idx, unsigned long *flags)
  {
        struct gpio_desc *desc = ERR_PTR(-ENOENT);
        struct gpiod_lookup_table *table;
@@@ -4072,8 -4080,8 +4084,8 @@@ EXPORT_SYMBOL_GPL(gpiod_get_optional)
   * gpiod_configure_flags - helper function to configure a given GPIO
   * @desc:     gpio whose value will be assigned
   * @con_id:   function within the GPIO consumer
-  * @lflags:   gpio_lookup_flags - returned from of_find_gpio() or
-  *            of_get_gpio_hog()
+  * @lflags:   bitmask of gpio_lookup_flags GPIO_* values - returned from
+  *            of_find_gpio() or of_get_gpio_hog()
   * @dflags:   gpiod_flags - optional GPIO initialization flags
   *
   * Return 0 on success, -ENOENT if no GPIO has been assigned to the
@@@ -4155,9 -4163,9 +4167,9 @@@ struct gpio_desc *__must_check gpiod_ge
                                               unsigned int idx,
                                               enum gpiod_flags flags)
  {
+       unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc = NULL;
        int status;
-       enum gpio_lookup_flags lookupflags = 0;
        /* Maybe we have a device name, maybe not */
        const char *devname = dev ? dev_name(dev) : "?";
  
@@@ -4242,8 -4250,8 +4254,8 @@@ struct gpio_desc *gpiod_get_from_of_nod
                                         enum gpiod_flags dflags,
                                         const char *label)
  {
+       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc;
-       unsigned long lflags = 0;
        enum of_gpio_flags flags;
        bool active_low = false;
        bool single_ended = false;
@@@ -4321,8 -4329,8 +4333,8 @@@ struct gpio_desc *fwnode_get_named_gpio
                                         enum gpiod_flags dflags,
                                         const char *label)
  {
+       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc = ERR_PTR(-ENODEV);
-       unsigned long lflags = 0;
        int ret;
  
        if (!fwnode)
                        return desc;
  
                acpi_gpio_update_gpiod_flags(&dflags, &info);
-               if (info.polarity == GPIO_ACTIVE_LOW)
-                       lflags |= GPIO_ACTIVE_LOW;
+               acpi_gpio_update_gpiod_lookup_flags(&lflags, &info);
        }
  
        /* Currently only ACPI takes this path */
@@@ -4395,8 -4401,8 +4405,8 @@@ EXPORT_SYMBOL_GPL(gpiod_get_index_optio
   * gpiod_hog - Hog the specified GPIO desc given the provided flags
   * @desc:     gpio whose value will be assigned
   * @name:     gpio line name
-  * @lflags:   gpio_lookup_flags - returned from of_find_gpio() or
-  *            of_get_gpio_hog()
+  * @lflags:   bitmask of gpio_lookup_flags GPIO_* values - returned from
+  *            of_find_gpio() or of_get_gpio_hog()
   * @dflags:   gpiod_flags - optional GPIO initialization flags
   */
  int gpiod_hog(struct gpio_desc *desc, const char *name,
  /**
   * gpiochip_free_hogs - Scan gpio-controller chip and release GPIO hog
   * @chip:     gpio chip to act on
-  *
-  * This is only used by of_gpiochip_remove to free hogged gpios
   */
  static void gpiochip_free_hogs(struct gpio_chip *chip)
  {
@@@ -4620,7 -4624,8 +4628,8 @@@ EXPORT_SYMBOL_GPL(gpiod_get_array_optio
   */
  void gpiod_put(struct gpio_desc *desc)
  {
-       gpiod_free(desc);
+       if (desc)
+               gpiod_free(desc);
  }
  EXPORT_SYMBOL_GPL(gpiod_put);
  
diff --combined drivers/gpio/gpiolib.h
@@@ -17,7 -17,6 +17,6 @@@
  #include <linux/cdev.h>
  
  enum of_gpio_flags;
- enum gpio_lookup_flags;
  struct acpi_device;
  
  /**
@@@ -75,6 -74,7 +74,7 @@@ struct gpio_device 
   * @adev: reference to ACPI device which consumes GPIO resource
   * @flags: GPIO initialization flags
   * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
+  * @pin_config: pin bias as provided by ACPI
   * @polarity: interrupt polarity as provided by ACPI
   * @triggering: triggering type as provided by ACPI
   * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
@@@ -83,6 -83,7 +83,7 @@@ struct acpi_gpio_info 
        struct acpi_device *adev;
        enum gpiod_flags flags;
        bool gpioint;
+       int pin_config;
        int polarity;
        int triggering;
        unsigned int quirks;
@@@ -95,7 -96,7 +96,7 @@@ static __maybe_unused const char * cons
  struct gpio_desc *of_find_gpio(struct device *dev,
                               const char *con_id,
                               unsigned int idx,
-                              enum gpio_lookup_flags *flags);
+                              unsigned long *lookupflags);
  struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
                   const char *list_name, int index, enum of_gpio_flags *flags);
  int of_gpiochip_add(struct gpio_chip *gc);
@@@ -104,7 -105,7 +105,7 @@@ void of_gpiochip_remove(struct gpio_chi
  static inline struct gpio_desc *of_find_gpio(struct device *dev,
                                             const char *con_id,
                                             unsigned int idx,
-                                            enum gpio_lookup_flags *flags)
+                                            unsigned long *lookupflags)
  {
        return ERR_PTR(-ENOENT);
  }
@@@ -126,12 -127,14 +127,14 @@@ void acpi_gpiochip_free_interrupts(stru
  
  int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags,
                                 struct acpi_gpio_info *info);
+ int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
+                                       struct acpi_gpio_info *info);
  
  struct gpio_desc *acpi_find_gpio(struct device *dev,
                                 const char *con_id,
                                 unsigned int idx,
                                 enum gpiod_flags *dflags,
-                                enum gpio_lookup_flags *lookupflags);
+                                unsigned long *lookupflags);
  struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
                                      const char *propname, int index,
                                      struct acpi_gpio_info *info);
@@@ -154,11 -157,17 +157,17 @@@ acpi_gpio_update_gpiod_flags(enum gpiod
  {
        return 0;
  }
+ static inline int
+ acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
+                                   struct acpi_gpio_info *info)
+ {
+       return 0;
+ }
  
  static inline struct gpio_desc *
  acpi_find_gpio(struct device *dev, const char *con_id,
               unsigned int idx, enum gpiod_flags *dflags,
-              enum gpio_lookup_flags *lookupflags)
+              unsigned long *lookupflags)
  {
        return ERR_PTR(-ENOENT);
  }
@@@ -243,6 -252,9 +252,6 @@@ static inline int gpio_chip_hwgpio(cons
        return desc - &desc->gdev->descs[0];
  }
  
 -void devprop_gpiochip_set_names(struct gpio_chip *chip,
 -                              const struct fwnode_handle *fwnode);
 -
  /* With descriptor prefix */
  
  #define gpiod_emerg(desc, fmt, ...)                                          \
@@@ -266,6 -266,7 +266,6 @@@ static int mcp_pinconf_get(struct pinct
                status = (data & BIT(pin)) ? 1 : 0;
                break;
        default:
 -              dev_err(mcp->dev, "Invalid config param %04x\n", param);
                return -ENOTSUPP;
        }
  
@@@ -292,7 -293,7 +292,7 @@@ static int mcp_pinconf_set(struct pinct
                        ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg);
                        break;
                default:
 -                      dev_err(mcp->dev, "Invalid config param %04x\n", param);
 +                      dev_dbg(mcp->dev, "Invalid config param %04x\n", param);
                        return -ENOTSUPP;
                }
        }
@@@ -655,115 -656,6 +655,6 @@@ static int mcp23s08_irqchip_setup(struc
  
  /*----------------------------------------------------------------------*/
  
- #ifdef CONFIG_DEBUG_FS
- #include <linux/seq_file.h>
- /*
-  * This compares the chip's registers with the register
-  * cache and corrects any incorrectly set register. This
-  * can be used to fix state for MCP23xxx, that temporary
-  * lost its power supply.
-  */
- #define MCP23S08_CONFIG_REGS 7
- static int __check_mcp23s08_reg_cache(struct mcp23s08 *mcp)
- {
-       int cached[MCP23S08_CONFIG_REGS];
-       int err = 0, i;
-       /* read cached config registers */
-       for (i = 0; i < MCP23S08_CONFIG_REGS; i++) {
-               err = mcp_read(mcp, i, &cached[i]);
-               if (err)
-                       goto out;
-       }
-       regcache_cache_bypass(mcp->regmap, true);
-       for (i = 0; i < MCP23S08_CONFIG_REGS; i++) {
-               int uncached;
-               err = mcp_read(mcp, i, &uncached);
-               if (err)
-                       goto out;
-               if (uncached != cached[i]) {
-                       dev_err(mcp->dev, "restoring reg 0x%02x from 0x%04x to 0x%04x (power-loss?)\n",
-                               i, uncached, cached[i]);
-                       mcp_write(mcp, i, cached[i]);
-               }
-       }
- out:
-       if (err)
-               dev_err(mcp->dev, "read error: reg=%02x, err=%d", i, err);
-       regcache_cache_bypass(mcp->regmap, false);
-       return err;
- }
- /*
-  * This shows more info than the generic gpio dump code:
-  * pullups, deglitching, open drain drive.
-  */
- static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
- {
-       struct mcp23s08 *mcp;
-       char            bank;
-       int             t;
-       unsigned        mask;
-       int iodir, gpio, gppu;
-       mcp = gpiochip_get_data(chip);
-       /* NOTE: we only handle one bank for now ... */
-       bank = '0' + ((mcp->addr >> 1) & 0x7);
-       mutex_lock(&mcp->lock);
-       t = __check_mcp23s08_reg_cache(mcp);
-       if (t) {
-               seq_printf(s, " I/O Error\n");
-               goto done;
-       }
-       t = mcp_read(mcp, MCP_IODIR, &iodir);
-       if (t) {
-               seq_printf(s, " I/O Error\n");
-               goto done;
-       }
-       t = mcp_read(mcp, MCP_GPIO, &gpio);
-       if (t) {
-               seq_printf(s, " I/O Error\n");
-               goto done;
-       }
-       t = mcp_read(mcp, MCP_GPPU, &gppu);
-       if (t) {
-               seq_printf(s, " I/O Error\n");
-               goto done;
-       }
-       for (t = 0, mask = BIT(0); t < chip->ngpio; t++, mask <<= 1) {
-               const char *label;
-               label = gpiochip_is_requested(chip, t);
-               if (!label)
-                       continue;
-               seq_printf(s, " gpio-%-3d P%c.%d (%-12s) %s %s %s\n",
-                          chip->base + t, bank, t, label,
-                          (iodir & mask) ? "in " : "out",
-                          (gpio & mask) ? "hi" : "lo",
-                          (gppu & mask) ? "up" : "  ");
-               /* NOTE:  ignoring the irq-related registers */
-       }
- done:
-       mutex_unlock(&mcp->lock);
- }
- #else
- #define mcp23s08_dbg_show     NULL
- #endif
- /*----------------------------------------------------------------------*/
  static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
                              void *data, unsigned addr, unsigned type,
                              unsigned int base, int cs)
        mcp->chip.get = mcp23s08_get;
        mcp->chip.direction_output = mcp23s08_direction_output;
        mcp->chip.set = mcp23s08_set;
-       mcp->chip.dbg_show = mcp23s08_dbg_show;
  #ifdef CONFIG_OF_GPIO
        mcp->chip.of_gpio_n_cells = 2;
        mcp->chip.of_node = dev->of_node;
@@@ -227,9 -227,10 +227,10 @@@ struct gpio_irq_chip 
   * @reg_dat: data (in) register for generic GPIO
   * @reg_set: output set register (out=high) for generic GPIO
   * @reg_clr: output clear register (out=low) for generic GPIO
-  * @reg_dir: direction setting register for generic GPIO
-  * @bgpio_dir_inverted: indicates that the direction register is inverted
-  *    (gpiolib private state variable)
+  * @reg_dir_out: direction out setting register for generic GPIO
+  * @reg_dir_in: direction in setting register for generic GPIO
+  * @bgpio_dir_unreadable: indicates that the direction register(s) cannot
+  *    be read and we need to rely on out internal state tracking.
   * @bgpio_bits: number of register bits used for a generic GPIO i.e.
   *    <register width> * 8
   * @bgpio_lock: used to lock chip->bgpio_data. Also, this is needed to keep
   * @bgpio_data:       shadowed data register for generic GPIO to clear/set bits
   *    safely.
   * @bgpio_dir: shadowed direction register for generic GPIO to clear/set
-  *    direction safely.
+  *    direction safely. A "1" in this word means the line is set as
+  *    output.
   *
   * A gpio_chip can help platforms abstract various sources of GPIOs so
   * they can all be accessed through a common programing interface.
@@@ -298,8 -300,9 +300,9 @@@ struct gpio_chip 
        void __iomem *reg_dat;
        void __iomem *reg_set;
        void __iomem *reg_clr;
-       void __iomem *reg_dir;
-       bool bgpio_dir_inverted;
+       void __iomem *reg_dir_out;
+       void __iomem *reg_dir_in;
+       bool bgpio_dir_unreadable;
        int bgpio_bits;
        spinlock_t bgpio_lock;
        unsigned long bgpio_data;
@@@ -614,9 -617,6 +617,9 @@@ struct gpio_desc *gpiochip_request_own_
                                            enum gpiod_flags flags);
  void gpiochip_free_own_desc(struct gpio_desc *desc);
  
 +void devprop_gpiochip_set_names(struct gpio_chip *chip,
 +                              const struct fwnode_handle *fwnode);
 +
  #else /* CONFIG_GPIOLIB */
  
  static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)