diff options
author | Hans de Goede <hdegoede@redhat.com> | 2017-06-14 17:30:36 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2017-06-23 10:59:39 +0200 |
commit | 88f3771491aa5e04aeb32607a30aaa632158e961 (patch) | |
tree | 6cd01958277a7f55962a826fd7a6d72d1c5454f7 /0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch | |
parent | 6b98e5e530e3b2c55e00df68c9537ac767058da5 (diff) | |
download | kernel-88f3771491aa5e04aeb32607a30aaa632158e961.tar.gz kernel-88f3771491aa5e04aeb32607a30aaa632158e961.tar.xz kernel-88f3771491aa5e04aeb32607a30aaa632158e961.zip |
Improve Bay and Cherry Trail device support
- Enable AXP288 PMIC support on x86_64 for battery charging and monitoring
support on Bay and Cherry Trail tablets and laptops
- Enable various drivers for peripherals found on Bay and Cherry Trail tablets
- Add some small patches fixing suspend/resume touchscreen and accelerometer
issues on various Bay and Cherry Trail tablets
Diffstat (limited to '0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch')
-rw-r--r-- | 0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch b/0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch new file mode 100644 index 000000000..b5c717c64 --- /dev/null +++ b/0014-mmc-sdhci-acpi-Workaround-conflict-with-PCI-wifi-on-.patch @@ -0,0 +1,143 @@ +From 51eb7454942c68c84b82782e47637de3ba37f113 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter <adrian.hunter@intel.com> +Date: Wed, 21 Jun 2017 15:08:39 +0300 +Subject: [PATCH 14/16] mmc: sdhci-acpi: Workaround conflict with PCI wifi on + GPD Win handheld + +GPDwin uses PCI wifi which conflicts with SDIO's use of +acpi_device_fix_up_power() on child device nodes. Specifically +acpi_device_fix_up_power() causes the wifi module to get turned off. +Identifying GPDwin is problematic, but since SDIO is only used for wifi, +the presence of the PCI wifi card in the expected slot with an ACPI +companion node, is used to indicate that acpi_device_fix_up_power() should +be avoided. + +Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> +Acked-by: Hans de Goede <hdegoede@redhat.com> +Tested-by: Hans de Goede <hdegoede@redhat.com> +Cc: stable@vger.kernel.org +--- + drivers/mmc/host/sdhci-acpi.c | 70 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 64 insertions(+), 6 deletions(-) + +diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c +index c6a9a1bfaa22..b3fb155f50e4 100644 +--- a/drivers/mmc/host/sdhci-acpi.c ++++ b/drivers/mmc/host/sdhci-acpi.c +@@ -45,6 +45,7 @@ + #include <asm/cpu_device_id.h> + #include <asm/intel-family.h> + #include <asm/iosf_mbi.h> ++#include <linux/pci.h> + #endif + + #include "sdhci.h" +@@ -134,6 +135,16 @@ static bool sdhci_acpi_byt(void) + return x86_match_cpu(byt); + } + ++static bool sdhci_acpi_cht(void) ++{ ++ static const struct x86_cpu_id cht[] = { ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, ++ {} ++ }; ++ ++ return x86_match_cpu(cht); ++} ++ + #define BYT_IOSF_SCCEP 0x63 + #define BYT_IOSF_OCP_NETCTRL0 0x1078 + #define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) +@@ -178,6 +189,45 @@ static bool sdhci_acpi_byt_defer(struct device *dev) + return false; + } + ++static bool sdhci_acpi_cht_pci_wifi(unsigned int vendor, unsigned int device, ++ unsigned int slot, unsigned int parent_slot) ++{ ++ struct pci_dev *dev, *parent, *from = NULL; ++ ++ while (1) { ++ dev = pci_get_device(vendor, device, from); ++ pci_dev_put(from); ++ if (!dev) ++ break; ++ parent = pci_upstream_bridge(dev); ++ if (ACPI_COMPANION(&dev->dev) && PCI_SLOT(dev->devfn) == slot && ++ parent && PCI_SLOT(parent->devfn) == parent_slot && ++ !pci_upstream_bridge(parent)) { ++ pci_dev_put(dev); ++ return true; ++ } ++ from = dev; ++ } ++ ++ return false; ++} ++ ++/* ++ * GPDwin uses PCI wifi which conflicts with SDIO's use of ++ * acpi_device_fix_up_power() on child device nodes. Identifying GPDwin is ++ * problematic, but since SDIO is only used for wifi, the presence of the PCI ++ * wifi card in the expected slot with an ACPI companion node, is used to ++ * indicate that acpi_device_fix_up_power() should be avoided. ++ */ ++static inline bool sdhci_acpi_no_fixup_child_power(const char *hid, ++ const char *uid) ++{ ++ return sdhci_acpi_cht() && ++ !strcmp(hid, "80860F14") && ++ !strcmp(uid, "2") && ++ sdhci_acpi_cht_pci_wifi(0x14e4, 0x43ec, 0, 28); ++} ++ + #else + + static inline void sdhci_acpi_byt_setting(struct device *dev) +@@ -189,6 +239,12 @@ static inline bool sdhci_acpi_byt_defer(struct device *dev) + return false; + } + ++static inline bool sdhci_acpi_no_fixup_child_power(const char *hid, ++ const char *uid) ++{ ++ return false; ++} ++ + #endif + + static int bxt_get_cd(struct mmc_host *mmc) +@@ -390,11 +446,16 @@ static int sdhci_acpi_probe(struct platform_device *pdev) + if (acpi_bus_get_device(handle, &device)) + return -ENODEV; + ++ hid = acpi_device_hid(device); ++ uid = device->pnp.unique_id; ++ + /* Power on the SDHCI controller and its children */ + acpi_device_fix_up_power(device); +- list_for_each_entry(child, &device->children, node) +- if (child->status.present && child->status.enabled) +- acpi_device_fix_up_power(child); ++ if (!sdhci_acpi_no_fixup_child_power(hid, uid)) { ++ list_for_each_entry(child, &device->children, node) ++ if (child->status.present && child->status.enabled) ++ acpi_device_fix_up_power(child); ++ } + + if (acpi_bus_get_status(device) || !device->status.present) + return -ENODEV; +@@ -402,9 +463,6 @@ static int sdhci_acpi_probe(struct platform_device *pdev) + if (sdhci_acpi_byt_defer(dev)) + return -EPROBE_DEFER; + +- hid = acpi_device_hid(device); +- uid = device->pnp.unique_id; +- + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) + return -ENOMEM; +-- +2.13.0 + |