From patchwork Mon Jan 17 15:19:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1580871 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JcwcS1twpz9t56 for ; Tue, 18 Jan 2022 02:22:00 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1n9TpP-0008Q1-Q4; Mon, 17 Jan 2022 15:21:51 +0000 Received: from mail-pl1-f179.google.com ([209.85.214.179]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1n9To5-00078i-6c for kernel-team@lists.ubuntu.com; Mon, 17 Jan 2022 15:20:29 +0000 Received: by mail-pl1-f179.google.com with SMTP id b3so12497339plc.7 for ; Mon, 17 Jan 2022 07:20:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6pu/dIJ1DEoNNoQvLOxZ7jfE0py4M/dSddPuKPR0alA=; b=WJx2gpWlpQEsj5qLKXzkapwxclX+R9KPyRI4+l9mFUAAWMQ1myO5QEEbqqUAPR763W DBUIqsVQ3IqZ2IIBIwQrx7Xz9ozXXT/8CoOaoGZOkMgx4TcMdFVvwtzVbgkN3GrCHWAQ mYjFVxGYijX5/YXeD//uetcdsyiyGaFSFeSINdSyRIqrPXG6wXniIO7+vpIStoTkmccc WW+fdcqR2rzbS02movdeAP33iqjUf/1ZVDWf+9kGPB4ORJLUNemgZjid7FbN4P7dRClr barOWCMaB3zmrH3W7hZYSmz4pHPEHc1DTtaQm+mntwlHd0MS91dr/ggEsy234Q1X5XoD MjWQ== X-Gm-Message-State: AOAM531Adsk1W5CHJ2EnYEWMjeRkqfM825DXYpDkBKgdBXx/i/YzrbqO D8QyXdQvOvi5gVc+nlvHH9Z5JntLLRmE2A== X-Google-Smtp-Source: ABdhPJx8DTbYllDAKB1IZGWBqc24zUc+KFZqeh1yZHYJ9RfLTg2EZLrSXuSTaDfRdmyKB1jl8/Mclw== X-Received: by 2002:a17:903:22c3:b0:14a:8cf0:63b2 with SMTP id y3-20020a17090322c300b0014a8cf063b2mr18112364plg.148.1642432827185; Mon, 17 Jan 2022 07:20:27 -0800 (PST) Received: from localhost (218-173-149-51.dynamic-ip.hinet.net. [218.173.149.51]) by smtp.gmail.com with ESMTPSA id a23sm13004948pjo.57.2022.01.17.07.20.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 07:20:26 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 26/30][SRU][Jammy] UBUNTU: SAUCE: ljca: add multi ACPI HID support Date: Mon, 17 Jan 2022 23:19:24 +0800 Message-Id: <20220117151928.954829-27-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220117151928.954829-1-vicamo.yang@canonical.com> References: <20220117151928.954829-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.179; envelope-from=vicamo@gmail.com; helo=mail-pl1-f179.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ye Xiang BugLink: https://bugs.launchpad.net/bugs/1955383 Precheck GPIO/I2C/SPI ACPI Device HID before enumeration. Signed-off-by: Ye Xiang (cherry picked from commit 11f55ee365786229f6a77885a817ead89e5e5a56 github.com/intel/ivsc-driver) Signed-off-by: You-Sheng Yang --- drivers/i2c/busses/i2c-ljca.c | 43 +++++++++++++++++- drivers/mfd/ljca.c | 82 +++++++++++++++++++++++++++++------ 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-ljca.c b/drivers/i2c/busses/i2c-ljca.c index de66a41f61ae..bec6d8a02ae8 100644 --- a/drivers/i2c/busses/i2c-ljca.c +++ b/drivers/i2c/busses/i2c-ljca.c @@ -5,6 +5,7 @@ * Copyright (c) 2021, Intel Corporation. */ +#include #include #include #include @@ -321,6 +322,44 @@ static const struct i2c_algorithm ljca_i2c_algo = { .functionality = ljca_i2c_func, }; +static void try_bind_acpi(struct platform_device *pdev, + struct ljca_i2c_dev *ljca_i2c) +{ + struct acpi_device *parent, *child; + struct acpi_device *cur = ACPI_COMPANION(&pdev->dev); + const char *hid1; + const char *uid1; + char uid2[2] = { 0 }; + + if (!cur) + return; + + hid1 = acpi_device_hid(cur); + uid1 = acpi_device_uid(cur); + snprintf(uid2, sizeof(uid2), "%d", ljca_i2c->ctr_info->id); + + dev_dbg(&pdev->dev, "hid %s uid %s new uid%s\n", hid1, uid1, uid2); + /* + * If the pdev is bound to the right acpi device, just forward it to the + * adapter. Otherwise, we find that of current adapter manually. + */ + if (!strcmp(uid1, uid2)) { + ACPI_COMPANION_SET(&ljca_i2c->adap.dev, cur); + return; + } + + parent = ACPI_COMPANION(pdev->dev.parent); + if (!parent) + return; + + list_for_each_entry(child, &parent->children, node) { + if (acpi_dev_hid_uid_match(child, hid1, uid2)) { + ACPI_COMPANION_SET(&ljca_i2c->adap.dev, child); + return; + } + } +} + static int ljca_i2c_probe(struct platform_device *pdev) { struct ljca_i2c_dev *ljca_i2c; @@ -338,7 +377,9 @@ static int ljca_i2c_probe(struct platform_device *pdev) ljca_i2c->adap.class = I2C_CLASS_HWMON; ljca_i2c->adap.algo = &ljca_i2c_algo; ljca_i2c->adap.dev.parent = &pdev->dev; - ACPI_COMPANION_SET(&ljca_i2c->adap.dev, ACPI_COMPANION(&pdev->dev)); + + try_bind_acpi(pdev, ljca_i2c); + ljca_i2c->adap.dev.of_node = pdev->dev.of_node; i2c_set_adapdata(&ljca_i2c->adap, ljca_i2c); snprintf(ljca_i2c->adap.name, sizeof(ljca_i2c->adap.name), "%s-%s-%d", diff --git a/drivers/mfd/ljca.c b/drivers/mfd/ljca.c index 64d4b48565e4..aace699de53a 100644 --- a/drivers/mfd/ljca.c +++ b/drivers/mfd/ljca.c @@ -5,6 +5,7 @@ * Copyright (c) 2021, Intel Corporation. */ +#include #include #include #include @@ -23,24 +24,23 @@ enum ljca_acpi_match_adr { LJCA_ACPI_MATCH_SPI1, }; -static struct mfd_cell_acpi_match ljca_acpi_match_gpio = { - .pnpid = "INTC1074", +static char *gpio_hids[] = { + "INTC1074", + "INTC1096", }; +static struct mfd_cell_acpi_match ljca_acpi_match_gpio; -static struct mfd_cell_acpi_match ljca_acpi_match_i2cs[] = { - { - .pnpid = "INTC1075", - }, - { - .pnpid = "INTC1076", - }, +static char *i2c_hids[] = { + "INTC1075", + "INTC1097", }; +static struct mfd_cell_acpi_match ljca_acpi_match_i2cs[2]; -static struct mfd_cell_acpi_match ljca_acpi_match_spis[] = { - { - .pnpid = "INTC1091", - }, +static char *spi_hids[] = { + "INTC1091", + "INTC1098", }; +static struct mfd_cell_acpi_match ljca_acpi_match_spis[1]; struct ljca_msg { u8 type; @@ -206,6 +206,50 @@ struct ljca_dev { int cell_count; }; +static int try_match_acpi_hid(struct acpi_device *child, + struct mfd_cell_acpi_match *match, char **hids, + int hids_num) +{ + struct acpi_device_id ids[2] = {}; + int i; + + for (i = 0; i < hids_num; i++) { + strlcpy(ids[0].id, hids[i], sizeof(ids[0].id)); + if (!acpi_match_device_ids(child, ids)) { + match->pnpid = hids[i]; + break; + } + } + + return 0; +} + +static int precheck_acpi_hid(struct usb_interface *intf) +{ + struct acpi_device *parent, *child; + + parent = ACPI_COMPANION(&intf->dev); + if (!parent) + return -ENODEV; + + list_for_each_entry (child, &parent->children, node) { + try_match_acpi_hid(child, + &ljca_acpi_match_gpio, + gpio_hids, ARRAY_SIZE(gpio_hids)); + try_match_acpi_hid(child, + &ljca_acpi_match_i2cs[0], + i2c_hids, ARRAY_SIZE(i2c_hids)); + try_match_acpi_hid(child, + &ljca_acpi_match_i2cs[1], + i2c_hids, ARRAY_SIZE(i2c_hids)); + try_match_acpi_hid(child, + &ljca_acpi_match_spis[0], + spi_hids, ARRAY_SIZE(spi_hids)); + } + + return 0; +} + static bool ljca_validate(void *data, u32 data_len) { struct ljca_msg *header = (struct ljca_msg *)data; @@ -568,6 +612,13 @@ static inline int ljca_mng_reset(struct ljca_stub *stub) static int ljca_add_mfd_cell(struct ljca_dev *ljca, struct mfd_cell *cell) { struct mfd_cell *new_cells; + + /* Enumerate the device even if it does not appear in DSDT */ + if (!cell->acpi_match->pnpid) + dev_warn(&ljca->intf->dev, + "The HID of cell %s does not exist in DSDT\n", + cell->name); + new_cells = krealloc_array(ljca->cells, (ljca->cell_count + 1), sizeof(struct mfd_cell), GFP_KERNEL); if (!new_cells) @@ -1000,6 +1051,11 @@ static int ljca_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *bulk_in, *bulk_out; int ret; + ret = precheck_acpi_hid(intf); + if(ret) + return ret; + + /* allocate memory for our device state and initialize it */ ljca = kzalloc(sizeof(*ljca), GFP_KERNEL); if (!ljca)