From patchwork Wed Oct 6 03:53:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515275 Delivered-To: patch@linaro.org Received: by 2002:ac0:890a:0:0:0:0:0 with SMTP id 10csp155038imy; Tue, 5 Oct 2021 20:54:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzu+QgVOI4U0zpwl6tsZBLExunNUQWarZmqQonoTPDpyBDwGUvWUvvNx5mtsaUvXfFagXl8 X-Received: by 2002:a17:906:3f83:: with SMTP id b3mr30412702ejj.233.1633492472913; Tue, 05 Oct 2021 20:54:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633492472; cv=none; d=google.com; s=arc-20160816; b=PAfF4P2aVaeKKhHHau2RK0w9z3H3hfcD+xC57YMLrdUPXn1y4+WF2teagzVD0ZMyUR Oiu4madbOKsxoo/pl66kDaE6ZtMcWMTr/KsZnBdGWneLm4NiyS0dS2FKZo8GMaU6Vl5B oaf1yv128B14S0NTBH4FyjWVlhFTYwDGYcWIvqIUtlKs4nTjeLUJY6kaX0X1F+vL2DU8 eVLA7EH5uj+9H1FTYagl9Ehgbz5nAyknLzxFvArzOzKjaTd0ozUPQfTCbzYvnk0Drr3/ d6oZ7tJgvXm9JX6ZGzBhtQfOVrWHEYsY11HpKfKbKYOnyaKpTSUGVO/a5zCx2+Z3Vllx Yzgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mcNit0g6jUmmUjsU7FAtIRduJRJ7wpPHtyysZeeAHFY=; b=kH5KkteUy1KLz5Eyq8NN9y9M6ERcbxgTgLvgqoWebTo3dTTy1JnFpA3oa5xZqr1A/e s+qOfq5buzYnRWuSIWjLnNDUhIhV7UTWoWqECd/cRwzzNKv88TgXZ4JPNTFNs8CxVlxZ 2wToRpgtUnPetJkFthCYHQ5wzkE5yo5LGn6H39R34Myw9NNxP5Dn8ZHETOMSfiJh+gdI hItl/xHL+dtwW5XB+IRdDPqWaEtuINYvDx5sx62ji+KW6B3VD+joACiI2L2UzWr4zJXg /dhFp4US6QTtmrnPex2gLTt+ax/z7e/2wdyxSPxhXZdT6yRlOgvBpalOoCp7mlqeXW8T Xmuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Xh2nneBb; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id eb13si4889864edb.395.2021.10.05.20.54.32; Tue, 05 Oct 2021 20:54:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Xh2nneBb; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237465AbhJFD4T (ORCPT + 17 others); Tue, 5 Oct 2021 23:56:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237365AbhJFD4K (ORCPT ); Tue, 5 Oct 2021 23:56:10 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66A77C061793 for ; Tue, 5 Oct 2021 20:54:18 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id t9so4632496lfd.1 for ; Tue, 05 Oct 2021 20:54:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mcNit0g6jUmmUjsU7FAtIRduJRJ7wpPHtyysZeeAHFY=; b=Xh2nneBb/87+tArNL4Ub5gViAzfXJDIt0nN7Bymb9OpZLb9P/imlrckWJlA/M+3cTt 7c8eGMzP7lXSIDLkTnIlfWXLR6Xt8rclJjKYOUk4e73SzYY5wYBvp2wpcbGuRMrQRVAv pNJ0hBoGw9uU0TfZASPIBvt36O//ykJfspidjcIBqyIqYOZBX/QzyrooyiirypL/kuXu 8tdfTQXThfx9NQsFJCPxqhgIjTpcA6bKlxLAp0JTBCeEwhnvOiswNRfaC3Rhbx2jvg2N enaYRfssXa/hK05/CkZxpLji7C7cni+x1/ooPHyZAFJhfzZw6eKLiuxEBSKAx79g7fSf cqyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mcNit0g6jUmmUjsU7FAtIRduJRJ7wpPHtyysZeeAHFY=; b=qcMGKke+XK8w6tBuMdW1bL97UbFh12y4arNiG5zdawKqgPeLUDVSp+yGzCjOa4H9nY 1H2XzSxx6NejhUBg61cjIMnkLmladrWTC0wOR/awmxYDwnuuFtczFUddKnlLmjj6rfBu uy/I/la2pu2SNlrlySjlgS6Y6euE/oVASGEbsokWRAmZOI6JZBC62pJtOG9ZdfOkQYuV A5P+bHRVDPa/Wzd5n1cIv5u39MgSok0ZskQHEUZU9f2FObjjuo0dHzA/IX/6RA19FY66 vvT+aU3yvpwL5yycafjV5JnddPOhKwsGEGweiw55UJEFGypLiasJsW/hZcZQgO/+kW9n I5+Q== X-Gm-Message-State: AOAM532zXd1jRtnpumZNAwi6TuSfmUADWNzefgtYjmFnmmxrG4Pa760S 6B/f0TCxKDenMCQjP9nyc+BgVQ== X-Received: by 2002:a05:651c:1615:: with SMTP id f21mr11860995ljq.318.1633492456613; Tue, 05 Oct 2021 20:54:16 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id s4sm2142967lfd.103.2021.10.05.20.54.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Oct 2021 20:54:16 -0700 (PDT) From: Dmitry Baryshkov To: Andy Gross , Bjorn Andersson , Ulf Hansson , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Kalle Valo , "David S. Miller" , Jakub Kicinski , Stanimir Varbanov Cc: linux-arm-msm@vger.kernel.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v1 06/15] pwrseq: add support for QCA BT+WiFi power sequencer Date: Wed, 6 Oct 2021 06:53:58 +0300 Message-Id: <20211006035407.1147909-7-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> References: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for power sequencer used in the Qualcomm BT+WiFi SoCs. They require several external volate regulators and some of them use separate BT and WiFi enable GPIO pins. This code is mostly extracted from the hci_qca.c bluetooth driver and ath10k WiFi driver. Instead of having each of them manage pins, different requirements, regulator types, move this knowledge to the common power sequencer driver. Currently original drivers are not stripped from the regulator code, this will be done later (to keep compatibility with the old device trees). Signed-off-by: Dmitry Baryshkov --- drivers/power/pwrseq/Kconfig | 14 ++ drivers/power/pwrseq/Makefile | 1 + drivers/power/pwrseq/pwrseq_qca.c | 373 ++++++++++++++++++++++++++++++ 3 files changed, 388 insertions(+) create mode 100644 drivers/power/pwrseq/pwrseq_qca.c -- 2.33.0 diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig index 1985f13d9193..7983e37c7855 100644 --- a/drivers/power/pwrseq/Kconfig +++ b/drivers/power/pwrseq/Kconfig @@ -22,6 +22,20 @@ config PWRSEQ_EMMC This driver can also be built as a module. If so, the module will be called pwrseq_emmc. +config PWRSEQ_QCA + tristate "Power Sequencer for Qualcomm WiFi + BT SoCs" + depends on OF + help + If you say yes to this option, support will be included for Qualcomm + WCN399x,QCA639x,QCA67xx families of hybrid WiFi and Bluetooth SoCs. + Note, this driver supports only power control for these SoC, you + still have to enable individual Bluetooth and WiFi drivers. This + driver is only necessary on ARM platforms with these chips. PCIe + cards handle power sequencing on their own. + + Say M here if you want to include support for Qualcomm WiFi+BT SoCs + as a module. This will build a module called "pwrseq_qca". + config PWRSEQ_SD8787 tristate "HW reset support for SD8787 BT + Wifi module" depends on OF diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile index 6f359d228843..556bf5582d47 100644 --- a/drivers/power/pwrseq/Makefile +++ b/drivers/power/pwrseq/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_PWRSEQ) += core.o obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o +obj-$(CONFIG_PWRSEQ_QCA) += pwrseq_qca.o obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o diff --git a/drivers/power/pwrseq/pwrseq_qca.c b/drivers/power/pwrseq/pwrseq_qca.c new file mode 100644 index 000000000000..c15508cc80d2 --- /dev/null +++ b/drivers/power/pwrseq/pwrseq_qca.c @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, Linaro Ltd. + * + * Author: Dmitry Baryshkov + * + * Power Sequencer for Qualcomm WiFi + BT SoCs + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* susclk rate */ +#define SUSCLK_RATE_32KHZ 32768 + +/* + * Voltage regulator information required for configuring the + * QCA WiFi+Bluetooth chipset + */ +struct qca_vreg { + const char *name; + unsigned int load_uA; +}; + +struct qca_device_data { + bool has_enable_gpios; + + /* + * VDDIO has to be enabled before the rest of regulators, so we treat + * it separately + */ + struct qca_vreg vddio; + + size_t num_vregs; + struct qca_vreg vregs[]; +}; + +struct pwrseq_qca_common { + struct gpio_desc *sw_ctrl; + struct clk *susclk; + + /* + * Again vddio is separate so that it can be enabled before enabling + * other regulators. + */ + struct regulator *vddio; + int num_vregs; + struct regulator_bulk_data vregs[]; +}; + +struct pwrseq_qca_one { + struct pwrseq_qca_common *common; + struct gpio_desc *enable; +}; + +#define PWRSEQ_QCA_WIFI 0 +#define PWRSEQ_QCA_BT 1 + +#define PWRSEQ_QCA_MAX 2 + +struct pwrseq_qca { + struct pwrseq_qca_one pwrseq_qcas[PWRSEQ_QCA_MAX]; + struct pwrseq_qca_common common; +}; + +static int pwrseq_qca_pre_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_qca_one *qca_one = pwrseq_get_drvdata(pwrseq); + + if (qca_one->enable) { + gpiod_set_value_cansleep(qca_one->enable, 0); + msleep(50); + } + + return 0; +} + +static int pwrseq_qca_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_qca_one *qca_one = pwrseq_get_drvdata(pwrseq); + int ret; + + if (qca_one->common->vddio) { + ret = regulator_enable(qca_one->common->vddio); + if (ret) + return ret; + } + + ret = regulator_bulk_enable(qca_one->common->num_vregs, qca_one->common->vregs); + if (ret) + goto err_bulk; + + ret = clk_prepare_enable(qca_one->common->susclk); + if (ret) + goto err_clk; + + if (qca_one->enable) { + gpiod_set_value_cansleep(qca_one->enable, 1); + msleep(150); + } + + if (qca_one->common->sw_ctrl) { + bool sw_ctrl_state = gpiod_get_value_cansleep(qca_one->common->sw_ctrl); + dev_dbg(&pwrseq->dev, "SW_CTRL is %d", sw_ctrl_state); + } + + return 0; + +err_clk: + regulator_bulk_disable(qca_one->common->num_vregs, qca_one->common->vregs); +err_bulk: + regulator_disable(qca_one->common->vddio); + + return ret; +} + +static void pwrseq_qca_power_off(struct pwrseq *pwrseq) +{ + struct pwrseq_qca_one *qca_one = pwrseq_get_drvdata(pwrseq); + + if (qca_one->enable) { + gpiod_set_value_cansleep(qca_one->enable, 0); + msleep(50); + } + + clk_disable_unprepare(qca_one->common->susclk); + + regulator_bulk_disable(qca_one->common->num_vregs, qca_one->common->vregs); + regulator_disable(qca_one->common->vddio); + + if (qca_one->common->sw_ctrl) { + bool sw_ctrl_state = gpiod_get_value_cansleep(qca_one->common->sw_ctrl); + dev_dbg(&pwrseq->dev, "SW_CTRL is %d", sw_ctrl_state); + } +} + +static const struct pwrseq_ops pwrseq_qca_ops = { + .pre_power_on = pwrseq_qca_pre_power_on, + .power_on = pwrseq_qca_power_on, + .power_off = pwrseq_qca_power_off, +}; + +static int pwrseq_qca_common_init(struct device *dev, struct pwrseq_qca_common *qca_common, + const struct qca_device_data *data) +{ + int ret, i; + + if (data->vddio.name) { + qca_common->vddio = devm_regulator_get(dev, data->vddio.name); + if (IS_ERR(qca_common->vddio)) + return PTR_ERR(qca_common->vddio); + + ret = regulator_set_load(qca_common->vddio, data->vddio.load_uA); + if (ret) + return ret; + } + + qca_common->num_vregs = data->num_vregs; + + for (i = 0; i < qca_common->num_vregs; i++) + qca_common->vregs[i].supply = data->vregs[i].name; + + ret = devm_regulator_bulk_get(dev, qca_common->num_vregs, qca_common->vregs); + if (ret) + return ret; + + for (i = 0; i < qca_common->num_vregs; i++) { + if (!data->vregs[i].load_uA) + continue; + + ret = regulator_set_load(qca_common->vregs[i].consumer, data->vregs[i].load_uA); + if (ret) + return ret; + } + + qca_common->susclk = devm_clk_get_optional(dev, NULL); + if (IS_ERR(qca_common->susclk)) { + dev_err(dev, "failed to acquire clk\n"); + return PTR_ERR(qca_common->susclk); + } + + qca_common->sw_ctrl = devm_gpiod_get_optional(dev, "swctrl", GPIOD_IN); + if (IS_ERR(qca_common->sw_ctrl)) { + return dev_err_probe(dev, PTR_ERR(qca_common->sw_ctrl), + "failed to acquire SW_CTRL gpio\n"); + } else if (!qca_common->sw_ctrl) + dev_info(dev, "No SW_CTRL gpio\n"); + + return 0; +} + +static void pwrseq_qca_unprepare_susclk(void *data) +{ + struct pwrseq_qca_common *qca_common = data; + + clk_disable_unprepare(qca_common->susclk); +} + +static const struct qca_device_data qca_soc_data_default = { + .num_vregs = 0, + .has_enable_gpios = true, +}; + +static int pwrseq_qca_probe(struct platform_device *pdev) +{ + struct pwrseq_qca *pwrseq_qca; + struct pwrseq *pwrseq; + struct pwrseq_provider *provider; + struct device *dev = &pdev->dev; + struct pwrseq_onecell_data *onecell; + const struct qca_device_data *data; + int ret, i; + + data = device_get_match_data(dev); + if (!data) + data = &qca_soc_data_default; + + pwrseq_qca = devm_kzalloc(dev, struct_size(pwrseq_qca, common.vregs, data->num_vregs), GFP_KERNEL); + if (!pwrseq_qca) + return -ENOMEM; + + onecell = devm_kzalloc(dev, struct_size(onecell, pwrseqs, PWRSEQ_QCA_MAX), GFP_KERNEL); + if (!onecell) + return -ENOMEM; + + ret = pwrseq_qca_common_init(dev, &pwrseq_qca->common, data); + if (ret) + return ret; + + if (data->has_enable_gpios) { + struct gpio_desc *gpiod; + + gpiod = devm_gpiod_get_optional(dev, "wifi-enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) + return dev_err_probe(dev, PTR_ERR(gpiod), "failed to acquire WIFI enable GPIO\n"); + else if (!gpiod) + dev_warn(dev, "No WiFi enable GPIO declared\n"); + + pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_WIFI].enable = gpiod; + + gpiod = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) + return dev_err_probe(dev, PTR_ERR(gpiod), "failed to acquire BT enable GPIO\n"); + else if (!gpiod) + dev_warn(dev, "No BT enable GPIO declared\n"); + + pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_BT].enable = gpiod; + } + + /* If we have no control over device's enablement, make sure that sleep clock is always running */ + if (!pwrseq_qca->common.vddio || + !pwrseq_qca->common.num_vregs || + !(pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_BT].enable && + pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_WIFI].enable)) { + ret = clk_set_rate(pwrseq_qca->common.susclk, SUSCLK_RATE_32KHZ); + if (ret) + return ret; + + ret = clk_prepare_enable(pwrseq_qca->common.susclk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, pwrseq_qca_unprepare_susclk, &pwrseq_qca->common); + if (ret) + return ret; + } + + for (i = 0; i < PWRSEQ_QCA_MAX; i++) { + pwrseq_qca->pwrseq_qcas[i].common = &pwrseq_qca->common; + + pwrseq = devm_pwrseq_create(dev, &pwrseq_qca_ops); + if (IS_ERR(pwrseq)) + return PTR_ERR(pwrseq); + + pwrseq_set_drvdata(pwrseq, &pwrseq_qca->pwrseq_qcas[i]); + + onecell->pwrseqs[i] = pwrseq; + } + + onecell->num = PWRSEQ_QCA_MAX; + + provider = devm_of_pwrseq_provider_register(dev, of_pwrseq_xlate_onecell, onecell); + + return PTR_ERR_OR_ZERO(provider); +} + +static const struct qca_device_data qca_soc_data_qca6390 = { + .vddio = { "vddio", 20000 }, + .vregs = { + /* 2.0 V */ + { "vddpcie2", 15000 }, + { "vddrfa3", 400000 }, + + /* 0.95 V */ + { "vddaon", 100000 }, + { "vddpmu", 1250000 }, + { "vddrfa1", 200000 }, + + /* 1.35 V */ + { "vddrfa2", 400000 }, + { "vddpcie1", 35000 }, + }, + .num_vregs = 7, + .has_enable_gpios = true, +}; + +/* Shared between wcn3990 and wcn3991 */ +static const struct qca_device_data qca_soc_data_wcn3990 = { + .vddio = { "vddio", 15000 }, + .vregs = { + { "vddxo", 80000 }, + { "vddrf", 300000 }, + { "vddch0", 450000 }, + { "vddch1", 450000 }, + }, + .num_vregs = 4, +}; + +static const struct qca_device_data qca_soc_data_wcn3998 = { + .vddio = { "vddio", 10000 }, + .vregs = { + { "vddxo", 80000 }, + { "vddrf", 300000 }, + { "vddch0", 450000 }, + { "vddch1", 450000 }, + }, + .num_vregs = 4, +}; + +static const struct qca_device_data qca_soc_data_wcn6750 = { + .vddio = { "vddio", 5000 }, + .vregs = { + { "vddaon", 26000 }, + { "vddbtcxmx", 126000 }, + { "vddrfacmn", 12500 }, + { "vddrfa0p8", 102000 }, + { "vddrfa1p7", 302000 }, + { "vddrfa1p2", 257000 }, + { "vddrfa2p2", 1700000 }, + { "vddasd", 200 }, + }, + .num_vregs = 8, + .has_enable_gpios = true, +}; + +static const struct of_device_id pwrseq_qca_of_match[] = { + { .compatible = "qcom,qca6174-pwrseq", }, + { .compatible = "qcom,qca6390-pwrseq", .data = &qca_soc_data_qca6390 }, + { .compatible = "qcom,qca9377-pwrseq" }, + { .compatible = "qcom,wcn3990-pwrseq", .data = &qca_soc_data_wcn3990 }, + { .compatible = "qcom,wcn3991-pwrseq", .data = &qca_soc_data_wcn3990 }, + { .compatible = "qcom,wcn3998-pwrseq", .data = &qca_soc_data_wcn3998 }, + { .compatible = "qcom,wcn6750-pwrseq", .data = &qca_soc_data_wcn6750 }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, pwrseq_qca_of_match); + +static struct platform_driver pwrseq_qca_driver = { + .probe = pwrseq_qca_probe, + .driver = { + .name = "pwrseq_qca", + .of_match_table = pwrseq_qca_of_match, + }, +}; + +module_platform_driver(pwrseq_qca_driver); +MODULE_LICENSE("GPL v2"); From patchwork Wed Oct 6 03:54:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515279 Delivered-To: patch@linaro.org Received: by 2002:ac0:890a:0:0:0:0:0 with SMTP id 10csp155152imy; Tue, 5 Oct 2021 20:54:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFm5geN9a/aQQjurglR5tiImHB9mzp7uaj+a8C3k9mLYbcx0pv0kirvOJ2cYfia6zIYwpq X-Received: by 2002:a17:906:2da2:: with SMTP id g2mr29824903eji.38.1633492484441; Tue, 05 Oct 2021 20:54:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633492484; cv=none; d=google.com; s=arc-20160816; b=bF/dET0//4XyqEgaM52hSNRYvCyjnREx6s12mhtOCJfdCo/b2BM8HohrLwgroqtL/c bdI2sAY3a9eR5ETodMS+cPLshjyGk+QUUYx1AaOJQLpIcM3YHbGxztC4c3FjK5k6wiA/ LXPOqT4IleXZbuyzEe6bMOAT4rTjaS5OuvdiqViVlSzKjkFUG5FZB3Alcgfu0LXSI1cY zDpfVRzV7qBGWL5AghPDDAzjvcp2TZMK57dwTTi6wKfDMhXT/+xnGtWbDllH3AwFzkcT 9JxMTtgfnQBtzL1TOZ7lIEOhuWjN3cppdKZfdt1qzh4sAw7DgKe8ClBdIQHihaIYfdUB Dz/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gdZGnwzEHVfU1lQviDSHFvhmNm98xNMbizrp42xP5ec=; b=zx9/1KTi474rv+GJqN++pOnrwTtMsFWkMl+uS7jq1QpJ5C6VIOoAk5C4oAUzJl+wDi vALiCwr+TLWxftHuKy/XzkMEzQqOCQx90AKBj1SIRVcMepkQqMG3TCUDvN1G5AbPRcOa fvbVjTLGTCWYAiu8m3axkuzQ1mk3eZG2HhMCLbldBx+gE9unnNbbzLRXrYmtlF//TlNb AiP2YoXmlJoUcpD4CZYF5AEayoDMbJW/bRvtME1VUB+3wZf9uK8FqEo3vLt+ZRBnENZz jxARpnl1jOcyyIh2pS/KH/Ac8dn9xSB0QbyDqf5KMXgzYha+qlX45I1G9bNUy0AXC7Iv 96UA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZIA3rODl; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w11si28825141edc.191.2021.10.05.20.54.44; Tue, 05 Oct 2021 20:54:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZIA3rODl; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237435AbhJFD4d (ORCPT + 17 others); Tue, 5 Oct 2021 23:56:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237419AbhJFD4N (ORCPT ); Tue, 5 Oct 2021 23:56:13 -0400 Received: from mail-lf1-x133.google.com (mail-lf1-x133.google.com [IPv6:2a00:1450:4864:20::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CCECC061766 for ; Tue, 5 Oct 2021 20:54:21 -0700 (PDT) Received: by mail-lf1-x133.google.com with SMTP id r19so4459405lfe.10 for ; Tue, 05 Oct 2021 20:54:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gdZGnwzEHVfU1lQviDSHFvhmNm98xNMbizrp42xP5ec=; b=ZIA3rODl2Ki9rPwRisOcBTnXWSqii6n74k4f+ncNlaH1T5a6RLVb1Ss1eRKXh1Up17 vx1n0JKLCUIn38lw/DBB535C0HaXoslYGo2N8KvPyMaRNdVBmkiHim6wtwusIKmxob1X 6lK5aeZYKBTOkgvd9sld6YmfOhvBIRX/9fKZRJCYRd04ZDVZyl3VWZYLO2QdFBXpzuTG nWlk1Ypn7QiipOPhGTPOWTMQ2rg6vxpBLe9IO3kYHkjOow/3p92OwKgpc28HBAzn0cZj v9fXFMuq3kKIc7lLX6iaDfi9m+fulgjvi1TOPZAXSmkr/0UxSKB3ctedYtGMDb3X852e 5+SA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gdZGnwzEHVfU1lQviDSHFvhmNm98xNMbizrp42xP5ec=; b=yTYRSe5M5+ZHYIRWFFhINSbL/5rhUJ0PJTQQy0aP/LpGFzSumYpV8vuukTL7+Smk3g oplUDttsQrvVdsj60VpSc187tKg/IKhDOPHSC1XdrO6uuIi3fEuGoP1hDSf7vOu4Iiej 5+eC8LI2wOOUfM4mdM8YawIHxLMwNc/OErplVJ9LqeVihfdKbLT2iDfH6An5O9U3zRQD ZNr4VDKrBGKDh1PWploDzvBE4v/KbtVDc6WyscXGgAJ2sAq7x9U3VcA6/EC36nL9HUWl fb9hTr71FgRLtYu95jBFWV9uSYMTp1VAF94Yh1xjSnWOyl0hBO7O3rB08GQd5bnXBdzU Hc+g== X-Gm-Message-State: AOAM5339eqSMl4Qxt6t+GpX6F108DtGDhTstvNsL3y+ZZh3v1oSOgEFp eG2zmsYaCm9W7yk/3oLR+TMlyQ== X-Received: by 2002:a2e:9c4b:: with SMTP id t11mr26711712ljj.376.1633492459533; Tue, 05 Oct 2021 20:54:19 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id s4sm2142967lfd.103.2021.10.05.20.54.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Oct 2021 20:54:18 -0700 (PDT) From: Dmitry Baryshkov To: Andy Gross , Bjorn Andersson , Ulf Hansson , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Kalle Valo , "David S. Miller" , Jakub Kicinski , Stanimir Varbanov Cc: linux-arm-msm@vger.kernel.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v1 09/15] Bluetooth: hci_qca: switch to using pwrseq Date: Wed, 6 Oct 2021 06:54:01 +0300 Message-Id: <20211006035407.1147909-10-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> References: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 260 +++++------------------------------- 1 file changed, 37 insertions(+), 223 deletions(-) -- 2.33.0 diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 53deea2eb7b4..1e4416916533 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -16,19 +16,17 @@ */ #include -#include #include #include #include #include #include -#include #include #include #include #include #include -#include +#include #include #include #include @@ -54,9 +52,6 @@ (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS) #define FW_DOWNLOAD_TIMEOUT_MS 3000 -/* susclk rate */ -#define SUSCLK_RATE_32KHZ 32768 - /* Controller debug log header */ #define QCA_DEBUG_HANDLE 0x2EDC @@ -200,28 +195,17 @@ struct qca_vreg { struct qca_device_data { enum qca_btsoc_type soc_type; - struct qca_vreg *vregs; - size_t num_vregs; uint32_t capabilities; }; /* * Platform data for the QCA Bluetooth power driver. */ -struct qca_power { - struct device *dev; - struct regulator_bulk_data *vreg_bulk; - int num_vregs; - bool vregs_on; -}; - struct qca_serdev { struct hci_uart serdev_hu; - struct gpio_desc *bt_en; - struct gpio_desc *sw_ctrl; - struct clk *susclk; enum qca_btsoc_type btsoc_type; - struct qca_power *bt_power; + struct pwrseq *pwrseq; + bool vregs_on; u32 init_speed; u32 oper_speed; const char *firmware_name; @@ -1596,13 +1580,12 @@ static int qca_regulator_init(struct hci_uart *hu) enum qca_btsoc_type soc_type = qca_soc_type(hu); struct qca_serdev *qcadev; int ret; - bool sw_ctrl_state; /* Check for vregs status, may be hci down has turned * off the voltage regulator. */ qcadev = serdev_device_get_drvdata(hu->serdev); - if (!qcadev->bt_power->vregs_on) { + if (!qcadev->vregs_on) { serdev_device_close(hu->serdev); ret = qca_regulator_enable(qcadev); if (ret) @@ -1623,19 +1606,9 @@ static int qca_regulator_init(struct hci_uart *hu) return ret; } - /* For wcn6750 need to enable gpio bt_en */ - if (qcadev->bt_en) { - gpiod_set_value_cansleep(qcadev->bt_en, 0); - msleep(50); - gpiod_set_value_cansleep(qcadev->bt_en, 1); - msleep(50); - if (qcadev->sw_ctrl) { - sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); - bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); - } - } - - qca_set_speed(hu, QCA_INIT_SPEED); + if (qca_is_wcn399x(soc_type) || + qca_is_wcn6750(soc_type)) + qca_set_speed(hu, QCA_INIT_SPEED); if (qca_is_wcn399x(soc_type)) { ret = qca_send_power_pulse(hu, true); @@ -1655,7 +1628,9 @@ static int qca_regulator_init(struct hci_uart *hu) return ret; } - hci_uart_set_flow_control(hu, false); + if (qca_is_wcn399x(soc_type) || + qca_is_wcn6750(soc_type)) + hci_uart_set_flow_control(hu, false); return 0; } @@ -1663,8 +1638,6 @@ static int qca_regulator_init(struct hci_uart *hu) static int qca_power_on(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); - enum qca_btsoc_type soc_type = qca_soc_type(hu); - struct qca_serdev *qcadev; struct qca_data *qca = hu->priv; int ret = 0; @@ -1674,17 +1647,7 @@ static int qca_power_on(struct hci_dev *hdev) if (!hu->serdev) return 0; - if (qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type)) { - ret = qca_regulator_init(hu); - } else { - qcadev = serdev_device_get_drvdata(hu->serdev); - if (qcadev->bt_en) { - gpiod_set_value_cansleep(qcadev->bt_en, 1); - /* Controller needs time to bootup. */ - msleep(150); - } - } + ret = qca_regulator_init(hu); clear_bit(QCA_BT_OFF, &qca->flags); return ret; @@ -1820,57 +1783,23 @@ static const struct hci_uart_proto qca_proto = { static const struct qca_device_data qca_soc_data_wcn3990 = { .soc_type = QCA_WCN3990, - .vregs = (struct qca_vreg []) { - { "vddio", 15000 }, - { "vddxo", 80000 }, - { "vddrf", 300000 }, - { "vddch0", 450000 }, - }, - .num_vregs = 4, }; static const struct qca_device_data qca_soc_data_wcn3991 = { .soc_type = QCA_WCN3991, - .vregs = (struct qca_vreg []) { - { "vddio", 15000 }, - { "vddxo", 80000 }, - { "vddrf", 300000 }, - { "vddch0", 450000 }, - }, - .num_vregs = 4, .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, }; static const struct qca_device_data qca_soc_data_wcn3998 = { .soc_type = QCA_WCN3998, - .vregs = (struct qca_vreg []) { - { "vddio", 10000 }, - { "vddxo", 80000 }, - { "vddrf", 300000 }, - { "vddch0", 450000 }, - }, - .num_vregs = 4, }; static const struct qca_device_data qca_soc_data_qca6390 = { .soc_type = QCA_QCA6390, - .num_vregs = 0, }; static const struct qca_device_data qca_soc_data_wcn6750 = { .soc_type = QCA_WCN6750, - .vregs = (struct qca_vreg []) { - { "vddio", 5000 }, - { "vddaon", 26000 }, - { "vddbtcxmx", 126000 }, - { "vddrfacmn", 12500 }, - { "vddrfa0p8", 102000 }, - { "vddrfa1p7", 302000 }, - { "vddrfa1p2", 257000 }, - { "vddrfa2p2", 1700000 }, - { "vddasd", 200 }, - }, - .num_vregs = 9, .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, }; @@ -1880,7 +1809,6 @@ static void qca_power_shutdown(struct hci_uart *hu) struct qca_data *qca = hu->priv; unsigned long flags; enum qca_btsoc_type soc_type = qca_soc_type(hu); - bool sw_ctrl_state; /* From this point we go into power off state. But serial port is * still open, stop queueing the IBS data and flush all the buffered @@ -1902,19 +1830,10 @@ static void qca_power_shutdown(struct hci_uart *hu) if (qca_is_wcn399x(soc_type)) { host_set_baudrate(hu, 2400); qca_send_power_pulse(hu, false); - qca_regulator_disable(qcadev); - } else if (soc_type == QCA_WCN6750) { - gpiod_set_value_cansleep(qcadev->bt_en, 0); - msleep(100); - qca_regulator_disable(qcadev); - if (qcadev->sw_ctrl) { - sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); - bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); - } - } else if (qcadev->bt_en) { - gpiod_set_value_cansleep(qcadev->bt_en, 0); } + qca_regulator_disable(qcadev); + set_bit(QCA_BT_OFF, &qca->flags); } @@ -1940,75 +1859,34 @@ static int qca_power_off(struct hci_dev *hdev) static int qca_regulator_enable(struct qca_serdev *qcadev) { - struct qca_power *power = qcadev->bt_power; int ret; /* Already enabled */ - if (power->vregs_on) + if (qcadev->vregs_on) return 0; - BT_DBG("enabling %d regulators)", power->num_vregs); + BT_DBG("enabling regulators)"); - ret = regulator_bulk_enable(power->num_vregs, power->vreg_bulk); + ret = pwrseq_full_power_on(qcadev->pwrseq); if (ret) return ret; - power->vregs_on = true; - - ret = clk_prepare_enable(qcadev->susclk); - if (ret) - qca_regulator_disable(qcadev); + qcadev->vregs_on = true; return ret; } static void qca_regulator_disable(struct qca_serdev *qcadev) { - struct qca_power *power; - if (!qcadev) return; - power = qcadev->bt_power; - /* Already disabled? */ - if (!power->vregs_on) + if (!qcadev->vregs_on) return; - regulator_bulk_disable(power->num_vregs, power->vreg_bulk); - power->vregs_on = false; - - clk_disable_unprepare(qcadev->susclk); -} - -static int qca_init_regulators(struct qca_power *qca, - const struct qca_vreg *vregs, size_t num_vregs) -{ - struct regulator_bulk_data *bulk; - int ret; - int i; - - bulk = devm_kcalloc(qca->dev, num_vregs, sizeof(*bulk), GFP_KERNEL); - if (!bulk) - return -ENOMEM; - - for (i = 0; i < num_vregs; i++) - bulk[i].supply = vregs[i].name; - - ret = devm_regulator_bulk_get(qca->dev, num_vregs, bulk); - if (ret < 0) - return ret; - - for (i = 0; i < num_vregs; i++) { - ret = regulator_set_load(bulk[i].consumer, vregs[i].load_uA); - if (ret) - return ret; - } - - qca->vreg_bulk = bulk; - qca->num_vregs = num_vregs; - - return 0; + pwrseq_power_off(qcadev->pwrseq); + qcadev->vregs_on = false; } static int qca_serdev_probe(struct serdev_device *serdev) @@ -2017,7 +1895,6 @@ static int qca_serdev_probe(struct serdev_device *serdev) struct hci_dev *hdev; const struct qca_device_data *data; int err; - bool power_ctrl_enabled = true; qcadev = devm_kzalloc(&serdev->dev, sizeof(*qcadev), GFP_KERNEL); if (!qcadev) @@ -2033,89 +1910,29 @@ static int qca_serdev_probe(struct serdev_device *serdev) if (!qcadev->oper_speed) BT_DBG("UART will pick default operating speed"); - if (data && - (qca_is_wcn399x(data->soc_type) || - qca_is_wcn6750(data->soc_type))) { - qcadev->btsoc_type = data->soc_type; - qcadev->bt_power = devm_kzalloc(&serdev->dev, - sizeof(struct qca_power), - GFP_KERNEL); - if (!qcadev->bt_power) - return -ENOMEM; - - qcadev->bt_power->dev = &serdev->dev; - err = qca_init_regulators(qcadev->bt_power, data->vregs, - data->num_vregs); - if (err) { - BT_ERR("Failed to init regulators:%d", err); - return err; - } - - qcadev->bt_power->vregs_on = false; - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (!qcadev->bt_en && data->soc_type == QCA_WCN6750) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - power_ctrl_enabled = false; - } - qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", - GPIOD_IN); - if (!qcadev->sw_ctrl && data->soc_type == QCA_WCN6750) - dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); - - qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); - if (IS_ERR(qcadev->susclk)) { - dev_err(&serdev->dev, "failed to acquire clk\n"); - return PTR_ERR(qcadev->susclk); - } - - err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); - if (err) { - BT_ERR("wcn3990 serdev registration failed"); - return err; - } - } else { - if (data) - qcadev->btsoc_type = data->soc_type; - else - qcadev->btsoc_type = QCA_ROME; + if (data) + qcadev->btsoc_type = data->soc_type; + else + qcadev->btsoc_type = QCA_ROME; - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (!qcadev->bt_en) { - dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); - power_ctrl_enabled = false; - } + qcadev->pwrseq = devm_pwrseq_get(&serdev->dev, "bt"); + if (IS_ERR(qcadev->pwrseq)) { + dev_err(&serdev->dev, "failed to acquire pwrseq\n"); + return PTR_ERR(qcadev->pwrseq); + } + qcadev->vregs_on = false; - qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); - if (IS_ERR(qcadev->susclk)) { - dev_warn(&serdev->dev, "failed to acquire clk\n"); - return PTR_ERR(qcadev->susclk); - } - err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); - if (err) - return err; - - err = clk_prepare_enable(qcadev->susclk); - if (err) - return err; - - err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); - if (err) { - BT_ERR("Rome serdev registration failed"); - clk_disable_unprepare(qcadev->susclk); - return err; - } + err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); + if (err) { + BT_ERR("wcn3990 serdev registration failed"); + return err; } hdev = qcadev->serdev_hu.hdev; - if (power_ctrl_enabled) { - set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); - hdev->shutdown = qca_power_off; - } + set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); + hdev->shutdown = qca_power_off; if (data) { /* Wideband speech support must be set per driver since it can't @@ -2135,14 +1952,11 @@ static int qca_serdev_probe(struct serdev_device *serdev) static void qca_serdev_remove(struct serdev_device *serdev) { struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); - struct qca_power *power = qcadev->bt_power; if ((qca_is_wcn399x(qcadev->btsoc_type) || qca_is_wcn6750(qcadev->btsoc_type)) && - power->vregs_on) + qcadev->vregs_on) qca_power_shutdown(&qcadev->serdev_hu); - else if (qcadev->susclk) - clk_disable_unprepare(qcadev->susclk); hci_uart_unregister_device(&qcadev->serdev_hu); } From patchwork Wed Oct 6 03:54:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515284 Delivered-To: patch@linaro.org Received: by 2002:ac0:890a:0:0:0:0:0 with SMTP id 10csp155828imy; Tue, 5 Oct 2021 20:56:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzs2GSCmTd3i3AEZp5sU/XY8zfhIjnXG65BB8X+T9Fe6IpgnBK3fFyHEsTUlP8FGi3aposQ X-Received: by 2002:a50:8405:: with SMTP id 5mr31116870edp.228.1633492592395; Tue, 05 Oct 2021 20:56:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633492592; cv=none; d=google.com; s=arc-20160816; b=yGl3HWh4rBWixqqPYa2owb5H/7/8q2WZgLpIe1E8CYrC7YpRFCz3PsVFrB9/TmVH75 k8TjDofebCm8Wn2OK/Z4NffWYQvd28gTltD5FbhxRCe3+mX3Dne1RG9fN8oCCrjtes6m n4gI9PFJFBgOSCpyBPq2dXnQ3SKllKJSt52mYTibs2CzwMeGpy07Isf93v0TJ700g7Jz l5EZW05r4QkwbtT12QfJRY1G53cPklRqFgPPS46ncIz8C2KqdwK7p01QcjaQT0Q6OQi+ 4VPUHQxyhPkJbCR7gPsL9iomaUMwWL1snNnM5tm91IAaHDCfFdPTTtjZSPIPNbu1sCae uwSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=cntTQV+8xT1gaPRWwmEttMqurpErGQCflfEN/t0ShBw=; b=uC7S7FIWHAx/sQQv8UDX+StmDG8hB52jx6mnBojJTmBEvtvkZzDme4UHqQbGbpOSp8 e4j7itDm2urvt/bXVuYv8w3hgRUUs+/my835XlVItz5FLXT73SuXofXN3GvisRXrXNIx KOxNaaYqGgvZ2ebgE8fJ/mMQ46avv4VxXvifLu/vgNFkxYTfRvdvCzZ2A/1K+HNz6t3u AdOjhchX/IesapancvnDSY1n15DY347FqqURX4QHYnM1TCjQa+KYGDzdVYforfxDlN4C jhnkuVRA2w6zQpSiCraJubOTfR2eV3H8CKlFTNvSj/vCtD9KwYY6WjP3+Kgsh3V/6xc+ s7GA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nI8QFgOb; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lf1si3914347ejb.498.2021.10.05.20.56.32; Tue, 05 Oct 2021 20:56:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nI8QFgOb; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230473AbhJFD6R (ORCPT + 17 others); Tue, 5 Oct 2021 23:58:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237300AbhJFD5I (ORCPT ); Tue, 5 Oct 2021 23:57:08 -0400 Received: from mail-lf1-x133.google.com (mail-lf1-x133.google.com [IPv6:2a00:1450:4864:20::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2924C0613A3 for ; Tue, 5 Oct 2021 20:54:25 -0700 (PDT) Received: by mail-lf1-x133.google.com with SMTP id y23so4777358lfb.0 for ; Tue, 05 Oct 2021 20:54:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cntTQV+8xT1gaPRWwmEttMqurpErGQCflfEN/t0ShBw=; b=nI8QFgOb018OHBusf4YC2JeMjW54+ysmQEB8kR7Xsem1gHesZm4WMMnTqiCIMiIJic WI7/wxQI+UPOYHBu3IM8HVi9QtbP9cW2z7Dw6JKWTuCV4ApU9PGZzJrmoVoO8ohQJUx2 ofFLe3i5sE2uwNgAtXM+eSdn8y8WAry7pokGo4W4zYARZ5um+aTBPwVaXMYetwnPHqnt EukYtJv6K7yZzw+gQsNKLblw67yWlUpB+YUL310GiTZMoiBbS2CMLfTpElLBXjmOdr5n Qg+qq3q8Cw/VMVHNvozcdAKgFGZYFF40fyNeJ64thfSGSgOSto4way/p2ww9JO/ImxaM 5Lww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cntTQV+8xT1gaPRWwmEttMqurpErGQCflfEN/t0ShBw=; b=4Sh5fw5DuSmmm/usjn09645HUw4eFgy3NbMGWWnNTEBCvYFM7nHScwq5r1pOscUqXP hU5ZAdpepIGVMPgFaFXkoOLZXxEc5oJGgVXOvucO1/0Pol77sb8H4B3HM1fWfIlJgeE8 x6MI1Dj4rBf2ksw65hmkdz0xTFjLizldMLDq58iwtxco5aV99hr/xPZm3HZYKFDj6W8l lb4z6gTVD7z5QhzBU5mnQ5OE3gOkC76trsJa1ajJ3TOGqAp4wSUnBDfZXOvBbZF4RUgD wWGTwtJV8oS/XeDjwCzlyW0M4pq1kr0alWWFYYWC4sDWwsY9gJuw8X4bASIUrLjDpy4+ ih/w== X-Gm-Message-State: AOAM532j/WwTjVZwjKL085vXQ57c136JMI3bfVCXHO6fHaf/Lm/wsKUc TbmhV5sQvA/AJYN8LGzAH4KNmg== X-Received: by 2002:ac2:59d0:: with SMTP id x16mr7310130lfn.107.1633492464220; Tue, 05 Oct 2021 20:54:24 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id s4sm2142967lfd.103.2021.10.05.20.54.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Oct 2021 20:54:23 -0700 (PDT) From: Dmitry Baryshkov To: Andy Gross , Bjorn Andersson , Ulf Hansson , Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Kalle Valo , "David S. Miller" , Jakub Kicinski , Stanimir Varbanov Cc: linux-arm-msm@vger.kernel.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v1 14/15] WIP: PCI: qcom: use pwrseq to power up bus devices Date: Wed, 6 Oct 2021 06:54:06 +0300 Message-Id: <20211006035407.1147909-15-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> References: <20211006035407.1147909-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Use bus-pwrseq device tree node to power up the devices on the bus. This is to be rewritten with the proper code parsing the device tree and powering up individual devices. Signed-off-by: Dmitry Baryshkov --- drivers/pci/controller/dwc/pcie-qcom.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) -- 2.33.0 diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 8a7a300163e5..f398283912c7 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1467,6 +1468,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) struct pcie_port *pp; struct dw_pcie *pci; struct qcom_pcie *pcie; + struct pwrseq *pwrseq; int ret; pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); @@ -1520,6 +1522,17 @@ static int qcom_pcie_probe(struct platform_device *pdev) pp->ops = &qcom_pcie_dw_ops; + pwrseq = devm_pwrseq_get(dev, "bus"); + if (IS_ERR(pwrseq)) { + ret = PTR_ERR(pwrseq); + goto err_pm_runtime_put; + } + if (pwrseq) { + ret = pwrseq_full_power_on(pwrseq); + if (ret) + goto err_pm_runtime_put; + } + ret = phy_init(pcie->phy); if (ret) { pm_runtime_disable(&pdev->dev);