mmc: atmel-mci: Move card detect gpio polarity quirk to gpiolib
authorBalamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
Fri, 25 Aug 2023 09:51:57 +0000 (15:21 +0530)
committerUlf Hansson <ulf.hansson@linaro.org>
Fri, 25 Aug 2023 11:40:21 +0000 (13:40 +0200)
The polarity of the card detection gpio is handled by the "cd-inverted"
property in the device tree. Move this inversion logic to gpiolib to avoid
reading the gpio raw value.

Signed-off-by: Balamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
Suggested-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20230825095157.76073-4-balamanikandan.gunasundar@microchip.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/gpio/gpiolib-of.c
drivers/mmc/host/atmel-mci.c

index 1436cdb..9694eb5 100644 (file)
@@ -209,6 +209,8 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np,
                                             const char *propname,
                                             enum of_gpio_flags *flags)
 {
+       const struct device_node *np_compat = np;
+       const struct device_node *np_propname = np;
        static const struct {
                const char *compatible;
                const char *gpio_propname;
@@ -253,14 +255,28 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np,
                { "regulator-gpio",    "enable-gpio",  "enable-active-high" },
                { "regulator-gpio",    "enable-gpios", "enable-active-high" },
 #endif
+#if IS_ENABLED(CONFIG_MMC_ATMELMCI)
+               { "atmel,hsmci",       "cd-gpios",     "cd-inverted" },
+#endif
        };
        unsigned int i;
        bool active_high;
 
+#if IS_ENABLED(CONFIG_MMC_ATMELMCI)
+       /*
+        * The Atmel HSMCI has compatible property in the parent node and
+        * gpio property in a child node
+        */
+       if (of_device_is_compatible(np->parent, "atmel,hsmci")) {
+               np_compat = np->parent;
+               np_propname = np;
+       }
+#endif
+
        for (i = 0; i < ARRAY_SIZE(gpios); i++) {
-               if (of_device_is_compatible(np, gpios[i].compatible) &&
+               if (of_device_is_compatible(np_compat, gpios[i].compatible) &&
                    !strcmp(propname, gpios[i].gpio_propname)) {
-                       active_high = of_property_read_bool(np,
+                       active_high = of_property_read_bool(np_propname,
                                                gpios[i].polarity_propname);
                        of_gpio_quirk_polarity(np, active_high, flags);
                        break;
index 6f81581..535783c 100644 (file)
@@ -206,7 +206,6 @@ enum atmci_pdc_buf {
  * @bus_width: Number of data lines wired up the slot
  * @detect_pin: GPIO pin wired to the card detect switch
  * @wp_pin: GPIO pin wired to the write protect sensor
- * @detect_is_active_high: The state of the detect pin when it is active
  * @non_removable: The slot is not removable, only detect once
  *
  * If a given slot is not present on the board, @bus_width should be
@@ -222,7 +221,6 @@ struct mci_slot_pdata {
        unsigned int            bus_width;
        struct gpio_desc        *detect_pin;
        struct gpio_desc        *wp_pin;
-       bool                    detect_is_active_high;
        bool                    non_removable;
 };
 
@@ -405,7 +403,6 @@ struct atmel_mci {
  *     available.
  * @wp_pin: GPIO pin used for card write protect sending, or negative
  *     if not available.
- * @detect_is_active_high: The state of the detect pin when it is active.
  * @detect_timer: Timer used for debouncing @detect_pin interrupts.
  */
 struct atmel_mci_slot {
@@ -426,7 +423,6 @@ struct atmel_mci_slot {
 
        struct gpio_desc        *detect_pin;
        struct gpio_desc        *wp_pin;
-       bool                    detect_is_active_high;
 
        struct timer_list       detect_timer;
 };
@@ -644,6 +640,7 @@ atmci_of_init(struct platform_device *pdev)
        struct device_node *cnp;
        struct mci_platform_data *pdata;
        u32 slot_id;
+       int err;
 
        if (!np) {
                dev_err(&pdev->dev, "device node not found\n");
@@ -675,11 +672,12 @@ atmci_of_init(struct platform_device *pdev)
                pdata->slot[slot_id].detect_pin =
                        devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
                                              "cd", GPIOD_IN, "cd-gpios");
-               if (IS_ERR(pdata->slot[slot_id].detect_pin))
+               err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].detect_pin);
+               if (err) {
+                       if (err != -ENOENT)
+                               return ERR_PTR(err);
                        pdata->slot[slot_id].detect_pin = NULL;
-
-               pdata->slot[slot_id].detect_is_active_high =
-                       of_property_read_bool(cnp, "cd-inverted");
+               }
 
                pdata->slot[slot_id].non_removable =
                        of_property_read_bool(cnp, "non-removable");
@@ -687,8 +685,12 @@ atmci_of_init(struct platform_device *pdev)
                pdata->slot[slot_id].wp_pin =
                        devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(cnp),
                                              "wp", GPIOD_IN, "wp-gpios");
-               if (IS_ERR(pdata->slot[slot_id].wp_pin))
+               err = PTR_ERR_OR_ZERO(pdata->slot[slot_id].wp_pin);
+               if (err) {
+                       if (err != -ENOENT)
+                               return ERR_PTR(err);
                        pdata->slot[slot_id].wp_pin = NULL;
+               }
        }
 
        return pdata;
@@ -1566,8 +1568,7 @@ static int atmci_get_cd(struct mmc_host *mmc)
        struct atmel_mci_slot   *slot = mmc_priv(mmc);
 
        if (slot->detect_pin) {
-               present = !(gpiod_get_raw_value(slot->detect_pin) ^
-                           slot->detect_is_active_high);
+               present = gpiod_get_value_cansleep(slot->detect_pin);
                dev_dbg(&mmc->class_dev, "card is %spresent\n",
                                present ? "" : "not ");
        }
@@ -1680,8 +1681,7 @@ static void atmci_detect_change(struct timer_list *t)
                return;
 
        enable_irq(gpiod_to_irq(slot->detect_pin));
-       present = !(gpiod_get_raw_value(slot->detect_pin) ^
-                   slot->detect_is_active_high);
+       present = gpiod_get_value_cansleep(slot->detect_pin);
        present_old = test_bit(ATMCI_CARD_PRESENT, &slot->flags);
 
        dev_vdbg(&slot->mmc->class_dev, "detect change: %d (was %d)\n",
@@ -2272,7 +2272,6 @@ static int atmci_init_slot(struct atmel_mci *host,
        slot->host = host;
        slot->detect_pin = slot_data->detect_pin;
        slot->wp_pin = slot_data->wp_pin;
-       slot->detect_is_active_high = slot_data->detect_is_active_high;
        slot->sdc_reg = sdc_reg;
        slot->sdio_irq = sdio_irq;
 
@@ -2280,7 +2279,7 @@ static int atmci_init_slot(struct atmel_mci *host,
                "slot[%u]: bus_width=%u, detect_pin=%d, "
                "detect_is_active_high=%s, wp_pin=%d\n",
                id, slot_data->bus_width, desc_to_gpio(slot_data->detect_pin),
-               slot_data->detect_is_active_high ? "true" : "false",
+               !gpiod_is_active_low(slot_data->detect_pin) ? "true" : "false",
                desc_to_gpio(slot_data->wp_pin));
 
        mmc->ops = &atmci_ops;
@@ -2318,10 +2317,8 @@ static int atmci_init_slot(struct atmel_mci *host,
        /* Assume card is present initially */
        set_bit(ATMCI_CARD_PRESENT, &slot->flags);
        if (slot->detect_pin) {
-               if (gpiod_get_raw_value(slot->detect_pin) ^
-                   slot->detect_is_active_high) {
+               if (!gpiod_get_value_cansleep(slot->detect_pin))
                        clear_bit(ATMCI_CARD_PRESENT, &slot->flags);
-               }
        } else {
                dev_dbg(&mmc->class_dev, "no detect pin available\n");
        }