with kernel 5.10.4 , this patch work on fedora 33.


diff -Narup a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
--- a/drivers/gpio/gpiolib-acpi.c       2020-12-14 06:41:30.000000000 +0800
+++ b/drivers/gpio/gpiolib-acpi.c       2020-12-22 14:31:53.078877000 +0800
@@ -205,6 +205,68 @@ static void acpi_gpiochip_request_irqs(s
                acpi_gpiochip_request_irq(acpi_gpio, event);
 }
 
+static enum gpiod_flags
+acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio, int polarity)
+{
+       /* GpioInt() implies input configuration */
+       if (agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT)
+               return GPIOD_IN;
+
+       switch (agpio->io_restriction) {
+       case ACPI_IO_RESTRICT_INPUT:
+               return GPIOD_IN;
+       case ACPI_IO_RESTRICT_OUTPUT:
+               /*
+                * ACPI GPIO resources don't contain an initial value for the
+                * GPIO. Therefore we deduce that value from the pull field
+                * and the polarity instead. If the pin is pulled up we assume
+                * default to be high, if it is pulled down we assume default
+                * to be low, otherwise we leave pin untouched. For active low
+                * polarity values will be switched. See also
+                * Documentation/firmware-guide/acpi/gpio-properties.rst.
+                */
+               switch (agpio->pin_config) {
+               case ACPI_PIN_CONFIG_PULLUP:
+                       return polarity == GPIO_ACTIVE_LOW ? GPIOD_OUT_LOW : 
GPIOD_OUT_HIGH;
+               case ACPI_PIN_CONFIG_PULLDOWN:
+                       return polarity == GPIO_ACTIVE_LOW ? GPIOD_OUT_HIGH : 
GPIOD_OUT_LOW;
+               default:
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       /*
+        * Assume that the BIOS has configured the direction and pull
+        * accordingly.
+        */
+       return GPIOD_ASIS;
+}
+
+static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
+                                               struct acpi_resource_gpio 
*agpio,
+                                               unsigned int index,
+                                               const char *label)
+{
+       int polarity = GPIO_ACTIVE_HIGH;
+       enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, polarity);
+       unsigned int pin = agpio->pin_table[index];
+       struct gpio_desc *desc;
+       int ret;
+
+       desc = gpiochip_request_own_desc(chip, pin, label, polarity, flags);
+       if (IS_ERR(desc))
+               return desc;
+
+       ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout);
+       if (ret)
+               gpiochip_free_own_desc(desc);
+
+       return ret ? ERR_PTR(ret) : desc;
+}
+
 static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in)
 {
        const char *controller, *pin_str;
@@ -290,8 +352,8 @@ static acpi_status acpi_gpiochip_alloc_e
        if (!handler)
                return AE_OK;
 
-       desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event",
-                                        GPIO_ACTIVE_HIGH, GPIOD_IN);
+       desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event");
+
        if (IS_ERR(desc)) {
                dev_err(chip->parent,
                        "Failed to request GPIO for pin 0x%04X, err %ld\n",
@@ -526,39 +588,6 @@ static bool acpi_get_driver_gpio_data(st
        return false;
 }
 
-static enum gpiod_flags
-acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio)
-{
-       switch (agpio->io_restriction) {
-       case ACPI_IO_RESTRICT_INPUT:
-               return GPIOD_IN;
-       case ACPI_IO_RESTRICT_OUTPUT:
-               /*
-                * ACPI GPIO resources don't contain an initial value for the
-                * GPIO. Therefore we deduce that value from the pull field
-                * instead. If the pin is pulled up we assume default to be
-                * high, if it is pulled down we assume default to be low,
-                * otherwise we leave pin untouched.
-                */
-               switch (agpio->pin_config) {
-               case ACPI_PIN_CONFIG_PULLUP:
-                       return GPIOD_OUT_HIGH;
-               case ACPI_PIN_CONFIG_PULLDOWN:
-                       return GPIOD_OUT_LOW;
-               default:
-                       break;
-               }
-       default:
-               break;
-       }
-
-       /*
-        * Assume that the BIOS has configured the direction and pull
-        * accordingly.
-        */
-       return GPIOD_ASIS;
-}
-
 static int
 __acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags 
update)
 {
@@ -664,6 +693,7 @@ static int acpi_populate_gpio_lookup(str
                lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
                                              agpio->pin_table[pin_index]);
                lookup->info.pin_config = agpio->pin_config;
+               lookup->info.debounce = agpio->debounce_timeout;
                lookup->info.gpioint = gpioint;
 
                /*
@@ -674,13 +704,13 @@ static int acpi_populate_gpio_lookup(str
                 * - ACPI_ACTIVE_HIGH == GPIO_ACTIVE_HIGH
                 */
                if (lookup->info.gpioint) {
-                       lookup->info.flags = GPIOD_IN;
                        lookup->info.polarity = agpio->polarity;
                        lookup->info.triggering = agpio->triggering;
                } else {
-                       lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio);
                        lookup->info.polarity = lookup->active_low;
                }
