diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 69e29f4..d79c6d7 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -180,6 +180,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { { "80860F14", (unsigned long)&byt_sdio_dev_desc }, { "80860F41", (unsigned long)&byt_i2c_dev_desc }, { "INT33B2", }, + { "INT33FC", }, { "INT3430", (unsigned long)&lpt_dev_desc }, { "INT3431", (unsigned long)&lpt_dev_desc }, diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index ebb3f39..ebed2a0 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -123,7 +123,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION, - .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, + .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | SDHCI_QUIRK2_BROKEN_POWER_ENABLE, .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, .flags = SDHCI_ACPI_RUNTIME_PM, .pm_caps = MMC_PM_KEEP_POWER, diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index 6e8301f..6c8eda2 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -151,9 +151,9 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, static bool is_special_pin(struct byt_gpio *vg, unsigned offset) { - /* SCORE pin 92-93 */ + /* SCORE pin 92-93; 41 for SDIO pwr_en bug */ if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && - offset >= 92 && offset <= 93) + ((offset >= 92 && offset <= 93) || (offset == 41))) return true; /* SUS pin 11-21 */ @@ -176,6 +176,10 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) * But, some pins may have func pin mux 001 represents * GPIO function. Only allow user to export pin with * func pin mux preset as GPIO function by BIOS/FW. + * + * We do make an exception, however, for pin 41 which + * is needed in order to power up the SDIO bus (as per + * the intel erratum) */ value = readl(reg) & BYT_PIN_MUX; special = is_special_pin(vg, offset); @@ -185,6 +189,13 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) return -EINVAL; } + /* This is an attempt to stop the SDHCI drivers from requesting IRQ lines + * through the pinctrl driver. This may be a quirk in the hardware or it + * may be a bug here in the IRQ handling + */ + if (offset == 38) + return -EINVAL; + pm_runtime_get(&vg->pdev->dev); return 0; @@ -572,6 +583,7 @@ static const struct dev_pm_ops byt_gpio_pm_ops = { static const struct acpi_device_id byt_gpio_acpi_match[] = { { "INT33B2", 0 }, + { "INT33FC", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 7be12b8..3a7fd87 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -102,6 +102,8 @@ struct sdhci_host { #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6) /* Controller does not support DDR50 */ #define SDHCI_QUIRK2_BROKEN_DDR50 (1<<7) +/* Controller cannot initialize power (must use GPIO instead) */ +#define SDHCI_QUIRK2_BROKEN_POWER_ENABLE (1<<8) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */