mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 14:43:16 +00:00
mmc: core: Rework cd-gpio handling
There are a few places around the code that invert inverted and possibly inverted CD line. That's really confusing. Squash them all into one place in mmc_gpiod_request_cd(). MMC_CAP2_CD_ACTIVE_HIGH is used analogously to WP line: in GPIO mode it is used only at probe time to switch polarity, for native mode it is left as is. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Link: https://lore.kernel.org/r/db189b715596d63caf8c6a088bddc71dd69a879b.1576031637.git.mirq-linux@rere.qmqm.pl Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
9073d10b09
commit
0f7c815d83
@ -104,23 +104,6 @@ static void of_gpio_flags_quirks(struct device_node *np,
|
||||
enum of_gpio_flags *flags,
|
||||
int index)
|
||||
{
|
||||
/*
|
||||
* Handle MMC "cd-inverted" and "wp-inverted" semantics.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MMC)) {
|
||||
/*
|
||||
* Active low is the default according to the
|
||||
* SDHCI specification and the device tree
|
||||
* bindings. However the code in the current
|
||||
* kernel was written such that the phandle
|
||||
* flags were always respected, and "cd-inverted"
|
||||
* would invert the flag from the device phandle.
|
||||
*/
|
||||
if (!strcmp(propname, "cd-gpios")) {
|
||||
if (of_property_read_bool(np, "cd-inverted"))
|
||||
*flags ^= OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Some GPIO fixed regulator quirks.
|
||||
* Note that active low is the default.
|
||||
|
@ -175,7 +175,6 @@ int mmc_of_parse(struct mmc_host *host)
|
||||
struct device *dev = host->parent;
|
||||
u32 bus_width, drv_type, cd_debounce_delay_ms;
|
||||
int ret;
|
||||
bool cd_cap_invert, cd_gpio_invert = false;
|
||||
|
||||
if (!dev || !dev_fwnode(dev))
|
||||
return 0;
|
||||
@ -218,10 +217,12 @@ int mmc_of_parse(struct mmc_host *host)
|
||||
*/
|
||||
|
||||
/* Parse Card Detection */
|
||||
|
||||
if (device_property_read_bool(dev, "non-removable")) {
|
||||
host->caps |= MMC_CAP_NONREMOVABLE;
|
||||
} else {
|
||||
cd_cap_invert = device_property_read_bool(dev, "cd-inverted");
|
||||
if (device_property_read_bool(dev, "cd-inverted"))
|
||||
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
||||
|
||||
if (device_property_read_u32(dev, "cd-debounce-delay-ms",
|
||||
&cd_debounce_delay_ms))
|
||||
@ -232,25 +233,11 @@ int mmc_of_parse(struct mmc_host *host)
|
||||
|
||||
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
|
||||
cd_debounce_delay_ms * 1000,
|
||||
&cd_gpio_invert);
|
||||
NULL);
|
||||
if (!ret)
|
||||
dev_info(host->parent, "Got CD GPIO\n");
|
||||
else if (ret != -ENOENT && ret != -ENOSYS)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* There are two ways to flag that the CD line is inverted:
|
||||
* through the cd-inverted flag and by the GPIO line itself
|
||||
* being inverted from the GPIO subsystem. This is a leftover
|
||||
* from the times when the GPIO subsystem did not make it
|
||||
* possible to flag a line as inverted.
|
||||
*
|
||||
* If the capability on the host AND the GPIO line are
|
||||
* both inverted, the end result is that the CD line is
|
||||
* not inverted.
|
||||
*/
|
||||
if (cd_cap_invert ^ cd_gpio_invert)
|
||||
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
||||
}
|
||||
|
||||
/* Parse Write Protection */
|
||||
|
@ -19,7 +19,6 @@
|
||||
struct mmc_gpio {
|
||||
struct gpio_desc *ro_gpio;
|
||||
struct gpio_desc *cd_gpio;
|
||||
bool override_cd_active_level;
|
||||
irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id);
|
||||
char *ro_label;
|
||||
char *cd_label;
|
||||
@ -80,13 +79,6 @@ int mmc_gpio_get_cd(struct mmc_host *host)
|
||||
return -ENOSYS;
|
||||
|
||||
cansleep = gpiod_cansleep(ctx->cd_gpio);
|
||||
if (ctx->override_cd_active_level) {
|
||||
int value = cansleep ?
|
||||
gpiod_get_raw_value_cansleep(ctx->cd_gpio) :
|
||||
gpiod_get_raw_value(ctx->cd_gpio);
|
||||
return !value ^ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
|
||||
}
|
||||
|
||||
return cansleep ?
|
||||
gpiod_get_value_cansleep(ctx->cd_gpio) :
|
||||
gpiod_get_value(ctx->cd_gpio);
|
||||
@ -194,10 +186,17 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
|
||||
ctx->cd_debounce_delay_ms = debounce / 1000;
|
||||
}
|
||||
|
||||
/* override forces default (active-low) polarity ... */
|
||||
if (override_active_level && !gpiod_is_active_low(desc))
|
||||
gpiod_toggle_active_low(desc);
|
||||
|
||||
/* ... or active-high */
|
||||
if (host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
|
||||
gpiod_toggle_active_low(desc);
|
||||
|
||||
if (gpio_invert)
|
||||
*gpio_invert = !gpiod_is_active_low(desc);
|
||||
|
||||
ctx->override_cd_active_level = override_active_level;
|
||||
ctx->cd_gpio = desc;
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user