+
+               lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio, 
lookup->info.polarity);
        }
 
        return 1;
@@ -942,6 +972,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de
 
                if (info.gpioint && idx++ == index) {
                        unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
+                       enum gpiod_flags dflags = GPIOD_ASIS;
                        char label[32];
                        int irq;
 
@@ -951,12 +982,19 @@ int acpi_dev_gpio_irq_get(struct acpi_de
                        irq = gpiod_to_irq(desc);
                        if (irq < 0)
                                return irq;
+                       
+                       acpi_gpio_update_gpiod_flags(&dflags, &info);
+                       acpi_gpio_update_gpiod_lookup_flags(&lflags, &info);
 
                        snprintf(label, sizeof(label), "GpioInt() %d", index);
-                       ret = gpiod_configure_flags(desc, label, lflags, 
info.flags);
+                       ret = gpiod_configure_flags(desc, label, lflags, 
dflags);
                        if (ret < 0)
                                return ret;
 
+                       ret = gpio_set_debounce_timeout(desc, info.debounce);
+                       if (ret)
+                               return ret;
+
                        irq_flags = acpi_dev_get_irq_type(info.triggering,
                                                          info.polarity);
 
@@ -979,7 +1017,7 @@ acpi_gpio_adr_space_handler(u32 function
                            void *region_context)
 {
        struct acpi_gpio_chip *achip = region_context;
-       struct gpio_chip *chip = achip->chip;
+       //struct gpio_chip *chip = achip->chip;
        struct acpi_resource_gpio *agpio;
        struct acpi_resource *ares;
        int pin_index = (int)address;
@@ -1042,23 +1080,20 @@ acpi_gpio_adr_space_handler(u32 function
                }
 
                if (!found) {
-                       enum gpiod_flags flags = 
acpi_gpio_to_gpiod_flags(agpio);
-                       const char *label = "ACPI:OpRegion";
 
-                       desc = gpiochip_request_own_desc(chip, pin, label,
-                                                        GPIO_ACTIVE_HIGH,
-                                                        flags);
                        if (IS_ERR(desc)) {
-                               status = AE_ERROR;
+                               
                                mutex_unlock(&achip->conn_lock);
+                               status = AE_ERROR;
                                goto out;
                        }
 
                        conn = kzalloc(sizeof(*conn), GFP_KERNEL);
                        if (!conn) {
-                               status = AE_NO_MEMORY;
+                               
                                gpiochip_free_own_desc(desc);
                                mutex_unlock(&achip->conn_lock);
+                               status = AE_NO_MEMORY;
                                goto out;
                        }
 
@@ -1070,8 +1105,7 @@ acpi_gpio_adr_space_handler(u32 function
                mutex_unlock(&achip->conn_lock);
 
                if (function == ACPI_WRITE)
-                       gpiod_set_raw_value_cansleep(desc,
-                                                    !!((1 << i) & *value));
+                       gpiod_set_raw_value_cansleep(desc, !!(*value & BIT(i)));
                else
                        *value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
        }
@@ -1132,7 +1166,7 @@ acpi_gpiochip_parse_own_gpio(struct acpi
        int ret;
 
        *lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
-       *dflags = 0;
+       *dflags = GPIOD_ASIS;
        *name = NULL;
 
        ret = fwnode_property_read_u32_array(fwnode, "gpios", gpios,
diff -Narup a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h
--- a/drivers/gpio/gpiolib-acpi.h       2020-12-14 06:41:30.000000000 +0800
+++ b/drivers/gpio/gpiolib-acpi.h       2020-12-22 13:45:48.396976000 +0800
@@ -18,6 +18,7 @@ struct acpi_device;
  * @pin_config: pin bias as provided by ACPI
  * @polarity: interrupt polarity as provided by ACPI
  * @triggering: triggering type as provided by ACPI
+ * @debounce: debounce timeout as provided by ACPI
  * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
  */
 struct acpi_gpio_info {
@@ -27,6 +28,7 @@ struct acpi_gpio_info {
        int pin_config;
        int polarity;
        int triggering;
+       unsigned int debounce;
        unsigned int quirks;
 };
 
diff -Narup a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
--- a/drivers/gpio/gpiolib.c    2020-12-31 11:54:59.920713000 +0800
+++ b/drivers/gpio/gpiolib.c    2020-12-22 14:28:08.770149000 +0800
@@ -1986,11 +1986,9 @@ static int gpiod_request_commit(struct g
 
        if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
                desc_set_label(desc, label ? : "?");
-               ret = 0;
        } else {
-               kfree_const(label);
                ret = -EBUSY;
-               goto done;
+               goto out_free_unlock;
        }
 
        if (gc->request) {
@@ -2003,11 +2001,10 @@ static int gpiod_request_commit(struct g
                        ret = -EINVAL;
                spin_lock_irqsave(&gpio_lock, flags);
 
-               if (ret < 0) {
+               if (ret) {
                        desc_set_label(desc, NULL);
-                       kfree_const(label);
                        clear_bit(FLAG_REQUESTED, &desc->flags);
-                       goto done;
+                       goto out_free_unlock;
                }
        }
        if (gc->get_direction) {
@@ -2016,8 +2013,13 @@ static int gpiod_request_commit(struct g
                gpiod_get_direction(desc);
                spin_lock_irqsave(&gpio_lock, flags);
        }
-done:
+
+       spin_unlock_irqrestore(&gpio_lock, flags);
+       return 0;
+
+out_free_unlock:
        spin_unlock_irqrestore(&gpio_lock, flags);
+       kfree_const(label);
        return ret;
 }
 
@@ -2069,7 +2071,7 @@ int gpiod_request(struct gpio_desc *desc
 
        if (try_module_get(gdev->owner)) {
                ret = gpiod_request_commit(desc, label);
-               if (ret < 0)
+               if (ret)
                        module_put(gdev->owner);
                else
                        get_device(&gdev->dev);
@@ -2252,30 +2254,49 @@ static int gpio_do_set_config(struct gpi
        return gc->set_config(gc, offset, config);
 }
 
-static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
+static int gpio_set_config_with_argument(struct gpio_desc *desc,
+                                        enum pin_config_param mode,
+                                        u32 argument)
 {
        struct gpio_chip *gc = desc->gdev->chip;
        unsigned long config;
-       unsigned arg;
+
+       config = pinconf_to_config_packed(mode, argument);
+       return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
+}
+
+static int gpio_set_config_with_argument_optional(struct gpio_desc *desc,
+                                                 enum pin_config_param mode,
+                                                 u32 argument)
+{
+       struct device *dev = &desc->gdev->dev;
+       int gpio = gpio_chip_hwgpio(desc);
+       int ret;
+
+       ret = gpio_set_config_with_argument(desc, mode, argument);
+       if (ret != -ENOTSUPP)
+               return ret;
 
        switch (mode) {
-       case PIN_CONFIG_BIAS_PULL_DOWN:
-       case PIN_CONFIG_BIAS_PULL_UP:
-               arg = 1;
+       case PIN_CONFIG_PERSIST_STATE:
+               dev_dbg(dev, "Persistence not supported for GPIO %d\n", gpio);
                break;
-
        default:
-               arg = 0;
+               break;
        }
 
-       config = PIN_CONF_PACKED(mode, arg);
-       return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
+       return 0;
+}
+
+static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
+{
+       return gpio_set_config_with_argument(desc, mode, 0);
 }
 
 static int gpio_set_bias(struct gpio_desc *desc)
 {
-       int bias = 0;
-       int ret = 0;
+       enum pin_config_param bias;
+       unsigned int arg;
 
        if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
                bias = PIN_CONFIG_BIAS_DISABLE;
@@ -2283,13 +2304,28 @@ static int gpio_set_bias(struct gpio_des
                bias = PIN_CONFIG_BIAS_PULL_UP;
        else if (test_bit(FLAG_PULL_DOWN, &desc->flags))
                bias = PIN_CONFIG_BIAS_PULL_DOWN;
+       else
+               return 0;
 
-       if (bias) {
-               ret = gpio_set_config(desc, bias);
-               if (ret != -ENOTSUPP)
-                       return ret;
+       switch (bias) {
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_PULL_UP:
+               arg = 1;
+               break;
+
+       default:
+               arg = 0;
+               break;
        }
-       return 0;
+
+       return gpio_set_config_with_argument_optional(desc, bias, arg);
+}
+
+int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
+{
+       return gpio_set_config_with_argument_optional(desc,
+                                                     PIN_CONFIG_INPUT_DEBOUNCE,
+                                                     debounce);
 }
 
 /**
@@ -2530,11 +2566,6 @@ EXPORT_SYMBOL_GPL(gpiod_set_debounce);
  */
 int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
 {
-       struct gpio_chip *gc;
-       unsigned long packed;
-       int gpio;
-       int rc;
-
        VALIDATE_DESC(desc);
        /*
         * Handle FLAG_TRANSITORY first, enabling queries to gpiolib for
@@ -2543,21 +2574,9 @@ int gpiod_set_transitory(struct gpio_des
        assign_bit(FLAG_TRANSITORY, &desc->flags, transitory);
 
        /* If the driver supports it, set the persistence state now */
-       gc = desc->gdev->chip;
-       if (!gc->set_config)
-               return 0;
-
-       packed = pinconf_to_config_packed(PIN_CONFIG_PERSIST_STATE,
-                                         !transitory);
-       gpio = gpio_chip_hwgpio(desc);
-       rc = gpio_do_set_config(gc, gpio, packed);
-       if (rc == -ENOTSUPP) {
-               dev_dbg(&desc->gdev->dev, "Persistence not supported for GPIO 
%d\n",
-                               gpio);
-               return 0;
-       }
-
-       return rc;
+       return gpio_set_config_with_argument_optional(desc,
+                                                     PIN_CONFIG_PERSIST_STATE,
+                                                     !transitory);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_transitory);
 
@@ -3785,7 +3804,7 @@ struct gpio_desc *fwnode_gpiod_get_index
 
                desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags,
                                              label);
-               if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
+               if (!gpiod_not_found(desc))
                        break;
        }
 
@@ -3961,7 +3980,7 @@ struct gpio_desc *__must_check gpiod_get
         * Either we are not using DT or ACPI, or their lookup did not return
         * a result. In that case, use platform lookup as a fallback.
         */
-       if (!desc || desc == ERR_PTR(-ENOENT)) {
+       if (!desc || gpiod_not_found(desc)) {
                dev_dbg(dev, "using lookup tables for GPIO lookup\n");
                desc = gpiod_find(dev, con_id, idx, &lookupflags);
        }
@@ -3976,7 +3995,7 @@ struct gpio_desc *__must_check gpiod_get
         * the device name as label
         */
        ret = gpiod_request(desc, con_id ? con_id : devname);
-       if (ret < 0) {
+       if (ret ) {
                if (ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
                        /*
                         * This happens when there are several consumers for
@@ -4096,10 +4115,8 @@ struct gpio_desc *__must_check gpiod_get
        struct gpio_desc *desc;
 
        desc = gpiod_get_index(dev, con_id, index, flags);
-       if (IS_ERR(desc)) {
-               if (PTR_ERR(desc) == -ENOENT)
-                       return NULL;
-       }
+       if (gpiod_not_found(desc))
+               return NULL;
 
        return desc;
 }
@@ -4301,7 +4318,7 @@ struct gpio_descs *__must_check gpiod_ge
        struct gpio_descs *descs;
 
        descs = gpiod_get_array(dev, con_id, flags);
-       if (PTR_ERR(descs) == -ENOENT)
+       if (gpiod_not_found(descs))
                return NULL;
 
        return descs;
diff -Narup a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
--- a/drivers/gpio/gpiolib.h    2020-12-14 06:41:30.000000000 +0800
+++ b/drivers/gpio/gpiolib.h    2020-12-22 14:05:04.658807000 +0800
@@ -116,6 +116,7 @@ struct gpio_desc {
 #define FLAG_BIAS_DISABLE    15        /* GPIO has pull disabled */
 #define FLAG_EDGE_RISING     16        /* GPIO CDEV detects rising edge events 
*/
 #define FLAG_EDGE_FALLING    17        /* GPIO CDEV detects falling edge 
events */
+#define FLAG_EVENT_CLOCK_REALTIME      18 /* GPIO CDEV reports REALTIME 
timestamps in events */
 
        /* Connection label */
        const char              *label;
@@ -130,10 +131,13 @@ struct gpio_desc {
 #endif
 };
 
+#define gpiod_not_found(desc)          (IS_ERR(desc) && PTR_ERR(desc) == 
-ENOENT)
+
 int gpiod_request(struct gpio_desc *desc, const char *label);
 void gpiod_free(struct gpio_desc *desc);
 int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
                unsigned long lflags, enum gpiod_flags dflags);
+int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
 int gpiod_hog(struct gpio_desc *desc, const char *name,
                unsigned long lflags, enum gpiod_flags dflags);

-- 
You received this bug notification because you are a member of Ubuntu-X,
which is subscribed to xserver-xorg-input-libinput in Ubuntu.
https://bugs.launchpad.net/bugs/1887190

Title:
  MSFT Touchpad not working on Lenovo Legion-5 15ARH05

To manage notifications about this bug go to:
https://bugs.launchpad.net/pop-os/+bug/1887190/+subscriptions

_______________________________________________
Mailing list: https://launchpad.net/~ubuntu-x-swat
Post to     : ubuntu-x-swat@lists.launchpad.net
Unsubscribe : https://launchpad.net/~ubuntu-x-swat
More help   : https://help.launchpad.net/ListHelp

Reply via email to