From patchwork Fri Oct 27 16:11:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriele Paoloni X-Patchwork-Id: 117368 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp948279qgn; Fri, 27 Oct 2017 09:15:09 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Qik5ebcSZnSSYx8KwruouPoHFPcKa9KKUrFQmiVa80bmXemubHLWzULF7eecJO9rvdLHO8 X-Received: by 10.84.216.9 with SMTP id m9mr784453pli.16.1509120909254; Fri, 27 Oct 2017 09:15:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509120909; cv=none; d=google.com; s=arc-20160816; b=KoRV3BsNg7D1MWztX0JspxiaSFABL0MG5724SRkdiI6txqtdgIEn9a73QmUOAi8vL7 /+CrWKMe+mCn2934wvzG0s47Y8CPddqvZAS7jicQFybmLrqPxHkZSvMA5OHfKo/wuiMg WaNA5HbebKeT7kgHyuKiW6yCcN9G2nT2wrgg/UJDIR0InRpfsF/ZhazWgnVjPVajgUmf ykkK1deOKaweKIAbcUP4kzFGGR5W/2Q92mMYe6RBmcVCB2ocUqiLba3pIDnjCDMHfdba rDNksQkcna7zFQkd2C8eRi5//OQbwoSAmnJDGcF3TbX/kxNiaIRHDaHV9beUjSBLr/JB V2Zw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=96cGiCtgKS6J7OpcP4cH0Wu+WcB83PCWgHBRacwpgwM=; b=K2DWacIbUkdooAICGIR5ehzJgM0a5pAzQXev/f4fT7aliCeamUfp8bT+KZmQ8D/zX2 2WSy/Y/MwkAUCTUjGHAZT54cgSq3WlRJwvKWmeYeOagVisotqN5oXk/nrtpc205de34q Q6tq/Ab7PvRQDtOSeJKKlLdLkmOSvQgNHJyL2qTosr0WUF3mCKLLXjRchgq8VR1sXyLb sAU/vkXeiyddsxSge3qiwIQLPaZtqjvxVjbvsqiACpmRBcloj6kUcfBIFoN1GeG+cm76 DeLrfxSou5eOHNXWU8D+ionxwAUdZ9Aic1OBkP4Gyf/VRofXAgztLq2SdHTKjnFR1bnQ U5Yw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f4si5099506pgr.306.2017.10.27.09.15.08; Fri, 27 Oct 2017 09:15:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752726AbdJ0QPH (ORCPT + 27 others); Fri, 27 Oct 2017 12:15:07 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:9450 "EHLO szxga04-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752539AbdJ0QOt (ORCPT ); Fri, 27 Oct 2017 12:14:49 -0400 Received: from 172.30.72.58 (EHLO DGGEMS414-HUB.china.huawei.com) ([172.30.72.58]) by dggrg04-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DJX16571; Sat, 28 Oct 2017 00:14:40 +0800 (CST) Received: from G00308965-DELL1.china.huawei.com (10.202.226.113) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.361.1; Sat, 28 Oct 2017 00:13:04 +0800 From: Gabriele Paoloni To: , , , , , , , , CC: , , , , , , , , , , , , "zhichang.yuan" Subject: [PATCH v10 8/9] LPC: Add the ACPI LPC support Date: Fri, 27 Oct 2017 17:11:26 +0100 Message-ID: <1509120687-7352-9-git-send-email-gabriele.paoloni@huawei.com> X-Mailer: git-send-email 2.7.1.windows.1 In-Reply-To: <1509120687-7352-1-git-send-email-gabriele.paoloni@huawei.com> References: <1509120687-7352-1-git-send-email-gabriele.paoloni@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.113] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020204.59F35B70.016F, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 64e5a2f428088c0b3bdf29ea63aee021 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "zhichang.yuan" Based on the provious patches, this patch supports the ACPI LPC host on Hip06/Hip07. Signed-off-by: zhichang.yuan Signed-off-by: John Garry Signed-off-by: Gabriele Paoloni Tested-by: dann frazier --- drivers/acpi/arm64/acpi_indirectio.c | 3 + drivers/acpi/arm64/acpi_indirectio.h | 4 + drivers/bus/hisi_lpc.c | 164 +++++++++++++++++++++++++++++++---- 3 files changed, 154 insertions(+), 17 deletions(-) -- 2.7.4 diff --git a/drivers/acpi/arm64/acpi_indirectio.c b/drivers/acpi/arm64/acpi_indirectio.c index 013db6f..424f3bd 100644 --- a/drivers/acpi/arm64/acpi_indirectio.c +++ b/drivers/acpi/arm64/acpi_indirectio.c @@ -123,6 +123,9 @@ int acpi_set_logicio_resource(struct device *child, /* All the host devices which apply indirect-IO can be listed here. */ static const struct acpi_device_id acpi_indirect_host_id[] = { +#ifdef CONFIG_HISILICON_LPC + {"HISI0191", INDIRECT_IO_INFO(lpc_host_desc)}, +#endif {""}, }; diff --git a/drivers/acpi/arm64/acpi_indirectio.h b/drivers/acpi/arm64/acpi_indirectio.h index 8102ea0..1b18590 100644 --- a/drivers/acpi/arm64/acpi_indirectio.h +++ b/drivers/acpi/arm64/acpi_indirectio.h @@ -18,6 +18,10 @@ struct indirectio_device_desc { int (*pre_setup)(struct acpi_device *adev, void *pdata); }; +#ifdef CONFIG_HISILICON_LPC +extern const struct indirectio_device_desc lpc_host_desc; +#endif + int acpi_set_logicio_resource(struct device *child, struct device *hostdev, const struct resource **res, int *num_res); diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c index c885483..26043f7 100644 --- a/drivers/bus/hisi_lpc.c +++ b/drivers/bus/hisi_lpc.c @@ -438,7 +438,6 @@ static int hisilpc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct resource *res; struct hisilpc_dev *lpcdev; - struct logic_pio_hwaddr *range; int ret = 0; lpcdev = devm_kzalloc(dev, sizeof(struct hisilpc_dev), GFP_KERNEL); @@ -460,21 +459,32 @@ static int hisilpc_probe(struct platform_device *pdev) } /* register the LPC host PIO resources */ - range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); - if (!range) - return -ENOMEM; - range->fwnode = dev->fwnode; - range->flags = PIO_INDIRECT; - range->size = LPC_BUS_IO_SIZE; - range->hw_start = LPC_MIN_BUS_RANGE; - - ret = logic_pio_register_range(range); - if (ret) { - kfree(range); - dev_err(dev, "OF: register IO range FAIL!\n"); - return -ret; + if (has_acpi_companion(dev)) { + lpcdev->io_host = find_io_range_by_fwnode(dev->fwnode); + if (!lpcdev->io_host) { + dev_err(dev, "HiSilicon LPC range not registered!\n"); + return -EFAULT; + } + } else { + struct logic_pio_hwaddr *range; + + range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); + if (!range) + return -ENOMEM; + range->fwnode = dev->fwnode; + range->flags = PIO_INDIRECT; + range->size = LPC_BUS_IO_SIZE; + range->hw_start = LPC_MIN_BUS_RANGE; + + ret = logic_pio_register_range(range); + if (ret) { + kfree(range); + dev_err(dev, "OF: register IO range FAIL!\n"); + return -ret; + } + lpcdev->io_host = range; } - lpcdev->io_host = range; + lpcdev->io_host->devpara = lpcdev; lpcdev->io_host->ops = &hisi_lpc_ops; @@ -486,8 +496,11 @@ static int hisilpc_probe(struct platform_device *pdev) * to avoid some children which complete the scanning trigger the * MMIO accesses which will probably cause panic. */ - dev_info(dev, " calling of_platform_populate"); - ret = of_platform_populate(dev->of_node, NULL, NULL, dev); + if (!has_acpi_companion(dev)) { + dev_info(dev, " calling of_platform_populate"); + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); + } + if (ret) { /* * When LPC probing is not completely successful, set 'devpara' @@ -515,10 +528,127 @@ static const struct of_device_id hisilpc_of_match[] = { {}, }; +#ifdef CONFIG_ACPI +#include "../acpi/arm64/acpi_indirectio.h" +#include + +struct lpc_private_data { + resource_size_t io_size; + resource_size_t io_start; +}; + +static struct lpc_private_data lpc_data = { + .io_size = LPC_BUS_IO_SIZE, + .io_start = LPC_MIN_BUS_RANGE, +}; + +static struct mfd_cell_acpi_match hisi_lpc_ipmi_acpi_match = { + .pnpid = "IPI0001", +}; + +static const char *hisi_lpc_ipmi_name = "hisi_lpc_ipmi"; + +static int lpc_host_io_setup(struct acpi_device *adev, void *pdata) +{ + int ret; + struct platform_device *pdev; + struct mfd_cell *ipmi_devs; + struct logic_pio_hwaddr *range; + struct lpc_private_data *lpc_private; + struct acpi_device *child; + int ipmi_dev_num = 0; + + lpc_private = pdata; + range = kzalloc(sizeof(*range), GFP_KERNEL); + if (!range) + return -ENOMEM; + range->fwnode = &adev->fwnode; + range->flags = PIO_INDIRECT; + range->size = lpc_private->io_size; + range->hw_start = lpc_private->io_start; + + ret = logic_pio_register_range(range); + if (ret) + goto free_range; + + /* count the ipmi children first */ + list_for_each_entry(child, &adev->children, node) { + if (!strcmp(hisi_lpc_ipmi_acpi_match.pnpid, + acpi_device_hid(child))) + ipmi_dev_num++; + } + + /* allocate the mfd cells */ + ipmi_devs = kcalloc(ipmi_dev_num, sizeof(*ipmi_devs), GFP_KERNEL); + if (!ipmi_devs) { + dev_err(&adev->dev, "ipmi_devs kzalloc failed!\n"); + ret = -ENOMEM; + goto free_range; + } + + ipmi_dev_num = 0; + /* For hisilpc, only care about the sons of host. */ + list_for_each_entry(child, &adev->children, node) { + if (!strcmp(hisi_lpc_ipmi_acpi_match.pnpid, + acpi_device_hid(child))) { + ipmi_devs[ipmi_dev_num].name = hisi_lpc_ipmi_name; + ipmi_devs[ipmi_dev_num].acpi_match = + &hisi_lpc_ipmi_acpi_match; + ret = acpi_set_logicio_resource(&child->dev, &adev->dev, + &ipmi_devs[ipmi_dev_num].resources, + &ipmi_devs[ipmi_dev_num].num_resources); + if (ret) { + dev_err(&child->dev, "set resource failed..\n"); + goto free_ipmi_devs; + } + ipmi_dev_num++; + } + } + + pdev = acpi_create_platform_device(adev, NULL); + if (IS_ERR_OR_NULL(pdev)) { + dev_err(&adev->dev, "Create platform device for host FAIL!\n"); + ret = -EFAULT; + goto free_ipmi_devs; + } + acpi_device_set_enumerated(adev); + + ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, + ipmi_devs, ipmi_dev_num, NULL, 0, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to add ipmi mfd cell\n"); + goto free_ipmi_devs; + } + + return ret; + +free_ipmi_devs: + while (ipmi_dev_num--) + kfree(ipmi_devs[ipmi_dev_num].resources); + kfree(ipmi_devs); +free_range: + kfree(range); + + return ret; +} + +static const struct acpi_device_id hisilpc_acpi_match[] = { + {"HISI0191", }, + {}, +}; + +const struct indirectio_device_desc lpc_host_desc = { + .pdata = &lpc_data, + .pre_setup = lpc_host_io_setup, +}; + +#endif + static struct platform_driver hisilpc_driver = { .driver = { .name = "hisi_lpc", .of_match_table = hisilpc_of_match, + .acpi_match_table = ACPI_PTR(hisilpc_acpi_match), }, .probe = hisilpc_probe, };