mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14
Adrian Hunter
maintainercover mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14
Hi
Here are some patches that fix broken card detect for ACPI HID 80860F14. To do that the card detect GPIO API needed to be extended to support the new GPIO descriptor API.
There are also 2 unrelated but self-explanatory patches appended:
mmc: sdhci-acpi: Add device id 80860F16 mmc: sdhci: Allow for irq being shared.
Adrian Hunter (6):
mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
mmc: slot-gpio: Split out CD IRQ request into a separate function
mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14 SD cards
mmc: sdhci-acpi: Add device id 80860F16
mmc: sdhci: Allow for irq being shared.
Regards
Adrian
Adrian Hunter
maintainerPATCH 1/6 mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
--- drivers/mmc/core/slot-gpio.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)
drivers/mmc/core/slot-gpio.c +27 -18
@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/mmc/host.h>
@@ -18,8 +19,10 @@#include <linux/slab.h> struct mmc_gpio { -int ro_gpio; -int cd_gpio; +struct gpio_desc *ro_gpio; +struct gpio_desc *cd_gpio; +bool override_ro_active_level; +bool override_cd_active_level;char *ro_label;char cd_label[0 ]; };
@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) ctx->ro_label = ctx->cd_label + len;snprintf (ctx->cd_label, len,"%s cd" ,dev_name (host->parent));snprintf (ctx->ro_label, len,"%s ro" ,dev_name (host->parent)); - ctx->cd_gpio = -EINVAL ; - ctx->ro_gpio = -EINVAL ; host->slot.handler_priv = ctx; } }
@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->ro_gpio) ^ - !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); +if (ctx->override_ro_active_level) +return !gpiod_get_raw_value_cansleep (ctx->ro_gpio) ^ + !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);
@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->cd_gpio) ^ - !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); +if (ctx->override_cd_active_level) +return !gpiod_get_raw_value_cansleep (ctx->cd_gpio) ^ + !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->cd_gpio); }EXPORT_SYMBOL (mmc_gpio_get_cd);
@@ -125,7 +132,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)if (ret <0 )return ret; - ctx->ro_gpio = gpio; + ctx->override_ro_active_level = true; + ctx->ro_gpio =gpio_to_desc (gpio);return 0 ; }
@@ -201,7 +209,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,if (irq <0 ) host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->cd_gpio = gpio; + ctx->override_cd_active_level = true; + ctx->cd_gpio =gpio_to_desc (gpio);return 0 ; }
@@ -219,11 +228,11 @@ void mmc_gpio_free_ro(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return ; - gpio = ctx->ro_gpio; - ctx->ro_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->ro_gpio); + ctx->ro_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }
@@ -241,7 +250,7 @@ void mmc_gpio_free_cd(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return ;if (host->slot.cd_irq >=0 ) {
@@ -249,8 +258,8 @@ void mmc_gpio_free_cd(struct mmc_host *host) host->slot.cd_irq = -EINVAL ; } - gpio = ctx->cd_gpio; - ctx->cd_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->cd_gpio); + ctx->cd_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }
Signature · 1 line
1.8.3.2
Re: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
Dear Adrain.
I have tested with your patch-set related slot-gpio. It's working fine. And looks good to me.
I have a question. what's override_cd/ro_active_level?
I didn't fully understand this value. Could you explain to me, plz?
Best Regards,
Jaehoon Chung
Quoted 135 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/core/slot-gpio.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)drivers/mmc/core/slot-gpio.c +27
-18@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/mmc/host.h> @@ -18,8 +19,10 @@#include <linux/slab.h> struct mmc_gpio { -int ro_gpio; -int cd_gpio; +struct gpio_desc *ro_gpio; +struct gpio_desc *cd_gpio; +bool override_ro_active_level; +bool override_cd_active_level;char *ro_label;char cd_label[0 ]; };@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) ctx->ro_label = ctx->cd_label + len;snprintf (ctx->cd_label, len,"%s cd" ,dev_name (host->parent));snprintf (ctx->ro_label, len,"%s ro" ,dev_name (host->parent)); - ctx->cd_gpio = -EINVAL ; - ctx->ro_gpio = -EINVAL ; host->slot.handler_priv = ctx; } }@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->ro_gpio) ^ - !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); +if (ctx->override_ro_active_level) +return !gpiod_get_raw_value_cansleep (ctx->ro_gpio) ^ + !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->cd_gpio) ^ - !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); +if (ctx->override_cd_active_level) +return !gpiod_get_raw_value_cansleep (ctx->cd_gpio) ^ + !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->cd_gpio); }EXPORT_SYMBOL (mmc_gpio_get_cd);@@ -125,7 +132,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)if (ret <0 )return ret; - ctx->ro_gpio = gpio; + ctx->override_ro_active_level = true; + ctx->ro_gpio =gpio_to_desc (gpio);return 0 ; }@@ -201,7 +209,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,if (irq <0 ) host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->cd_gpio = gpio; + ctx->override_cd_active_level = true; + ctx->cd_gpio =gpio_to_desc (gpio);return 0 ; }@@ -219,11 +228,11 @@ void mmc_gpio_free_ro(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return ; - gpio = ctx->ro_gpio; - ctx->ro_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->ro_gpio); + ctx->ro_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }@@ -241,7 +250,7 @@ void mmc_gpio_free_cd(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return ;if (host->slot.cd_irq >=0 ) {@@ -249,8 +258,8 @@ void mmc_gpio_free_cd(struct mmc_host *host) host->slot.cd_irq = -EINVAL ; } - gpio = ctx->cd_gpio; - ctx->cd_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->cd_gpio); + ctx->cd_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }
Adrian Hunter
maintainerRe: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
Quoted 7 lines · Jaehoon Chung
Dear Adrain.
I have tested with your patch-set related slot-gpio. It's working fine. And looks good to me.
I have a question. what's override_cd/ro_active_level?
I didn't fully understand this value. Could you explain to me, plz?
The gpio descriptor records whether the gpio is active high or active low. When using gpiod_get_value_cansleep() the value is inverted on that basis. When using gpiod_get_raw_value_cansleep() the value is not inverted.
The legacy GPIO API did not record active low/high. So then we use gpiod_get_raw_value_cansleep(). The new API should be able to use gpiod_get_value_cansleep().
In addition, for the device that I have the active high/low information passed by ACPI is wrong anyway, so I also have to use the override flag.
Quoted 143 lines
Best Regards,
Jaehoon ChungQuoted 135 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/core/slot-gpio.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)drivers/mmc/core/slot-gpio.c +27
-18@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/mmc/host.h> @@ -18,8 +19,10 @@#include <linux/slab.h> struct mmc_gpio { -int ro_gpio; -int cd_gpio; +struct gpio_desc *ro_gpio; +struct gpio_desc *cd_gpio; +bool override_ro_active_level; +bool override_cd_active_level;char *ro_label;char cd_label[0 ]; };@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) ctx->ro_label = ctx->cd_label + len;snprintf (ctx->cd_label, len,"%s cd" ,dev_name (host->parent));snprintf (ctx->ro_label, len,"%s ro" ,dev_name (host->parent)); - ctx->cd_gpio = -EINVAL ; - ctx->ro_gpio = -EINVAL ; host->slot.handler_priv = ctx; } }@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->ro_gpio) ^ - !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); +if (ctx->override_ro_active_level) +return !gpiod_get_raw_value_cansleep (ctx->ro_gpio) ^ + !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->cd_gpio) ^ - !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); +if (ctx->override_cd_active_level) +return !gpiod_get_raw_value_cansleep (ctx->cd_gpio) ^ + !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->cd_gpio); }EXPORT_SYMBOL (mmc_gpio_get_cd);@@ -125,7 +132,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)if (ret <0 )return ret; - ctx->ro_gpio = gpio; + ctx->override_ro_active_level = true; + ctx->ro_gpio =gpio_to_desc (gpio);return 0 ; }@@ -201,7 +209,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,if (irq <0 ) host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->cd_gpio = gpio; + ctx->override_cd_active_level = true; + ctx->cd_gpio =gpio_to_desc (gpio);return 0 ; }@@ -219,11 +228,11 @@ void mmc_gpio_free_ro(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return ; - gpio = ctx->ro_gpio; - ctx->ro_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->ro_gpio); + ctx->ro_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }@@ -241,7 +250,7 @@ void mmc_gpio_free_cd(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return ;if (host->slot.cd_irq >=0 ) {@@ -249,8 +258,8 @@ void mmc_gpio_free_cd(struct mmc_host *host) host->slot.cd_irq = -EINVAL ; } - gpio = ctx->cd_gpio; - ctx->cd_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->cd_gpio); + ctx->cd_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }
Re: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
Hi, Adrian.
Thanks for kindly explanation.
Best Regards,
Jaehoon Chung
Quoted 171 lines · Adrian Hunter
Quoted 7 lines · Jaehoon Chung
Dear Adrain.
I have tested with your patch-set related slot-gpio. It's working fine. And looks good to me.
I have a question. what's override_cd/ro_active_level?
I didn't fully understand this value. Could you explain to me, plz?The gpio descriptor records whether the gpio is active high or active low. When using
gpiod_get_value_cansleep()the value is inverted on that basis. When usinggpiod_get_raw_value_cansleep()the value is not inverted.The legacy GPIO API did not record active low/high. So then we use
gpiod_get_raw_value_cansleep(). The new API should be able to usegpiod_get_value_cansleep().In addition, for the device that I have the active high/low information passed by ACPI is wrong anyway, so I also have to use the override flag.
Quoted 132 lines
Best Regards,
Jaehoon ChungQuoted 127 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/core/slot-gpio.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)drivers/mmc/core/slot-gpio.c +25
-16@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/mmc/host.h> @@ -18,8 +19,10 @@#include <linux/slab.h> struct mmc_gpio { -int ro_gpio; -int cd_gpio; +struct gpio_desc *ro_gpio; +struct gpio_desc *cd_gpio; +bool override_ro_active_level; +bool override_cd_active_level;char *ro_label;char cd_label[0 ]; };@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) ctx->ro_label = ctx->cd_label + len;snprintf (ctx->cd_label, len,"%s cd" ,dev_name (host->parent));snprintf (ctx->ro_label, len,"%s ro" ,dev_name (host->parent)); - ctx->cd_gpio = -EINVAL ; - ctx->ro_gpio = -EINVAL ; host->slot.handler_priv = ctx; } }@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->ro_gpio) ^ - !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); +if (ctx->override_ro_active_level) +return !gpiod_get_raw_value_cansleep (ctx->ro_gpio) ^ + !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->cd_gpio) ^ - !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); +if (ctx->override_cd_active_level) +return !gpiod_get_raw_value_cansleep (ctx->cd_gpio) ^ + !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->cd_gpio); }EXPORT_SYMBOL (mmc_gpio_get_cd);@@ -125,7 +132,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)if (ret <0 )return ret; - ctx->ro_gpio = gpio; + ctx->override_ro_active_level = true; + ctx->ro_gpio =gpio_to_desc (gpio);return 0 ; }@@ -201,7 +209,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,if (irq <0 ) host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->cd_gpio = gpio; + ctx->override_cd_active_level = true; + ctx->cd_gpio =gpio_to_desc (gpio);return 0 ; }@@ -219,11 +228,11 @@ void mmc_gpio_free_ro(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return ; - gpio = ctx->ro_gpio; - ctx->ro_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->ro_gpio); + ctx->ro_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }@@ -241,7 +250,7 @@ void mmc_gpio_free_cd(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return ;if (host->slot.cd_irq >=0 ) {@@ -249,8 +258,8 @@ void mmc_gpio_free_cd(struct mmc_host *host) host->slot.cd_irq = -EINVAL ; }Quoted 11 lines
drivers/mmc/core/slot-gpio.c void mmc_gpio_free_cd(struct mmc_host *host) · line 265
Quoted 8 lines
drivers/mmc/core/slot-gpio.c +2
-2- gpio = ctx->cd_gpio; - ctx->cd_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->cd_gpio); + ctx->cd_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jaehoon Chung
Tested-byRe: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
After applied "[PATCH 1/6]~[PATCH 3/6]", I have tested on exynos board.
Quoted 185 lines · Jaehoon Chung
Hi, Adrian.
Thanks for kindly explanation.
Best Regards,
Jaehoon ChungQuoted 166 lines · Adrian Hunter
Quoted 7 lines · Jaehoon Chung
Dear Adrain.
I have tested with your patch-set related slot-gpio. It's working fine. And looks good to me.
I have a question. what's override_cd/ro_active_level?
I didn't fully understand this value. Could you explain to me, plz?The gpio descriptor records whether the gpio is active high or active low. When using
gpiod_get_value_cansleep()the value is inverted on that basis. When usinggpiod_get_raw_value_cansleep()the value is not inverted.The legacy GPIO API did not record active low/high. So then we use
gpiod_get_raw_value_cansleep(). The new API should be able to usegpiod_get_value_cansleep().In addition, for the device that I have the active high/low information passed by ACPI is wrong anyway, so I also have to use the override flag.
Quoted 132 lines
Best Regards,
Jaehoon ChungQuoted 127 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/core/slot-gpio.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)drivers/mmc/core/slot-gpio.c +25
-16@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/mmc/host.h> @@ -18,8 +19,10 @@#include <linux/slab.h> struct mmc_gpio { -int ro_gpio; -int cd_gpio; +struct gpio_desc *ro_gpio; +struct gpio_desc *cd_gpio; +bool override_ro_active_level; +bool override_cd_active_level;char *ro_label;char cd_label[0 ]; };@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) ctx->ro_label = ctx->cd_label + len;snprintf (ctx->cd_label, len,"%s cd" ,dev_name (host->parent));snprintf (ctx->ro_label, len,"%s ro" ,dev_name (host->parent)); - ctx->cd_gpio = -EINVAL ; - ctx->ro_gpio = -EINVAL ; host->slot.handler_priv = ctx; } }@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->ro_gpio) ^ - !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); +if (ctx->override_ro_active_level) +return !gpiod_get_raw_value_cansleep (ctx->ro_gpio) ^ + !!(host->caps2 &MMC_CAP2_RO_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return -ENOSYS ; -return !gpio_get_value_cansleep (ctx->cd_gpio) ^ - !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); +if (ctx->override_cd_active_level) +return !gpiod_get_raw_value_cansleep (ctx->cd_gpio) ^ + !!(host->caps2 &MMC_CAP2_CD_ACTIVE_HIGH ); + +return gpiod_get_value_cansleep (ctx->cd_gpio); }EXPORT_SYMBOL (mmc_gpio_get_cd);@@ -125,7 +132,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)if (ret <0 )return ret; - ctx->ro_gpio = gpio; + ctx->override_ro_active_level = true; + ctx->ro_gpio =gpio_to_desc (gpio);return 0 ; }@@ -201,7 +209,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,if (irq <0 ) host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->cd_gpio = gpio; + ctx->override_cd_active_level = true; + ctx->cd_gpio =gpio_to_desc (gpio);return 0 ; }@@ -219,11 +228,11 @@ void mmc_gpio_free_ro(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->ro_gpio)) +if (!ctx || !ctx->ro_gpio)return ; - gpio = ctx->ro_gpio; - ctx->ro_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->ro_gpio); + ctx->ro_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }@@ -241,7 +250,7 @@ void mmc_gpio_free_cd(struct mmc_host *host)struct mmc_gpio *ctx = host->slot.handler_priv;int gpio; -if (!ctx || !gpio_is_valid (ctx->cd_gpio)) +if (!ctx || !ctx->cd_gpio)return ;if (host->slot.cd_irq >=0 ) {@@ -249,8 +258,8 @@ void mmc_gpio_free_cd(struct mmc_host *host) host->slot.cd_irq = -EINVAL ; }Quoted 11 lines
drivers/mmc/core/slot-gpio.c void mmc_gpio_free_cd(struct mmc_host *host) · line 265
Quoted 8 lines
drivers/mmc/core/slot-gpio.c +2
-2- gpio = ctx->cd_gpio; - ctx->cd_gpio = -EINVAL ; + gpio =desc_to_gpio (ctx->cd_gpio); + ctx->cd_gpio =NULL ;devm_gpio_free (&host->class_dev, gpio); }Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
In reply to Adrian HunterQuoted 5 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>
Certainly this makes things look better from a GPIO POV so Acked-by.
However:
(...)
Quoted 1 line
+
ctx->ro_gpio=gpio_to_desc(gpio);
(...)
Quoted 1 line
+
ctx->cd_gpio=gpio_to_desc(gpio);
How much harder would it be to switch the platforms using this MMC driver to pass GPIO descriptors using the gpiod_lookup_table in affected platforms (or device tree or ACPI) and then use devm_gpiod_get[_index]() in probe()?
This can certainly be step 2, but that is where we want to go with the GPIO clean-up work in the long run.
Yours,
Linus Walleij
Adrian Hunter
maintainerRe: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
Quoted 14 lines · Linus Walleij
Quoted 5 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>Certainly this makes things look better from a GPIO POV so Acked-by.
However:
(...)
Quoted 8 lines
Quoted 1 line
+
ctx->ro_gpio=gpio_to_desc(gpio);(...)
Quoted 1 line
+
ctx->cd_gpio=gpio_to_desc(gpio);How much harder would it be to switch the platforms using this MMC driver to pass GPIO descriptors using the
gpiod_lookup_tablein affected platforms (or device tree or ACPI) and then use devm_gpiod_get[_index]() inprobe()?
There are 10 drivers plus users of mmc_of_config(), so too much work for me right now. Also parts that relate to device-tree are outside my sphere.
Quoted 2 lines
This can certainly be step 2, but that is where we want to go with the GPIO clean-up work in the long run.
Perhaps Ulf or Guennadi would be interested.
Adrian Hunter
maintainerRe: [PATCH 1/6] mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
In reply to Linus WalleijResent with updated email address for Ulf.
Quoted 14 lines · Linus Walleij
Quoted 5 lines · Adrian Hunter
In preparation for adding a descriptor-based CD GPIO API, switch from recording GPIO numbers to recording GPIO descriptors.
Signed-off-by Adrian Hunter <[email protected]>Certainly this makes things look better from a GPIO POV so Acked-by.
However:
(...)
Quoted 8 lines
Quoted 1 line
+
ctx->ro_gpio=gpio_to_desc(gpio);(...)
Quoted 1 line
+
ctx->cd_gpio=gpio_to_desc(gpio);How much harder would it be to switch the platforms using this MMC driver to pass GPIO descriptors using the
gpiod_lookup_tablein affected platforms (or device tree or ACPI) and then use devm_gpiod_get[_index]() inprobe()?
There are 10 drivers plus users of mmc_of_config(), so too much work for me right now. Also parts that relate to device-tree are outside my sphere.
Quoted 2 lines
This can certainly be step 2, but that is where we want to go with the GPIO clean-up work in the long run.
Perhaps Ulf or Guennadi would be interested.
Adrian Hunter
maintainerPATCH 2/6 mmc: slot-gpio: Split out CD IRQ request into a separate function
In reply to Adrian HunterIn preparation for adding a descriptor-based CD GPIO API, split out CD IRQ request into a separate function.
--- drivers/mmc/core/slot-gpio.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 23 deletions(-)
drivers/mmc/core/slot-gpio.c +35 -23
@@ -139,6 +139,39 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) }EXPORT_SYMBOL (mmc_gpio_request_ro); +static void mmc_gpiod_request_cd_irq (struct mmc_host *host) +{ +struct mmc_gpio *ctx = host->slot.handler_priv; +int ret, irq; + +if (host->slot.cd_irq >=0 || !ctx || !ctx->cd_gpio) +return ; + + irq =gpiod_to_irq (ctx->cd_gpio); + +/* +* Even if gpiod_to_irq() returns a valid IRQ number, the platform might +* still prefer to poll, e.g., because that IRQ number is already used +* by another unit and cannot be shared. +*/ +if (irq >=0 && host->caps &MMC_CAP_NEEDS_POLL ) + irq = -EINVAL ; + +if (irq >=0 ) { + ret =devm_request_threaded_irq (&host->class_dev, irq, +NULL , mmc_gpio_cd_irqt, +IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT , + ctx->cd_label, host); +if (ret <0 ) + irq = ret; + } + + host->slot.cd_irq = irq; + +if (irq <0 ) + host->caps |=MMC_CAP_NEEDS_POLL ; +} +/** * mmc_gpio_request_cd - request a gpio for card-detection * @host: mmc host
@@ -162,7 +195,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, unsigned int debounce) {struct mmc_gpio *ctx; -int irq =gpio_to_irq (gpio);int ret; ret =mmc_gpio_alloc (host);
@@ -187,31 +219,11 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,return ret; } -/* -* Even if gpio_to_irq() returns a valid IRQ number, the platform might -* still prefer to poll, e.g., because that IRQ number is already used -* by another unit and cannot be shared. -*/ -if (irq >=0 && host->caps &MMC_CAP_NEEDS_POLL ) - irq = -EINVAL ; - -if (irq >=0 ) { - ret =devm_request_threaded_irq (&host->class_dev, irq, -NULL , mmc_gpio_cd_irqt, -IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT , - ctx->cd_label, host); -if (ret <0 ) - irq = ret; - } - - host->slot.cd_irq = irq; - -if (irq <0 ) - host->caps |=MMC_CAP_NEEDS_POLL ; - ctx->override_cd_active_level = true; ctx->cd_gpio =gpio_to_desc (gpio); +mmc_gpiod_request_cd_irq (host); +return 0 ; }EXPORT_SYMBOL (mmc_gpio_request_cd);
Signature · 1 line
1.8.3.2
Adrian Hunter
maintainerPATCH 3/6 mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
In reply to Adrian HunterAdd functions to request a CD GPIO using the GPIO descriptor API. Note that the new request function is paired with mmc_gpiod_free_cd() not mmc_gpio_free_cd(). Note also that it must be called prior to mmc_add_host() otherwise the caller must also call mmc_gpiod_request_cd_irq().
--- drivers/mmc/core/core.c | 4 +++ drivers/mmc/core/slot-gpio.c | 81 ++++++++++++++++++++++++++++++++++++++++++- include/linux/mmc/slot-gpio.h | 6 ++++ 3 files changed, 90 insertions(+), 1 deletion(-)
drivers/mmc/core/core.c +4 -0
@@ -34,6 +34,7 @@#include <linux/mmc/host.h> #include <linux/mmc/mmc.h> #include <linux/mmc/sd.h> +#include <linux/mmc/slot-gpio.h> #include "core.h" #include "bus.h"
@@ -2471,6 +2472,7 @@ void mmc_start_host(struct mmc_host *host)mmc_power_off (host); else mmc_power_up(host, host->ocr_avail); +mmc_gpiod_request_cd_irq (host);_mmc_detect_change (host,0 , false); }
@@ -2482,6 +2484,8 @@ void mmc_stop_host(struct mmc_host *host) host->removed =1 ;spin_unlock_irqrestore (&host->lock, flags);#endif +if (host->slot.cd_irq >=0 ) +disable_irq (host->slot.cd_irq); host->rescan_disable =1 ;cancel_delayed_work_sync (&host->detect);
drivers/mmc/core/slot-gpio.c +80 -1
96 lines not on this page · raw message
include/linux/mmc/slot-gpio.h +6 -0
@@ -22,4 +22,10 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, unsigned int debounce);void mmc_gpio_free_cd (struct mmc_host *host); +int mmc_gpiod_request_cd (struct mmc_host *host,const char *con_id, +unsigned int idx,bool override_active_level, +unsigned int debounce); +void mmc_gpiod_free_cd (struct mmc_host *host); +void mmc_gpiod_request_cd_irq (struct mmc_host *host); +#endif
Signature · 1 line
1.8.3.2
Re: [PATCH 3/6] mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
Quoted 7 lines · Adrian Hunter
Add functions to request a CD GPIO using the GPIO descriptor API. Note that the new request function is paired with
mmc_gpiod_free_cd()notmmc_gpio_free_cd(). Note also that it must be called prior tommc_add_host()otherwise the caller must also callmmc_gpiod_request_cd_irq().Signed-off-by Adrian Hunter <[email protected]>
This is very helpful.
Yours,
Linus Walleij
Adrian Hunter
maintainerPATCH 4/6 mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14
In reply to Adrian HunterSome 80860F14 devices do not support card detect and must rely completely on GPIO. Presently the card detect GPIO is used only to wake-up from runtime suspend. Change to using mmc_gpioid_request_cd() which will cause the SDHCI driver to prefer the GPIO to the host controller's native card detect.
--- drivers/mmc/host/sdhci-acpi.c | 77 +++++++++---------------------------------- 1 file changed, 15 insertions(+), 62 deletions(-)
drivers/mmc/host/sdhci-acpi.c +15 -62
@@ -31,7 +31,6 @@#include <linux/bitops.h> #include <linux/types.h> #include <linux/err.h> -#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/acpi.h> #include <linux/pm.h>
@@ -40,13 +39,15 @@#include <linux/mmc/host.h> #include <linux/mmc/pm.h> +#include <linux/mmc/slot-gpio.h> #include <linux/mmc/sdhci.h> #include "sdhci.h" enum { -SDHCI_ACPI_SD_CD =BIT (0 ), -SDHCI_ACPI_RUNTIME_PM =BIT (1 ), +SDHCI_ACPI_SD_CD =BIT (0 ), +SDHCI_ACPI_RUNTIME_PM =BIT (1 ), +SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL =BIT (2 ), };struct sdhci_acpi_chip {
@@ -128,7 +129,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { };static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { - .flags =SDHCI_ACPI_SD_CD |SDHCI_ACPI_RUNTIME_PM , + .flags =SDHCI_ACPI_SD_CD |SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | +SDHCI_ACPI_RUNTIME_PM , .quirks2 =SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON , };
@@ -192,59 +194,6 @@ static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle,return slot; } -#ifdef CONFIG_PM_RUNTIME - -static irqreturn_t sdhci_acpi_sd_cd (int irq,void *dev_id) -{ -mmc_detect_change (dev_id,msecs_to_jiffies (200 )); -return IRQ_HANDLED ; -} - -static int sdhci_acpi_add_own_cd (struct device *dev,struct mmc_host *mmc) -{ -struct gpio_desc *desc; -unsigned long flags; -int err, irq; - - desc =devm_gpiod_get_index (dev,"sd_cd" ,0 ); -if (IS_ERR (desc)) { - err =PTR_ERR (desc); - goto out; - } - - err =gpiod_direction_input (desc); -if (err) - goto out_free; - - irq =gpiod_to_irq (desc); -if (irq <0 ) { - err = irq; - goto out_free; - } - - flags =IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING ; - err =devm_request_irq (dev, irq, sdhci_acpi_sd_cd, flags,"sd_cd" , mmc); -if (err) - goto out_free; - -return 0 ; - -out_free: -devm_gpiod_put (dev, desc); -out: -dev_warn (dev,"failed to setup card detect wake up\n" ); -return err; -} - -#else - -static int sdhci_acpi_add_own_cd (struct device *dev,struct mmc_host *mmc) -{ -return 0 ; -} - -#endif -static int sdhci_acpi_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -332,15 +281,19 @@ static int sdhci_acpi_probe(struct platform_device *pdev) host->mmc->caps2 |=MMC_CAP2_NO_PRESCAN_POWERUP ; - err =sdhci_add_host (host); -if (err) - goto err_free; -if (sdhci_acpi_flag (c,SDHCI_ACPI_SD_CD )) { -if (sdhci_acpi_add_own_cd (dev, host->mmc)) +bool v =sdhci_acpi_flag (c,SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL ); + +if (mmc_gpiod_request_cd (host->mmc,NULL ,0 , v,0 )) { +dev_warn (dev,"failed to setup card detect gpio\n" ); c->use_runtime_pm = false; + } } + err =sdhci_add_host (host); +if (err) + goto err_free; +if (c->use_runtime_pm) {pm_runtime_set_active (dev);pm_suspend_ignore_children (dev,1 );
Signature · 1 line
1.8.3.2
Adrian Hunter
maintainerPATCH 5/6 mmc: sdhci-acpi: Add device id 80860F16
In reply to Adrian HunterAdd ACPI HID 80860F16 as a host controller for
a SD card.
--- drivers/mmc/host/sdhci-acpi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mmc/host/sdhci-acpi.c +2 -0
@@ -143,6 +143,7 @@ struct sdhci_acpi_uid_slot {static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { {"80860F14" ,"1" , &sdhci_acpi_slot_int_emmc }, {"80860F14" ,"3" , &sdhci_acpi_slot_int_sd }, + {"80860F16" ,NULL , &sdhci_acpi_slot_int_sd }, {"INT33BB" ,"2" , &sdhci_acpi_slot_int_sdio }, {"INT33C6" ,NULL , &sdhci_acpi_slot_int_sdio }, {"INT3436" ,NULL , &sdhci_acpi_slot_int_sdio },
@@ -152,6 +153,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {static const struct acpi_device_id sdhci_acpi_ids[] = { {"80860F14" }, + {"80860F16" }, {"INT33BB" }, {"INT33C6" }, {"INT3436" },
Signature · 1 line
1.8.3.2
Adrian Hunter
maintainerPATCH 6/6 mmc: sdhci: Allow for irq being shared.
In reply to Adrian HunterIf the SDHCI irq is shared with another device then the interrupt handler can get called while SDHCI is runtime suspended. That is harmless but the warning message is no longer useful so remove it.
--- drivers/mmc/host/sdhci.c | 2 -- 1 file changed, 2 deletions(-)
drivers/mmc/host/sdhci.c +0 -2
@@ -2434,8 +2434,6 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)if (host->runtime_suspended) {spin_unlock (&host->lock); -pr_warning ("%s: got irq while runtime suspended\n" , -mmc_hostname (host->mmc));return IRQ_HANDLED ; }
Signature · 1 line
1.8.3.2
Adrian Hunter
maintainerPATCH v2 6/6 mmc: sdhci: Allow for irq being shared.
If the SDHCI irq is shared with another device then the interrupt handler can get called while SDHCI is runtime suspended. That is harmless but the warning message is not useful so remove it. Also returning IRQ_NONE is more appropriate.
---
Changes in V2:
Return IRQ_NONE instead of IRQ_HANDLED
drivers/mmc/host/sdhci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/mmc/host/sdhci.c +1 -3
@@ -2434,9 +2434,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)if (host->runtime_suspended) {spin_unlock (&host->lock); -pr_warning ("%s: got irq while runtime suspended\n" , -mmc_hostname (host->mmc)); -return IRQ_HANDLED ; +return IRQ_NONE ; } intmask =sdhci_readl (host,SDHCI_INT_STATUS );
Signature · 1 line
1.8.3.2
Adrian Hunter
maintainerQuoted 12 lines · Adrian Hunter
Hi
Here are some patches that fix broken card detect for ACPI HID 80860F14. To do that the card detect GPIO API needed to be extended to support the new GPIO descriptor API.
There are also 2 unrelated but self-explanatory patches appended:
mmc: sdhci-acpi: Add device id 80860F16 mmc: sdhci: Allow for irq being shared.
Quoted 7 lines
Adrian Hunter (6):
mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
mmc: slot-gpio: Split out CD IRQ request into a separate function
mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14 SD cards
mmc: sdhci-acpi: Add device id 80860F16
mmc: sdhci: Allow for irq being shared.
Chris, can these be queued for 3.15? Note I did a V2 of just "mmc: sdhci:
Allow for irq being shared"
Hi Adrian,
Quoted 10 lines · Adrian Hunter
Quoted 7 lines
Adrian Hunter (6):
mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
mmc: slot-gpio: Split out CD IRQ request into a separate function
mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14 SD cards
mmc: sdhci-acpi: Add device id 80860F16
mmc: sdhci: Allow for irq being shared.Chris, can these be queued for 3.15? Note I did a V2 of just "mmc: sdhci:
Allow for irq being shared"
Thanks, merged all six patches (with v2 of 6/6) to mmc-next for 3.15.
- Chris.
Signature · 1 line
Chris Ball <[email protected]> <http://printf.net/>