]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/acpi/acpi_lpss.c
ACPI / LPSS: Make hid_uid_match helper accept a NULL uid argument
[linux.git] / drivers / acpi / acpi_lpss.c
index 9706613eecf9e2320209225b41d4856fecbf3ae1..73ae43627d603eb9e5a71e505227f661a0d8bf5c 100644 (file)
@@ -99,6 +99,9 @@ struct lpss_private_data {
        u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
 };
 
+/* Devices which need to be in D3 before lpss_iosf_enter_d3_state() proceeds */
+static u32 pmc_atom_d3_mask = 0xfe000ffe;
+
 /* LPSS run time quirks */
 static unsigned int lpss_quirks;
 
@@ -175,6 +178,21 @@ static void byt_pwm_setup(struct lpss_private_data *pdata)
 
 static void byt_i2c_setup(struct lpss_private_data *pdata)
 {
+       const char *uid_str = acpi_device_uid(pdata->adev);
+       acpi_handle handle = pdata->adev->handle;
+       unsigned long long shared_host = 0;
+       acpi_status status;
+       long uid = 0;
+
+       /* Expected to always be true, but better safe then sorry */
+       if (uid_str)
+               uid = simple_strtol(uid_str, NULL, 10);
+
+       /* Detect I2C bus shared with PUNIT and ignore its d3 status */
+       status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
+       if (ACPI_SUCCESS(status) && shared_host && uid)
+               pmc_atom_d3_mask &= ~(BIT_LPSS2_F1_I2C1 << (uid - 1));
+
        lpss_deassert_reset(pdata);
 
        if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset))
@@ -327,9 +345,11 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
        { "INT33FC", },
 
        /* Braswell LPSS devices */
+       { "80862286", LPSS_ADDR(lpss_dma_desc) },
        { "80862288", LPSS_ADDR(bsw_pwm_dev_desc) },
        { "8086228A", LPSS_ADDR(bsw_uart_dev_desc) },
        { "8086228E", LPSS_ADDR(bsw_spi_dev_desc) },
+       { "808622C0", LPSS_ADDR(lpss_dma_desc) },
        { "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) },
 
        /* Broadwell LPSS devices */
@@ -453,24 +473,31 @@ static const struct lpss_device_links lpss_device_links[] = {
        {"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME},
 };
 
-static bool hid_uid_match(const char *hid1, const char *uid1,
+static bool hid_uid_match(struct acpi_device *adev,
                          const char *hid2, const char *uid2)
 {
-       return !strcmp(hid1, hid2) && uid1 && uid2 && !strcmp(uid1, uid2);
+       const char *hid1 = acpi_device_hid(adev);
+       const char *uid1 = acpi_device_uid(adev);
+
+       if (strcmp(hid1, hid2))
+               return false;
+
+       if (!uid2)
+               return true;
+
+       return uid1 && !strcmp(uid1, uid2);
 }
 
 static bool acpi_lpss_is_supplier(struct acpi_device *adev,
                                  const struct lpss_device_links *link)
 {
-       return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev),
-                            link->supplier_hid, link->supplier_uid);
+       return hid_uid_match(adev, link->supplier_hid, link->supplier_uid);
 }
 
 static bool acpi_lpss_is_consumer(struct acpi_device *adev,
                                  const struct lpss_device_links *link)
 {
-       return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev),
-                            link->consumer_hid, link->consumer_uid);
+       return hid_uid_match(adev, link->consumer_hid, link->consumer_uid);
 }
 
 struct hid_uid {
@@ -486,8 +513,7 @@ static int match_hid_uid(struct device *dev, void *data)
        if (!adev)
                return 0;
 
-       return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev),
-                            id->hid, id->uid);
+       return hid_uid_match(adev, id->hid, id->uid);
 }
 
 static struct device *acpi_lpss_find_device(const char *hid, const char *uid)
@@ -879,7 +905,7 @@ static void acpi_lpss_dismiss(struct device *dev)
 #define LPSS_GPIODEF0_DMA_LLP          BIT(13)
 
 static DEFINE_MUTEX(lpss_iosf_mutex);
-static bool lpss_iosf_d3_entered;
+static bool lpss_iosf_d3_entered = true;
 
 static void lpss_iosf_enter_d3_state(void)
 {
@@ -892,7 +918,7 @@ static void lpss_iosf_enter_d3_state(void)
         * Here we read the values related to LPSS power island, i.e. LPSS
         * devices, excluding both LPSS DMA controllers, along with SCC domain.
         */
-       u32 func_dis, d3_sts_0, pmc_status, pmc_mask = 0xfe000ffe;
+       u32 func_dis, d3_sts_0, pmc_status;
        int ret;
 
        ret = pmc_atom_read(PMC_FUNC_DIS, &func_dis);
@@ -910,7 +936,7 @@ static void lpss_iosf_enter_d3_state(void)
         * Shutdown both LPSS DMA controllers if and only if all other devices
         * are already in D3hot.
         */
-       pmc_status = (~(d3_sts_0 | func_dis)) & pmc_mask;
+       pmc_status = (~(d3_sts_0 | func_dis)) & pmc_atom_d3_mask;
        if (pmc_status)
                goto exit;