From patchwork Tue Aug 17 00:54:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87514C43216 for ; Tue, 17 Aug 2021 00:56:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 71D3660EE0 for ; Tue, 17 Aug 2021 00:56:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237535AbhHQA4w (ORCPT ); Mon, 16 Aug 2021 20:56:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235592AbhHQAzt (ORCPT ); Mon, 16 Aug 2021 20:55:49 -0400 Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14DACC0617AD for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x231.google.com with SMTP id h11so30061309ljo.12 for ; Mon, 16 Aug 2021 17:55:15 -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=qnH5wm74aQQYkbbYsHGpsKxsAK5V3pMJGAfubtjXjRY=; b=cC4o/hrQ02ISSmttLJwBudvzBxdgJ7lq9XoYmMU3TumY8yehcdwky82yrf60zYVc3a 7nX1ZONTpwKb8zWb8VzOBNTch3O+6O0HWFf6Ld58mOlWANtH2OkRM+6V8FV7lVOvjWzx Urldw7oXrcjAYZqwklTPMae92K1UXReMh27tfz1YIILg8LZQ57iYmP6GgCO/Ls7sb7HC crhlLdaiax4C3XWCq//gF3oWlNuBBsaLfr3yBaPVog0K+8vsMRpM+5O/aemvE9ZD93Xb oFZug7ynWcw87L5I5OJrPrSbG6OwCsoPbd/KrSXaKLU/5JZKSIHKI9B8/q7sGy/E2CiR F9IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qnH5wm74aQQYkbbYsHGpsKxsAK5V3pMJGAfubtjXjRY=; b=gmRQ7momuekUPGXj3JWQAKLbESyW2ELrCHLmoU7QmA+gFiLX8PkBODmr0M09rogal/ LMmwkRZROuaf+0uZB+2SfJ6e//22WIS//Bs2qXA8GcRPCFRmuX5vY8OduJYKEFAMsfoU o+VTPqOxYLeqop3xLjdrBw5li0RDSUylQhDiSsZlc9mZgRfO21CKFd3ynLABL3uaPja2 BhvuBhaQMMvAjufPTEv2HAaJ/CHNReathMBZThk7IO0dpnEshnhzMukaw6N8tUwbd1oT TWNy7DTc3UIvNJh8Kt/6q8rAPLaWySshyeHCNYVy0PdZHbhTYR0uc0TqC+3XQfmS5Zd2 56wQ== X-Gm-Message-State: AOAM533CXaV5zmryQZ14DScLPtn34Tjd11Wj2nyT5u48cR3iwXhaIMkD wG5HLwm5ASNMP6mRVcBMgDwccA== X-Google-Smtp-Source: ABdhPJwPJ57miR3CMHOwti9+8/OX4IldFiBjVxpgeeZE5hh99p2iu46HrH7fiQwilyAdwnIQCO1LNw== X-Received: by 2002:a05:651c:211b:: with SMTP id a27mr766103ljq.191.1629161714184; Mon, 16 Aug 2021 17:55:14 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:13 -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: [RFC PATCH 01/15] power: add power sequencer subsystem Date: Tue, 17 Aug 2021 03:54:53 +0300 Message-Id: <20210817005507.1507580-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Basing on MMC's pwrseq support code, add separate power sequencer subsystem. It will be used by other drivers to handle device power up requirements. Signed-off-by: Dmitry Baryshkov --- drivers/power/Kconfig | 1 + drivers/power/Makefile | 1 + drivers/power/pwrseq/Kconfig | 11 + drivers/power/pwrseq/Makefile | 6 + drivers/power/pwrseq/core.c | 411 ++++++++++++++++++++++++++++++++ include/linux/pwrseq/consumer.h | 88 +++++++ include/linux/pwrseq/driver.h | 71 ++++++ 7 files changed, 589 insertions(+) create mode 100644 drivers/power/pwrseq/Kconfig create mode 100644 drivers/power/pwrseq/Makefile create mode 100644 drivers/power/pwrseq/core.c create mode 100644 include/linux/pwrseq/consumer.h create mode 100644 include/linux/pwrseq/driver.h diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 696bf77a7042..c87cd2240a74 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only +source "drivers/power/pwrseq/Kconfig" source "drivers/power/reset/Kconfig" source "drivers/power/supply/Kconfig" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index effbf0377f32..1dbce454a8c4 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_POWER_RESET) += reset/ obj-$(CONFIG_POWER_SUPPLY) += supply/ +obj-$(CONFIG_PWRSEQ) += pwrseq/ diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig new file mode 100644 index 000000000000..8904ec9ed541 --- /dev/null +++ b/drivers/power/pwrseq/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig PWRSEQ + bool "Power Sequencer drivers" + help + Provides support for special power sequencing drivers. + + Say Y here to enable support for such devices + +if PWRSEQ + +endif diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile new file mode 100644 index 000000000000..108429ff6445 --- /dev/null +++ b/drivers/power/pwrseq/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for power sequencer drivers. +# + +obj-$(CONFIG_PWRSEQ) += core.o diff --git a/drivers/power/pwrseq/core.c b/drivers/power/pwrseq/core.c new file mode 100644 index 000000000000..20485cae29aa --- /dev/null +++ b/drivers/power/pwrseq/core.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright 2021 (c) Linaro Ltd. +// Author: Dmitry Baryshkov +// +// Based on phy-core.c: +// Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_pwrseq(a) (container_of((a), struct pwrseq, dev)) + +static DEFINE_IDA(pwrseq_ida); +static DEFINE_MUTEX(pwrseq_provider_mutex); +static LIST_HEAD(pwrseq_provider_list); + +struct pwrseq_provider { + struct device *dev; + struct module *owner; + struct list_head list; + void *data; + struct pwrseq * (*of_xlate)(void *data, struct of_phandle_args *args); +}; + +void pwrseq_put(struct device *dev, struct pwrseq *pwrseq) +{ + device_link_remove(dev, &pwrseq->dev); + + module_put(pwrseq->owner); + put_device(&pwrseq->dev); +} +EXPORT_SYMBOL_GPL(pwrseq_put); + +static struct pwrseq_provider *of_pwrseq_provider_lookup(struct device_node *node) +{ + struct pwrseq_provider *pwrseq_provider; + + list_for_each_entry(pwrseq_provider, &pwrseq_provider_list, list) { + if (pwrseq_provider->dev->of_node == node) + return pwrseq_provider; + } + + return ERR_PTR(-EPROBE_DEFER); +} + +static struct pwrseq *_of_pwrseq_get(struct device *dev, const char *id) +{ + struct pwrseq_provider *pwrseq_provider; + struct pwrseq *pwrseq; + struct of_phandle_args args; + char prop_name[64]; /* 64 is max size of property name */ + int ret; + + snprintf(prop_name, 64, "%s-pwrseq", id); + ret = of_parse_phandle_with_args(dev->of_node, prop_name, "#pwrseq-cells", 0, &args); + if (ret) { + struct device_node *dn; + + /* + * Parsing failed. Try locating old bindings for mmc-pwrseq, + * which did not use #pwrseq-cells. + */ + if (strcmp(id, "mmc")) + return ERR_PTR(-ENODEV); + + dn = of_parse_phandle(dev->of_node, prop_name, 0); + if (!dn) + return ERR_PTR(-ENODEV); + + args.np = dn; + args.args_count = 0; + } + + mutex_lock(&pwrseq_provider_mutex); + pwrseq_provider = of_pwrseq_provider_lookup(args.np); + if (IS_ERR(pwrseq_provider) || !try_module_get(pwrseq_provider->owner)) { + pwrseq = ERR_PTR(-EPROBE_DEFER); + goto out_unlock; + } + + if (!of_device_is_available(args.np)) { + dev_warn(pwrseq_provider->dev, "Requested pwrseq is disabled\n"); + pwrseq = ERR_PTR(-ENODEV); + goto out_put_module; + } + + pwrseq = pwrseq_provider->of_xlate(pwrseq_provider->data, &args); + +out_put_module: + module_put(pwrseq_provider->owner); + +out_unlock: + mutex_unlock(&pwrseq_provider_mutex); + of_node_put(args.np); + + return pwrseq; +} + +struct pwrseq *__must_check pwrseq_get(struct device *dev, const char *id) +{ + struct pwrseq *pwrseq; + struct device_link *link; + + pwrseq = _of_pwrseq_get(dev, id); + if (IS_ERR(pwrseq)) + return pwrseq; + + if (!try_module_get(pwrseq->owner)) + return ERR_PTR(-EPROBE_DEFER); + + get_device(&pwrseq->dev); + link = device_link_add(dev, &pwrseq->dev, DL_FLAG_STATELESS); + if (!link) + dev_dbg(dev, "failed to create device link to %s\n", + dev_name(pwrseq->dev.parent)); + + return pwrseq; +} +EXPORT_SYMBOL_GPL(pwrseq_get); + +static void devm_pwrseq_release(struct device *dev, void *res) +{ + struct pwrseq *pwrseq = *(struct pwrseq **)res; + + pwrseq_put(dev, pwrseq); +} + +struct pwrseq *__must_check devm_pwrseq_get(struct device *dev, const char *id) +{ + struct pwrseq **ptr, *pwrseq; + + ptr = devres_alloc(devm_pwrseq_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + pwrseq = pwrseq_get(dev, id); + if (!IS_ERR(pwrseq)) { + *ptr = pwrseq; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pwrseq; +} +EXPORT_SYMBOL_GPL(devm_pwrseq_get); + +struct pwrseq *__must_check pwrseq_get_optional(struct device *dev, const char *id) +{ + struct pwrseq *pwrseq = pwrseq_get(dev, id); + + if (pwrseq == ERR_PTR(-ENODEV)) + return NULL; + + return pwrseq; +} +EXPORT_SYMBOL_GPL(pwrseq_get_optional); + +struct pwrseq *__must_check devm_pwrseq_get_optional(struct device *dev, const char *id) +{ + struct pwrseq **ptr, *pwrseq; + + ptr = devres_alloc(devm_pwrseq_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + pwrseq = pwrseq_get_optional(dev, id); + if (!IS_ERR_OR_NULL(pwrseq)) { + *ptr = pwrseq; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pwrseq; +} +EXPORT_SYMBOL_GPL(devm_pwrseq_get_optional); + +int pwrseq_pre_power_on(struct pwrseq *pwrseq) +{ + if (pwrseq && pwrseq->ops->pre_power_on) + return pwrseq->ops->pre_power_on(pwrseq); + + return 0; +} +EXPORT_SYMBOL_GPL(pwrseq_pre_power_on); + +int pwrseq_power_on(struct pwrseq *pwrseq) +{ + if (pwrseq && pwrseq->ops->power_on) + return pwrseq->ops->power_on(pwrseq); + + return 0; +} +EXPORT_SYMBOL_GPL(pwrseq_power_on); + +void pwrseq_power_off(struct pwrseq *pwrseq) +{ + if (pwrseq && pwrseq->ops->power_off) + pwrseq->ops->power_off(pwrseq); +} +EXPORT_SYMBOL_GPL(pwrseq_power_off); + +void pwrseq_reset(struct pwrseq *pwrseq) +{ + if (pwrseq && pwrseq->ops->reset) + pwrseq->ops->reset(pwrseq); +} +EXPORT_SYMBOL_GPL(pwrseq_reset); + +static void pwrseq_dev_release(struct device *dev) +{ + struct pwrseq *pwrseq = to_pwrseq(dev); + + ida_free(&pwrseq_ida, pwrseq->id); + of_node_put(dev->of_node); + kfree(pwrseq); +} + +static struct class pwrseq_class = { + .name = "pwrseq", + .dev_release = pwrseq_dev_release, +}; + +struct pwrseq *__pwrseq_create(struct device *dev, struct module *owner, const struct pwrseq_ops *ops, void *data) +{ + struct pwrseq *pwrseq; + int ret; + + if (WARN_ON(!dev)) + return ERR_PTR(-EINVAL); + + pwrseq = kzalloc(sizeof(*pwrseq), GFP_KERNEL); + if (!pwrseq) + return ERR_PTR(-ENOMEM); + + ret = ida_alloc(&pwrseq_ida, GFP_KERNEL); + if (ret < 0) + goto free_pwrseq; + + pwrseq->id = ret; + + device_initialize(&pwrseq->dev); + + pwrseq->dev.class = &pwrseq_class; + pwrseq->dev.parent = dev; + pwrseq->dev.of_node = of_node_get(dev->of_node); + pwrseq->ops = ops; + pwrseq->owner = owner; + + dev_set_drvdata(&pwrseq->dev, data); + + ret = dev_set_name(&pwrseq->dev, "pwrseq-%s.%u", dev_name(dev), pwrseq->id); + if (ret) + goto put_dev; + + ret = device_add(&pwrseq->dev); + if (ret) + goto put_dev; + + if (pm_runtime_enabled(dev)) { + pm_runtime_enable(&pwrseq->dev); + pm_runtime_no_callbacks(&pwrseq->dev); + } + + return pwrseq; + +put_dev: + /* will call pwrseq_dev_release() to free resources */ + put_device(&pwrseq->dev); + + return ERR_PTR(ret); + +free_pwrseq: + kfree(pwrseq); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(__pwrseq_create); + +void pwrseq_destroy(struct pwrseq *pwrseq) +{ + pm_runtime_disable(&pwrseq->dev); + device_unregister(&pwrseq->dev); +} +EXPORT_SYMBOL_GPL(pwrseq_destroy); + +static void devm_pwrseq_destroy(struct device *dev, void *res) +{ + struct pwrseq *pwrseq = *(struct pwrseq **)res; + + pwrseq_destroy(pwrseq); +} + +struct pwrseq *__devm_pwrseq_create(struct device *dev, struct module *owner, const struct pwrseq_ops *ops, void *data) +{ + struct pwrseq **ptr, *pwrseq; + + ptr = devres_alloc(devm_pwrseq_destroy, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + pwrseq = __pwrseq_create(dev, owner, ops, data); + if (!IS_ERR(pwrseq)) { + *ptr = pwrseq; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pwrseq; +} +EXPORT_SYMBOL_GPL(__devm_pwrseq_create); + +struct pwrseq_provider *__of_pwrseq_provider_register(struct device *dev, + struct module *owner, + struct pwrseq * (*of_xlate)(void *data, + struct of_phandle_args *args), + void *data) +{ + struct pwrseq_provider *pwrseq_provider; + + pwrseq_provider = kzalloc(sizeof(*pwrseq_provider), GFP_KERNEL); + if (!pwrseq_provider) + return ERR_PTR(-ENOMEM); + + pwrseq_provider->dev = dev; + pwrseq_provider->owner = owner; + pwrseq_provider->of_xlate = of_xlate; + pwrseq_provider->data = data; + + mutex_lock(&pwrseq_provider_mutex); + list_add_tail(&pwrseq_provider->list, &pwrseq_provider_list); + mutex_unlock(&pwrseq_provider_mutex); + + return pwrseq_provider; +} +EXPORT_SYMBOL_GPL(__of_pwrseq_provider_register); + +void of_pwrseq_provider_unregister(struct pwrseq_provider *pwrseq_provider) +{ + if (IS_ERR(pwrseq_provider)) + return; + + mutex_lock(&pwrseq_provider_mutex); + list_del(&pwrseq_provider->list); + kfree(pwrseq_provider); + mutex_unlock(&pwrseq_provider_mutex); +} +EXPORT_SYMBOL_GPL(of_pwrseq_provider_unregister); + +static void devm_pwrseq_provider_unregister(struct device *dev, void *res) +{ + struct pwrseq_provider *pwrseq_provider = *(struct pwrseq_provider **)res; + + of_pwrseq_provider_unregister(pwrseq_provider); +} + +struct pwrseq_provider *__devm_of_pwrseq_provider_register(struct device *dev, + struct module *owner, + struct pwrseq * (*of_xlate)(void *data, + struct of_phandle_args *args), + void *data) +{ + struct pwrseq_provider **ptr, *pwrseq_provider; + + ptr = devres_alloc(devm_pwrseq_provider_unregister, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + pwrseq_provider = __of_pwrseq_provider_register(dev, owner, of_xlate, data); + if (!IS_ERR(pwrseq_provider)) { + *ptr = pwrseq_provider; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pwrseq_provider; +} +EXPORT_SYMBOL_GPL(__devm_of_pwrseq_provider_register); + +struct pwrseq *of_pwrseq_xlate_onecell(void *data, struct of_phandle_args *args) +{ + struct pwrseq_onecell_data *pwrseq_data = data; + unsigned int idx; + + if (args->args_count != 1) + return ERR_PTR(-EINVAL); + + idx = args->args[0]; + if (idx >= pwrseq_data->num) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return pwrseq_data->pwrseqs[idx]; +} + +static int __init pwrseq_core_init(void) +{ + return class_register(&pwrseq_class); +} +device_initcall(pwrseq_core_init); diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h new file mode 100644 index 000000000000..fbcdc1fc0751 --- /dev/null +++ b/include/linux/pwrseq/consumer.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Linaro Ltd. + */ + +#ifndef __LINUX_PWRSEQ_CONSUMER_H__ +#define __LINUX_PWRSEQ_CONSUMER_H__ + +struct pwrseq; +struct device; + +#if defined(CONFIG_PWRSEQ) + +struct pwrseq *__must_check pwrseq_get(struct device *dev, const char *id); +struct pwrseq *__must_check devm_pwrseq_get(struct device *dev, const char *id); + +struct pwrseq *__must_check pwrseq_get_optional(struct device *dev, const char *id); +struct pwrseq *__must_check devm_pwrseq_get_optional(struct device *dev, const char *id); + +void pwrseq_put(struct device *dev, struct pwrseq *pwrseq); + +int pwrseq_pre_power_on(struct pwrseq *pwrseq); +int pwrseq_power_on(struct pwrseq *pwrseq); +void pwrseq_power_off(struct pwrseq *pwrseq); +void pwrseq_reset(struct pwrseq *pwrseq); + +#else + +static inline struct pwrseq *__must_check +pwrseq_get(struct device *dev, const char *id) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct pwrseq *__must_check +devm_pwrseq_get(struct device *dev, const char *id) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct pwrseq *__must_check +pwrseq_get_optional(struct device *dev, const char *id) +{ + return NULL; +} + +static inline struct pwrseq *__must_check +devm_pwrseq_get_optional(struct device *dev, const char *id) +{ + return NULL; +} + +static inline void pwrseq_put(struct device *dev, struct pwrseq *pwrseq) +{ +} + +static inline int pwrseq_pre_power_on(struct pwrseq *pwrseq) +{ + return -ENOSYS; +} + +static inline int pwrseq_power_on(struct pwrseq *pwrseq) +{ + return -ENOSYS; +} + +static inline void pwrseq_power_off(struct pwrseq *pwrseq) +{ +} + +static inline void pwrseq_reset(struct pwrseq *pwrseq) +{ +} + +#endif + +static inline int pwrseq_full_power_on(struct pwrseq *pwrseq) +{ + int ret; + + ret = pwrseq_pre_power_on(pwrseq); + if (ret) + return ret; + + return pwrseq_power_on(pwrseq); +} + +#endif /* __LINUX_PWRSEQ_CONSUMER_H__ */ diff --git a/include/linux/pwrseq/driver.h b/include/linux/pwrseq/driver.h new file mode 100644 index 000000000000..6d7c66525134 --- /dev/null +++ b/include/linux/pwrseq/driver.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Linaro Ltd. + */ + +#ifndef __LINUX_PWRSEQ_DRIVER_H__ +#define __LINUX_PWRSEQ_DRIVER_H__ + +#include + +struct pwrseq; + +struct pwrseq_ops { + int (*pre_power_on)(struct pwrseq *pwrseq); + int (*power_on)(struct pwrseq *pwrseq); + void (*power_off)(struct pwrseq *pwrseq); + void (*reset)(struct pwrseq *pwrseq); +}; + +struct pwrseq { + struct device dev; + const struct pwrseq_ops *ops; + unsigned int id; + struct module *owner; +}; + +struct pwrseq *__pwrseq_create(struct device *dev, struct module *owner, const struct pwrseq_ops *ops, void *data); +struct pwrseq *__devm_pwrseq_create(struct device *dev, struct module *owner, const struct pwrseq_ops *ops, void *data); + +#define pwrseq_create(dev, ops, data) __pwrseq_create((dev), THIS_MODULE, (ops), (data)) +#define devm_pwrseq_create(dev, ops, data) __devm_pwrseq_create((dev), THIS_MODULE, (ops), (data)) + +void pwrseq_destroy(struct pwrseq *pwrseq); + +static inline void *pwrseq_get_data(struct pwrseq *pwrseq) +{ + return dev_get_drvdata(&pwrseq->dev); +} + +#define of_pwrseq_provider_register(dev, xlate, data) \ + __of_pwrseq_provider_register((dev), THIS_MODULE, (xlate), (data)) + +#define devm_of_pwrseq_provider_register(dev, xlate, data) \ + __devm_of_pwrseq_provider_register((dev), THIS_MODULE, (xlate), (data)) + +struct pwrseq_provider *__of_pwrseq_provider_register(struct device *dev, + struct module *owner, + struct pwrseq * (*of_xlate)(void *data, + struct of_phandle_args *args), + void *data); +struct pwrseq_provider *__devm_of_pwrseq_provider_register(struct device *dev, + struct module *owner, + struct pwrseq * (*of_xlate)(void *data, + struct of_phandle_args *args), + void *data); +void of_pwrseq_provider_unregister(struct pwrseq_provider *pwrseq_provider); + +static inline struct pwrseq *of_pwrseq_xlate_single(void *data, + struct of_phandle_args *args) +{ + return data; +} + +struct pwrseq_onecell_data { + unsigned int num; + struct pwrseq *pwrseqs[]; +}; + +struct pwrseq *of_pwrseq_xlate_onecell(void *data, struct of_phandle_args *args); + +#endif /* __LINUX_PWRSEQ_DRIVER_H__ */ From patchwork Tue Aug 17 00:54:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31F1EC4320A for ; Tue, 17 Aug 2021 00:56:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 16AAD60EE0 for ; Tue, 17 Aug 2021 00:56:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235652AbhHQA4t (ORCPT ); Mon, 16 Aug 2021 20:56:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235656AbhHQAzt (ORCPT ); Mon, 16 Aug 2021 20:55:49 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8EB8C0612E7 for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id n6so30065804ljp.9 for ; Mon, 16 Aug 2021 17:55:16 -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=FRhJlspuhr5Q3RAjzuhd5WsagmM/XJE9SdkaJUDZM6w=; b=fdUyAwxHnLCAtikwBEBM1kQZ/KTdfUZVby/xjvc0oz84sCO1fRXVf8wMYh0eDH46MI hnLfx+VkmOKDWTc6caj3PmQd5iIsTOfxfdUsNln2QzfCr2IC0iyZxukbeOtMVYoMejZb pJQJbad63VL5V6LPBtmgYAuJgUv4wQILf5v3mUlkY5pVKc9GqRGAmJNwvRRfA6ZgDOtn uPDaK9T8DWuCu/HDbIVmpZcnkvfEBjBzlqVXs9Xk5oskdhSrGyBCHi03nTIP7P3MZwsq 3uQ4yzmHwAKjCjJc0+PLzQ0bycu7LESwTyjYfSgFx4ZZWMVx242Zdy6A2KeejIKHMd0n dDmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FRhJlspuhr5Q3RAjzuhd5WsagmM/XJE9SdkaJUDZM6w=; b=aJN4GNgP2BweB9t1IEDFsC9+5nYXYDZqHHq5VGmVKLOM29yU2knfIz2lBUUZBe/n5x 7oFZwGd9EE4Tv92gqwi9tDbXKq1qpU6OKMby04E+p3bftfM1y1Yqj78DdVJJUfkvlT5o cytJtu6mX8jhGkeWftXQfU7xr9F0Nr+3ZhKL29olTymx4Q6yT2fmSVr4XO/lmUJ/oobt LCI2vhr2MQg3zR3rMoaTxsOPprYaCxD+EZ8rChOsQm3mAS/vfamDAPtLPdkF56svKqsk dgbEgTSeAM5mXR7b/UTiu+TT0z/KKCCHqxoh0JNVfj+IxMg/IjPCSxpMM/DQwXeK4GNM pKeQ== X-Gm-Message-State: AOAM532tUsgJYih5q60W2pwk1FUWgQMQxi2osqeJ9EbC2heSQGehVp+D zYeRngKNfw/ebaU07WAtNWy8yA== X-Google-Smtp-Source: ABdhPJxTs5QoxsKt8CoEGoLxj8Tx7EmN2XLBfvYLdBTJTU9Eg6vdu8tTkPjB9z2/Vf6240S1i/Rvmg== X-Received: by 2002:a2e:a225:: with SMTP id i5mr803806ljm.64.1629161714891; Mon, 16 Aug 2021 17:55:14 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:14 -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: [RFC PATCH 02/15] pwrseq: port MMC's pwrseq drivers to new pwrseq subsystem Date: Tue, 17 Aug 2021 03:54:54 +0300 Message-Id: <20210817005507.1507580-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Port MMC's all pwrseq drivers to new pwrseq subsystem. Signed-off-by: Dmitry Baryshkov --- .../pwrseq}/mmc-pwrseq-emmc.yaml | 0 .../pwrseq}/mmc-pwrseq-sd8787.yaml | 0 .../pwrseq}/mmc-pwrseq-simple.yaml | 0 drivers/mmc/core/Kconfig | 32 ---- drivers/mmc/core/Makefile | 3 - drivers/mmc/core/pwrseq_emmc.c | 120 ------------- drivers/mmc/core/pwrseq_sd8787.c | 107 ------------ drivers/mmc/core/pwrseq_simple.c | 164 ------------------ drivers/power/pwrseq/Kconfig | 32 ++++ drivers/power/pwrseq/Makefile | 4 + drivers/power/pwrseq/pwrseq_emmc.c | 118 +++++++++++++ drivers/power/pwrseq/pwrseq_sd8787.c | 97 +++++++++++ drivers/power/pwrseq/pwrseq_simple.c | 160 +++++++++++++++++ 13 files changed, 411 insertions(+), 426 deletions(-) rename Documentation/devicetree/bindings/{mmc => power/pwrseq}/mmc-pwrseq-emmc.yaml (100%) rename Documentation/devicetree/bindings/{mmc => power/pwrseq}/mmc-pwrseq-sd8787.yaml (100%) rename Documentation/devicetree/bindings/{mmc => power/pwrseq}/mmc-pwrseq-simple.yaml (100%) delete mode 100644 drivers/mmc/core/pwrseq_emmc.c delete mode 100644 drivers/mmc/core/pwrseq_sd8787.c delete mode 100644 drivers/mmc/core/pwrseq_simple.c create mode 100644 drivers/power/pwrseq/pwrseq_emmc.c create mode 100644 drivers/power/pwrseq/pwrseq_sd8787.c create mode 100644 drivers/power/pwrseq/pwrseq_simple.c diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.yaml b/Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-emmc.yaml similarity index 100% rename from Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.yaml rename to Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-emmc.yaml diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml b/Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-sd8787.yaml similarity index 100% rename from Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml rename to Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-sd8787.yaml diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml b/Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-simple.yaml similarity index 100% rename from Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml rename to Documentation/devicetree/bindings/power/pwrseq/mmc-pwrseq-simple.yaml diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index ae8b69aee619..cf7df64ce009 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -2,38 +2,6 @@ # # MMC core configuration # -config PWRSEQ_EMMC - tristate "HW reset support for eMMC" - default y - depends on OF - help - This selects Hardware reset support aka pwrseq-emmc for eMMC - devices. By default this option is set to y. - - This driver can also be built as a module. If so, the module - will be called pwrseq_emmc. - -config PWRSEQ_SD8787 - tristate "HW reset support for SD8787 BT + Wifi module" - depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO) - help - This selects hardware reset support for the SD8787 BT + Wifi - module. By default this option is set to n. - - This driver can also be built as a module. If so, the module - will be called pwrseq_sd8787. - -config PWRSEQ_SIMPLE - tristate "Simple HW reset support for MMC" - default y - depends on OF - help - This selects simple hardware reset support aka pwrseq-simple for MMC - devices. By default this option is set to y. - - This driver can also be built as a module. If so, the module - will be called pwrseq_simple. - config MMC_BLOCK tristate "MMC block device driver" depends on BLOCK diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 6a907736cd7a..322eb69bd00e 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -10,9 +10,6 @@ mmc_core-y := core.o bus.o host.o \ sdio_cis.o sdio_io.o sdio_irq.o \ slot-gpio.o regulator.o mmc_core-$(CONFIG_OF) += pwrseq.o -obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o -obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o -obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o obj-$(CONFIG_MMC_BLOCK) += mmc_block.o mmc_block-objs := block.o queue.o diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c deleted file mode 100644 index f6dde9edd7a3..000000000000 --- a/drivers/mmc/core/pwrseq_emmc.c +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015, Samsung Electronics Co., Ltd. - * - * Author: Marek Szyprowski - * - * Simple eMMC hardware reset provider - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pwrseq.h" - -struct mmc_pwrseq_emmc { - struct mmc_pwrseq pwrseq; - struct notifier_block reset_nb; - struct gpio_desc *reset_gpio; -}; - -#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq) - -static void mmc_pwrseq_emmc_reset(struct mmc_host *host) -{ - struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); - - gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); - udelay(1); - gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); - udelay(200); -} - -static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, - unsigned long mode, void *cmd) -{ - struct mmc_pwrseq_emmc *pwrseq = container_of(this, - struct mmc_pwrseq_emmc, reset_nb); - gpiod_set_value(pwrseq->reset_gpio, 1); - udelay(1); - gpiod_set_value(pwrseq->reset_gpio, 0); - udelay(200); - - return NOTIFY_DONE; -} - -static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { - .reset = mmc_pwrseq_emmc_reset, -}; - -static int mmc_pwrseq_emmc_probe(struct platform_device *pdev) -{ - struct mmc_pwrseq_emmc *pwrseq; - struct device *dev = &pdev->dev; - - pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); - if (!pwrseq) - return -ENOMEM; - - pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(pwrseq->reset_gpio)) - return PTR_ERR(pwrseq->reset_gpio); - - if (!gpiod_cansleep(pwrseq->reset_gpio)) { - /* - * register reset handler to ensure emmc reset also from - * emergency_reboot(), priority 255 is the highest priority - * so it will be executed before any system reboot handler. - */ - pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; - pwrseq->reset_nb.priority = 255; - register_restart_handler(&pwrseq->reset_nb); - } else { - dev_notice(dev, "EMMC reset pin tied to a sleepy GPIO driver; reset on emergency-reboot disabled\n"); - } - - pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; - pwrseq->pwrseq.dev = dev; - pwrseq->pwrseq.owner = THIS_MODULE; - platform_set_drvdata(pdev, pwrseq); - - return mmc_pwrseq_register(&pwrseq->pwrseq); -} - -static int mmc_pwrseq_emmc_remove(struct platform_device *pdev) -{ - struct mmc_pwrseq_emmc *pwrseq = platform_get_drvdata(pdev); - - unregister_restart_handler(&pwrseq->reset_nb); - mmc_pwrseq_unregister(&pwrseq->pwrseq); - - return 0; -} - -static const struct of_device_id mmc_pwrseq_emmc_of_match[] = { - { .compatible = "mmc-pwrseq-emmc",}, - {/* sentinel */}, -}; - -MODULE_DEVICE_TABLE(of, mmc_pwrseq_emmc_of_match); - -static struct platform_driver mmc_pwrseq_emmc_driver = { - .probe = mmc_pwrseq_emmc_probe, - .remove = mmc_pwrseq_emmc_remove, - .driver = { - .name = "pwrseq_emmc", - .of_match_table = mmc_pwrseq_emmc_of_match, - }, -}; - -module_platform_driver(mmc_pwrseq_emmc_driver); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c deleted file mode 100644 index 68a826f1c0a1..000000000000 --- a/drivers/mmc/core/pwrseq_sd8787.c +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip - * - * Copyright (C) 2016 Matt Ranostay - * - * Based on the original work pwrseq_simple.c - * Copyright (C) 2014 Linaro Ltd - * Author: Ulf Hansson - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pwrseq.h" - -struct mmc_pwrseq_sd8787 { - struct mmc_pwrseq pwrseq; - struct gpio_desc *reset_gpio; - struct gpio_desc *pwrdn_gpio; -}; - -#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq) - -static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host) -{ - struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq); - - gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); - - msleep(300); - gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1); -} - -static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host) -{ - struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq); - - gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0); - gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); -} - -static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = { - .pre_power_on = mmc_pwrseq_sd8787_pre_power_on, - .power_off = mmc_pwrseq_sd8787_power_off, -}; - -static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = { - { .compatible = "mmc-pwrseq-sd8787",}, - {/* sentinel */}, -}; -MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match); - -static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) -{ - struct mmc_pwrseq_sd8787 *pwrseq; - struct device *dev = &pdev->dev; - - pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); - if (!pwrseq) - return -ENOMEM; - - pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); - if (IS_ERR(pwrseq->pwrdn_gpio)) - return PTR_ERR(pwrseq->pwrdn_gpio); - - pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(pwrseq->reset_gpio)) - return PTR_ERR(pwrseq->reset_gpio); - - pwrseq->pwrseq.dev = dev; - pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops; - pwrseq->pwrseq.owner = THIS_MODULE; - platform_set_drvdata(pdev, pwrseq); - - return mmc_pwrseq_register(&pwrseq->pwrseq); -} - -static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev) -{ - struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev); - - mmc_pwrseq_unregister(&pwrseq->pwrseq); - - return 0; -} - -static struct platform_driver mmc_pwrseq_sd8787_driver = { - .probe = mmc_pwrseq_sd8787_probe, - .remove = mmc_pwrseq_sd8787_remove, - .driver = { - .name = "pwrseq_sd8787", - .of_match_table = mmc_pwrseq_sd8787_of_match, - }, -}; - -module_platform_driver(mmc_pwrseq_sd8787_driver); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c deleted file mode 100644 index ea4d3670560e..000000000000 --- a/drivers/mmc/core/pwrseq_simple.c +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Linaro Ltd - * - * Author: Ulf Hansson - * - * Simple MMC power sequence management - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "pwrseq.h" - -struct mmc_pwrseq_simple { - struct mmc_pwrseq pwrseq; - bool clk_enabled; - u32 post_power_on_delay_ms; - u32 power_off_delay_us; - struct clk *ext_clk; - struct gpio_descs *reset_gpios; -}; - -#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq) - -static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, - int value) -{ - struct gpio_descs *reset_gpios = pwrseq->reset_gpios; - - if (!IS_ERR(reset_gpios)) { - unsigned long *values; - int nvalues = reset_gpios->ndescs; - - values = bitmap_alloc(nvalues, GFP_KERNEL); - if (!values) - return; - - if (value) - bitmap_fill(values, nvalues); - else - bitmap_zero(values, nvalues); - - gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, - reset_gpios->info, values); - - kfree(values); - } -} - -static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) -{ - struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); - - if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) { - clk_prepare_enable(pwrseq->ext_clk); - pwrseq->clk_enabled = true; - } - - mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); -} - -static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) -{ - struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); - - mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); - - if (pwrseq->post_power_on_delay_ms) - msleep(pwrseq->post_power_on_delay_ms); -} - -static void mmc_pwrseq_simple_power_off(struct mmc_host *host) -{ - struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); - - mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); - - if (pwrseq->power_off_delay_us) - usleep_range(pwrseq->power_off_delay_us, - 2 * pwrseq->power_off_delay_us); - - if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) { - clk_disable_unprepare(pwrseq->ext_clk); - pwrseq->clk_enabled = false; - } -} - -static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { - .pre_power_on = mmc_pwrseq_simple_pre_power_on, - .post_power_on = mmc_pwrseq_simple_post_power_on, - .power_off = mmc_pwrseq_simple_power_off, -}; - -static const struct of_device_id mmc_pwrseq_simple_of_match[] = { - { .compatible = "mmc-pwrseq-simple",}, - {/* sentinel */}, -}; -MODULE_DEVICE_TABLE(of, mmc_pwrseq_simple_of_match); - -static int mmc_pwrseq_simple_probe(struct platform_device *pdev) -{ - struct mmc_pwrseq_simple *pwrseq; - struct device *dev = &pdev->dev; - - pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); - if (!pwrseq) - return -ENOMEM; - - pwrseq->ext_clk = devm_clk_get(dev, "ext_clock"); - if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT) - return PTR_ERR(pwrseq->ext_clk); - - pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset", - GPIOD_OUT_HIGH); - if (IS_ERR(pwrseq->reset_gpios) && - PTR_ERR(pwrseq->reset_gpios) != -ENOENT && - PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) { - return PTR_ERR(pwrseq->reset_gpios); - } - - device_property_read_u32(dev, "post-power-on-delay-ms", - &pwrseq->post_power_on_delay_ms); - device_property_read_u32(dev, "power-off-delay-us", - &pwrseq->power_off_delay_us); - - pwrseq->pwrseq.dev = dev; - pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; - pwrseq->pwrseq.owner = THIS_MODULE; - platform_set_drvdata(pdev, pwrseq); - - return mmc_pwrseq_register(&pwrseq->pwrseq); -} - -static int mmc_pwrseq_simple_remove(struct platform_device *pdev) -{ - struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev); - - mmc_pwrseq_unregister(&pwrseq->pwrseq); - - return 0; -} - -static struct platform_driver mmc_pwrseq_simple_driver = { - .probe = mmc_pwrseq_simple_probe, - .remove = mmc_pwrseq_simple_remove, - .driver = { - .name = "pwrseq_simple", - .of_match_table = mmc_pwrseq_simple_of_match, - }, -}; - -module_platform_driver(mmc_pwrseq_simple_driver); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig index 8904ec9ed541..36339a456b03 100644 --- a/drivers/power/pwrseq/Kconfig +++ b/drivers/power/pwrseq/Kconfig @@ -8,4 +8,36 @@ menuconfig PWRSEQ if PWRSEQ +config PWRSEQ_EMMC + tristate "HW reset support for eMMC" + default y + depends on OF + help + This selects Hardware reset support aka pwrseq-emmc for eMMC + devices. By default this option is set to y. + + This driver can also be built as a module. If so, the module + will be called pwrseq_emmc. + +config PWRSEQ_SD8787 + tristate "HW reset support for SD8787 BT + Wifi module" + depends on OF + help + This selects hardware reset support for the SD8787 BT + Wifi + module. By default this option is set to n. + + This driver can also be built as a module. If so, the module + will be called pwrseq_sd8787. + +config PWRSEQ_SIMPLE + tristate "Simple HW reset support" + default y + depends on OF + help + This selects simple hardware reset support aka pwrseq-simple. + By default this option is set to y. + + This driver can also be built as a module. If so, the module + will be called pwrseq_simple. + endif diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile index 108429ff6445..6f359d228843 100644 --- a/drivers/power/pwrseq/Makefile +++ b/drivers/power/pwrseq/Makefile @@ -4,3 +4,7 @@ # obj-$(CONFIG_PWRSEQ) += core.o + +obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o +obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o diff --git a/drivers/power/pwrseq/pwrseq_emmc.c b/drivers/power/pwrseq/pwrseq_emmc.c new file mode 100644 index 000000000000..a56969e18b1a --- /dev/null +++ b/drivers/power/pwrseq/pwrseq_emmc.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2015, Samsung Electronics Co., Ltd. + * + * Author: Marek Szyprowski + * + * Simple eMMC hardware reset provider + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct pwrseq_emmc { + struct notifier_block reset_nb; + struct gpio_desc *reset_gpio; +}; + +static void pwrseq_ereset(struct pwrseq *pwrseq) +{ + struct pwrseq_emmc *pwrseq_emmc = pwrseq_get_data(pwrseq); + + gpiod_set_value_cansleep(pwrseq_emmc->reset_gpio, 1); + udelay(1); + gpiod_set_value_cansleep(pwrseq_emmc->reset_gpio, 0); + udelay(200); +} + +static int pwrseq_ereset_nb(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + struct pwrseq_emmc *pwrseq_emmc = container_of(this, + struct pwrseq_emmc, reset_nb); + gpiod_set_value(pwrseq_emmc->reset_gpio, 1); + udelay(1); + gpiod_set_value(pwrseq_emmc->reset_gpio, 0); + udelay(200); + + return NOTIFY_DONE; +} + +static const struct pwrseq_ops pwrseq_eops = { + .reset = pwrseq_ereset, +}; + +static int pwrseq_eprobe(struct platform_device *pdev) +{ + struct pwrseq_emmc *pwrseq_emmc; + struct pwrseq *pwrseq; + struct pwrseq_provider *provider; + struct device *dev = &pdev->dev; + + pwrseq_emmc = devm_kzalloc(dev, sizeof(*pwrseq_emmc), GFP_KERNEL); + if (!pwrseq_emmc) + return -ENOMEM; + + pwrseq_emmc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(pwrseq_emmc->reset_gpio)) + return PTR_ERR(pwrseq_emmc->reset_gpio); + + if (!gpiod_cansleep(pwrseq_emmc->reset_gpio)) { + /* + * register reset handler to ensure emmc reset also from + * emergency_reboot(), priority 255 is the highest priority + * so it will be executed before any system reboot handler. + */ + pwrseq_emmc->reset_nb.notifier_call = pwrseq_ereset_nb; + pwrseq_emmc->reset_nb.priority = 255; + register_restart_handler(&pwrseq_emmc->reset_nb); + } else { + dev_notice(dev, "EMMC reset pin tied to a sleepy GPIO driver; reset on emergency-reboot disabled\n"); + } + + platform_set_drvdata(pdev, pwrseq_emmc); + + pwrseq = devm_pwrseq_create(dev, &pwrseq_eops, pwrseq_emmc); + if (IS_ERR(pwrseq)) + return PTR_ERR(pwrseq); + + provider = devm_of_pwrseq_provider_register(dev, of_pwrseq_xlate_single, pwrseq); + + return PTR_ERR_OR_ZERO(provider); +} + +static int pwrseq_eremove(struct platform_device *pdev) +{ + struct pwrseq_emmc *pwrseq_emmc = platform_get_drvdata(pdev); + + unregister_restart_handler(&pwrseq_emmc->reset_nb); + + return 0; +} + +static const struct of_device_id pwrseq_eof_match[] = { + { .compatible = "mmc-pwrseq-emmc",}, + {/* sentinel */}, +}; + +MODULE_DEVICE_TABLE(of, pwrseq_eof_match); + +static struct platform_driver pwrseq_edriver = { + .probe = pwrseq_eprobe, + .remove = pwrseq_eremove, + .driver = { + .name = "pwrseq_emmc", + .of_match_table = pwrseq_eof_match, + }, +}; + +module_platform_driver(pwrseq_edriver); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/pwrseq/pwrseq_sd8787.c b/drivers/power/pwrseq/pwrseq_sd8787.c new file mode 100644 index 000000000000..7759097dd4d6 --- /dev/null +++ b/drivers/power/pwrseq/pwrseq_sd8787.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip + * + * Copyright (C) 2016 Matt Ranostay + * + * Based on the original work pwrseq_sd8787.c + * Copyright (C) 2014 Linaro Ltd + * Author: Ulf Hansson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct pwrseq_sd8787 { + struct gpio_desc *reset_gpio; + struct gpio_desc *pwrdn_gpio; +}; + +static int pwrseq_sd8787_pre_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_sd8787 *pwrseq_sd8787 = pwrseq_get_data(pwrseq); + + gpiod_set_value_cansleep(pwrseq_sd8787->reset_gpio, 1); + + msleep(300); + gpiod_set_value_cansleep(pwrseq_sd8787->pwrdn_gpio, 1); + + return 0; +} + +static void pwrseq_sd8787_power_off(struct pwrseq *pwrseq) +{ + struct pwrseq_sd8787 *pwrseq_sd8787 = pwrseq_get_data(pwrseq); + + gpiod_set_value_cansleep(pwrseq_sd8787->pwrdn_gpio, 0); + gpiod_set_value_cansleep(pwrseq_sd8787->reset_gpio, 0); +} + +static const struct pwrseq_ops pwrseq_sd8787_ops = { + .pre_power_on = pwrseq_sd8787_pre_power_on, + .power_off = pwrseq_sd8787_power_off, +}; + +static const struct of_device_id pwrseq_sd8787_of_match[] = { + { .compatible = "mmc-pwrseq-sd8787",}, + {/* sentinel */}, +}; +MODULE_DEVICE_TABLE(of, pwrseq_sd8787_of_match); + +static int pwrseq_sd8787_probe(struct platform_device *pdev) +{ + struct pwrseq_sd8787 *pwrseq_sd8787; + struct pwrseq *pwrseq; + struct pwrseq_provider *provider; + struct device *dev = &pdev->dev; + + pwrseq_sd8787 = devm_kzalloc(dev, sizeof(*pwrseq_sd8787), GFP_KERNEL); + if (!pwrseq_sd8787) + return -ENOMEM; + + pwrseq_sd8787->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); + if (IS_ERR(pwrseq_sd8787->pwrdn_gpio)) + return PTR_ERR(pwrseq_sd8787->pwrdn_gpio); + + pwrseq_sd8787->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(pwrseq_sd8787->reset_gpio)) + return PTR_ERR(pwrseq_sd8787->reset_gpio); + + pwrseq = devm_pwrseq_create(dev, &pwrseq_sd8787_ops, pwrseq_sd8787); + if (IS_ERR(pwrseq)) + return PTR_ERR(pwrseq); + + provider = devm_of_pwrseq_provider_register(dev, of_pwrseq_xlate_single, pwrseq); + + return PTR_ERR_OR_ZERO(provider); +} + +static struct platform_driver pwrseq_sd8787_driver = { + .probe = pwrseq_sd8787_probe, + .driver = { + .name = "pwrseq_sd8787", + .of_match_table = pwrseq_sd8787_of_match, + }, +}; + +module_platform_driver(pwrseq_sd8787_driver); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/pwrseq/pwrseq_simple.c b/drivers/power/pwrseq/pwrseq_simple.c new file mode 100644 index 000000000000..f8d6e6e077df --- /dev/null +++ b/drivers/power/pwrseq/pwrseq_simple.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2014 Linaro Ltd + * + * Author: Ulf Hansson + * + * Simple MMC power sequence management + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct pwrseq_simple { + bool clk_enabled; + u32 post_power_on_delay_ms; + u32 power_off_delay_us; + struct clk *ext_clk; + struct gpio_descs *reset_gpios; +}; + +static int pwrseq_simple_set_gpios_value(struct pwrseq_simple *pwrseq_simple, + int value) +{ + struct gpio_descs *reset_gpios = pwrseq_simple->reset_gpios; + unsigned long *values; + int nvalues; + int ret; + + if (IS_ERR(reset_gpios)) + return PTR_ERR(reset_gpios); + + nvalues = reset_gpios->ndescs; + + values = bitmap_alloc(nvalues, GFP_KERNEL); + if (!values) + return -ENOMEM; + + if (value) + bitmap_fill(values, nvalues); + else + bitmap_zero(values, nvalues); + + ret = gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, + reset_gpios->info, values); + kfree(values); + + return ret; +} + +static int pwrseq_simple_pre_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_simple *pwrseq_simple = pwrseq_get_data(pwrseq); + + if (!IS_ERR(pwrseq_simple->ext_clk) && !pwrseq_simple->clk_enabled) { + clk_prepare_enable(pwrseq_simple->ext_clk); + pwrseq_simple->clk_enabled = true; + } + + return pwrseq_simple_set_gpios_value(pwrseq_simple, 1); +} + +static int pwrseq_simple_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_simple *pwrseq_simple = pwrseq_get_data(pwrseq); + int ret; + + ret = pwrseq_simple_set_gpios_value(pwrseq_simple, 0); + if (ret) + return ret; + + if (pwrseq_simple->post_power_on_delay_ms) + msleep(pwrseq_simple->post_power_on_delay_ms); + + return 0; +} + +static void pwrseq_simple_power_off(struct pwrseq *pwrseq) +{ + struct pwrseq_simple *pwrseq_simple = pwrseq_get_data(pwrseq); + + pwrseq_simple_set_gpios_value(pwrseq_simple, 1); + + if (pwrseq_simple->power_off_delay_us) + usleep_range(pwrseq_simple->power_off_delay_us, + 2 * pwrseq_simple->power_off_delay_us); + + if (!IS_ERR(pwrseq_simple->ext_clk) && pwrseq_simple->clk_enabled) { + clk_disable_unprepare(pwrseq_simple->ext_clk); + pwrseq_simple->clk_enabled = false; + } +} + +static const struct pwrseq_ops pwrseq_simple_ops = { + .pre_power_on = pwrseq_simple_pre_power_on, + .power_on = pwrseq_simple_power_on, + .power_off = pwrseq_simple_power_off, +}; + +static const struct of_device_id pwrseq_simple_of_match[] = { + { .compatible = "mmc-pwrseq-simple",}, /* MMC-specific compatible */ + {/* sentinel */}, +}; +MODULE_DEVICE_TABLE(of, pwrseq_simple_of_match); + +static int pwrseq_simple_probe(struct platform_device *pdev) +{ + struct pwrseq_simple *pwrseq_simple; + struct pwrseq *pwrseq; + struct pwrseq_provider *provider; + struct device *dev = &pdev->dev; + + pwrseq_simple = devm_kzalloc(dev, sizeof(*pwrseq_simple), GFP_KERNEL); + if (!pwrseq_simple) + return -ENOMEM; + + pwrseq_simple->ext_clk = devm_clk_get(dev, "ext_clock"); + if (IS_ERR(pwrseq_simple->ext_clk) && PTR_ERR(pwrseq_simple->ext_clk) != -ENOENT) + return PTR_ERR(pwrseq_simple->ext_clk); + + pwrseq_simple->reset_gpios = devm_gpiod_get_array(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(pwrseq_simple->reset_gpios) && + PTR_ERR(pwrseq_simple->reset_gpios) != -ENOENT && + PTR_ERR(pwrseq_simple->reset_gpios) != -ENOSYS) { + return PTR_ERR(pwrseq_simple->reset_gpios); + } + + device_property_read_u32(dev, "post-power-on-delay-ms", + &pwrseq_simple->post_power_on_delay_ms); + device_property_read_u32(dev, "power-off-delay-us", + &pwrseq_simple->power_off_delay_us); + + pwrseq = devm_pwrseq_create(dev, &pwrseq_simple_ops, pwrseq_simple); + if (IS_ERR(pwrseq)) + return PTR_ERR(pwrseq); + + provider = devm_of_pwrseq_provider_register(dev, of_pwrseq_xlate_single, pwrseq); + + return PTR_ERR_OR_ZERO(provider); +} + +static struct platform_driver pwrseq_simple_driver = { + .probe = pwrseq_simple_probe, + .driver = { + .name = "pwrseq_simple", + .of_match_table = pwrseq_simple_of_match, + }, +}; + +module_platform_driver(pwrseq_simple_driver); +MODULE_LICENSE("GPL v2"); From patchwork Tue Aug 17 00:54:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA83AC4320A for ; Tue, 17 Aug 2021 00:55:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9275160E76 for ; Tue, 17 Aug 2021 00:55:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235884AbhHQAzv (ORCPT ); Mon, 16 Aug 2021 20:55:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235719AbhHQAzu (ORCPT ); Mon, 16 Aug 2021 20:55:50 -0400 Received: from mail-lj1-x22a.google.com (mail-lj1-x22a.google.com [IPv6:2a00:1450:4864:20::22a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A9F4C061764 for ; Mon, 16 Aug 2021 17:55:17 -0700 (PDT) Received: by mail-lj1-x22a.google.com with SMTP id h9so30119018ljq.8 for ; Mon, 16 Aug 2021 17:55:17 -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=zHW7j8uJ1T5WAhTwDkkfCp9h9wlSajIJoR2TS5WeI4s=; b=M+8JmFaKoyF4Y6sGJg8MksjCPy8KWaLrMoFoU5H/2SMFu13wI0tZayH+k0nGh0OWbx wTjtWcx1quOS5cRy2xvqqRmYvddYA8HJupQ9OTKGLoouVYSG27ky3BLt2PwxHowLqHqm 36/rnjAw3GBl9O5C3YC2voq/YPTNQYZSsBWDz+93sPFAwdRc3Ub6BWI/lAQgigJmjz5O lZA0GH8wqBHUmeBfgeAQklXJt62i1xchURucNna7ys6Ol6jpBNdTISUCqeJTXpGRtchh UIfEKvMaMukniWjwHDeeht0jC1S4nB//S1BBEpJHvLeUGnRbdwrhV5/D1PYI75b9IfA7 xoEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zHW7j8uJ1T5WAhTwDkkfCp9h9wlSajIJoR2TS5WeI4s=; b=Kh/AN5pYHLe2hDZ+pORPLM3WM8vr5vQMMNj2Uz3qWzsCtaeyxNn4VpqvRaxXC/e9KJ 2IvrV4C2ZbZikfpP4Qagl1U+ZMQn4rhVm6TUN/+pX+JIOhigPjvZLR+d8+Ot2qls8CJm 9UBmh1D3OMoZYmc8guDIPShqaN7eiVspicFN64I0/94HFGfHNTaFneMrju9BUDfMBYAq 6d2mQGZJ2gQoDRnGK6OFT6qpvBp2o8QKFRdLL4OxVMlXdJ35Svu//3FQF5NZ1bwT5KLe ZQu49uSxyw+wo6Vr35PI6bCjMco5Yux5zme/Ijt1D8eXrcffRftExBwnnzw99GneMupi dMVw== X-Gm-Message-State: AOAM533we5JKheASisrbVM4UuPc5+555yQoAHcMWykFABMufDHol4MGj mv6sJ8e0YpExrRq5Zl1f+cLPDg== X-Google-Smtp-Source: ABdhPJwzl+6gfIV47ZCHmVz5/wqhiY0aSpqI/1a5FDmoJTan/NZyyOCfBI9EfZad5k9e0Yjfqz8dWg== X-Received: by 2002:a05:651c:902:: with SMTP id e2mr790319ljq.198.1629161715773; Mon, 16 Aug 2021 17:55:15 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:15 -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: [RFC PATCH 03/15] mmc: core: switch to new pwrseq subsystem Date: Tue, 17 Aug 2021 03:54:55 +0300 Message-Id: <20210817005507.1507580-4-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Drop old MMC pwrseq code and use new pwrseq subsystem instead. Individual drivers are already ported to new subsystem. Signed-off-by: Dmitry Baryshkov --- drivers/mmc/core/Makefile | 1 - drivers/mmc/core/core.c | 9 ++- drivers/mmc/core/host.c | 8 ++- drivers/mmc/core/mmc.c | 3 +- drivers/mmc/core/pwrseq.c | 117 -------------------------------------- drivers/mmc/core/pwrseq.h | 58 ------------------- include/linux/mmc/host.h | 4 +- 7 files changed, 12 insertions(+), 188 deletions(-) delete mode 100644 drivers/mmc/core/pwrseq.c delete mode 100644 drivers/mmc/core/pwrseq.h diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 322eb69bd00e..a504d873cf8e 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -9,7 +9,6 @@ mmc_core-y := core.o bus.o host.o \ sdio.o sdio_ops.o sdio_bus.o \ sdio_cis.o sdio_io.o sdio_irq.o \ slot-gpio.o regulator.o -mmc_core-$(CONFIG_OF) += pwrseq.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o obj-$(CONFIG_MMC_BLOCK) += mmc_block.o mmc_block-objs := block.o queue.o diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 95fedcf56e4a..c468af900a45 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -41,7 +41,6 @@ #include "bus.h" #include "host.h" #include "sdio_bus.h" -#include "pwrseq.h" #include "mmc_ops.h" #include "sd_ops.h" @@ -1321,7 +1320,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) if (host->ios.power_mode == MMC_POWER_ON) return; - mmc_pwrseq_pre_power_on(host); + pwrseq_pre_power_on(host->pwrseq); host->ios.vdd = fls(ocr) - 1; host->ios.power_mode = MMC_POWER_UP; @@ -1336,7 +1335,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) */ mmc_delay(host->ios.power_delay_ms); - mmc_pwrseq_post_power_on(host); + pwrseq_power_on(host->pwrseq); host->ios.clock = host->f_init; @@ -1355,7 +1354,7 @@ void mmc_power_off(struct mmc_host *host) if (host->ios.power_mode == MMC_POWER_OFF) return; - mmc_pwrseq_power_off(host); + pwrseq_power_off(host->pwrseq); host->ios.clock = 0; host->ios.vdd = 0; @@ -1985,7 +1984,7 @@ EXPORT_SYMBOL(mmc_set_blocklen); static void mmc_hw_reset_for_init(struct mmc_host *host) { - mmc_pwrseq_reset(host); + pwrseq_reset(host->pwrseq); if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) return; diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 0475d96047c4..214b9cfda723 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -28,7 +28,6 @@ #include "crypto.h" #include "host.h" #include "slot-gpio.h" -#include "pwrseq.h" #include "sdio_ops.h" #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) @@ -413,7 +412,11 @@ int mmc_of_parse(struct mmc_host *host) device_property_read_u32(dev, "post-power-on-delay-ms", &host->ios.power_delay_ms); - return mmc_pwrseq_alloc(host); + host->pwrseq = devm_pwrseq_get_optional(dev, "mmc"); + if (IS_ERR(host->pwrseq)) + return PTR_ERR(host->pwrseq); + + return 0; } EXPORT_SYMBOL(mmc_of_parse); @@ -632,7 +635,6 @@ EXPORT_SYMBOL(mmc_remove_host); */ void mmc_free_host(struct mmc_host *host) { - mmc_pwrseq_free(host); put_device(&host->class_dev); } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 838726b68ff3..59d0d26bb5c0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -24,7 +24,6 @@ #include "mmc_ops.h" #include "quirks.h" #include "sd_ops.h" -#include "pwrseq.h" #define DEFAULT_CMD6_TIMEOUT_MS 500 #define MIN_CACHE_EN_TIMEOUT_MS 1600 @@ -2220,7 +2219,7 @@ static int _mmc_hw_reset(struct mmc_host *host) } else { /* Do a brute force power cycle */ mmc_power_cycle(host, card->ocr); - mmc_pwrseq_reset(host); + pwrseq_reset(host->pwrseq); } return mmc_init_card(host, card->ocr, card); } diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c deleted file mode 100644 index ef675f364bf0..000000000000 --- a/drivers/mmc/core/pwrseq.c +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Linaro Ltd - * - * Author: Ulf Hansson - * - * MMC power sequence management - */ -#include -#include -#include -#include - -#include - -#include "pwrseq.h" - -static DEFINE_MUTEX(pwrseq_list_mutex); -static LIST_HEAD(pwrseq_list); - -int mmc_pwrseq_alloc(struct mmc_host *host) -{ - struct device_node *np; - struct mmc_pwrseq *p; - - np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); - if (!np) - return 0; - - mutex_lock(&pwrseq_list_mutex); - list_for_each_entry(p, &pwrseq_list, pwrseq_node) { - if (p->dev->of_node == np) { - if (!try_module_get(p->owner)) - dev_err(host->parent, - "increasing module refcount failed\n"); - else - host->pwrseq = p; - - break; - } - } - - of_node_put(np); - mutex_unlock(&pwrseq_list_mutex); - - if (!host->pwrseq) - return -EPROBE_DEFER; - - dev_info(host->parent, "allocated mmc-pwrseq\n"); - - return 0; -} - -void mmc_pwrseq_pre_power_on(struct mmc_host *host) -{ - struct mmc_pwrseq *pwrseq = host->pwrseq; - - if (pwrseq && pwrseq->ops->pre_power_on) - pwrseq->ops->pre_power_on(host); -} - -void mmc_pwrseq_post_power_on(struct mmc_host *host) -{ - struct mmc_pwrseq *pwrseq = host->pwrseq; - - if (pwrseq && pwrseq->ops->post_power_on) - pwrseq->ops->post_power_on(host); -} - -void mmc_pwrseq_power_off(struct mmc_host *host) -{ - struct mmc_pwrseq *pwrseq = host->pwrseq; - - if (pwrseq && pwrseq->ops->power_off) - pwrseq->ops->power_off(host); -} - -void mmc_pwrseq_reset(struct mmc_host *host) -{ - struct mmc_pwrseq *pwrseq = host->pwrseq; - - if (pwrseq && pwrseq->ops->reset) - pwrseq->ops->reset(host); -} - -void mmc_pwrseq_free(struct mmc_host *host) -{ - struct mmc_pwrseq *pwrseq = host->pwrseq; - - if (pwrseq) { - module_put(pwrseq->owner); - host->pwrseq = NULL; - } -} - -int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) -{ - if (!pwrseq || !pwrseq->ops || !pwrseq->dev) - return -EINVAL; - - mutex_lock(&pwrseq_list_mutex); - list_add(&pwrseq->pwrseq_node, &pwrseq_list); - mutex_unlock(&pwrseq_list_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(mmc_pwrseq_register); - -void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) -{ - if (pwrseq) { - mutex_lock(&pwrseq_list_mutex); - list_del(&pwrseq->pwrseq_node); - mutex_unlock(&pwrseq_list_mutex); - } -} -EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister); diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h deleted file mode 100644 index f3bb103db9ad..000000000000 --- a/drivers/mmc/core/pwrseq.h +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2014 Linaro Ltd - * - * Author: Ulf Hansson - */ -#ifndef _MMC_CORE_PWRSEQ_H -#define _MMC_CORE_PWRSEQ_H - -#include - -struct mmc_host; -struct device; -struct module; - -struct mmc_pwrseq_ops { - void (*pre_power_on)(struct mmc_host *host); - void (*post_power_on)(struct mmc_host *host); - void (*power_off)(struct mmc_host *host); - void (*reset)(struct mmc_host *host); -}; - -struct mmc_pwrseq { - const struct mmc_pwrseq_ops *ops; - struct device *dev; - struct list_head pwrseq_node; - struct module *owner; -}; - -#ifdef CONFIG_OF - -int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq); -void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq); - -int mmc_pwrseq_alloc(struct mmc_host *host); -void mmc_pwrseq_pre_power_on(struct mmc_host *host); -void mmc_pwrseq_post_power_on(struct mmc_host *host); -void mmc_pwrseq_power_off(struct mmc_host *host); -void mmc_pwrseq_reset(struct mmc_host *host); -void mmc_pwrseq_free(struct mmc_host *host); - -#else - -static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) -{ - return -ENOSYS; -} -static inline void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) {} -static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; } -static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {} -static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {} -static inline void mmc_pwrseq_power_off(struct mmc_host *host) {} -static inline void mmc_pwrseq_reset(struct mmc_host *host) {} -static inline void mmc_pwrseq_free(struct mmc_host *host) {} - -#endif - -#endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0abd47e9ef9b..1673e37f6028 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -16,6 +16,7 @@ #include #include #include +#include struct mmc_ios { unsigned int clock; /* clock rate */ @@ -278,7 +279,6 @@ struct mmc_context_info { }; struct regulator; -struct mmc_pwrseq; struct mmc_supply { struct regulator *vmmc; /* Card power supply */ @@ -294,7 +294,7 @@ struct mmc_host { struct device class_dev; int index; const struct mmc_host_ops *ops; - struct mmc_pwrseq *pwrseq; + struct pwrseq *pwrseq; unsigned int f_min; unsigned int f_max; unsigned int f_init; From patchwork Tue Aug 17 00:54:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05132C43216 for ; Tue, 17 Aug 2021 00:56:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCAE360EE0 for ; Tue, 17 Aug 2021 00:56:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237706AbhHQA46 (ORCPT ); Mon, 16 Aug 2021 20:56:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235784AbhHQAzu (ORCPT ); Mon, 16 Aug 2021 20:55:50 -0400 Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 509BDC0613CF for ; Mon, 16 Aug 2021 17:55:18 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id d16so11985964ljq.4 for ; Mon, 16 Aug 2021 17:55: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=wdu5a/cMDbATqqiF4Vpee9GEfvuO3Zi0W+N+1NhGvAs=; b=KadqBNUFvId8+sROkIoWW2FnIiISPA/xpZWhqmtLgHDQHk5ltVM9Jgu60gY6RHkhhU LxZfK3sQvb2jKcgpbunWaDbUXqzuuNAoBiRd/+aZ6ZlKUbctO+qgDzwoU8spR3DMw9/R 2ErU12GwvauMTdGSM+eBF1gUNlVHdg+JTKJ6WJ6UIq9jrevyeoLYCbT8n83RcBz5AgPA 7ITGMU2aIZBqx+9cPVoj5uPuPEyFDbj3EsmIoCMwaCeme7ugesPolg0LvwnnyEYGVBd0 HQkA6lOYvqUppAIJVQdlmtl51ODC6UeKWmNnXFk6X9c90iuFUn3oHF9d1QqEl3AV1jCG 13Gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wdu5a/cMDbATqqiF4Vpee9GEfvuO3Zi0W+N+1NhGvAs=; b=P+cQV4QPSBvJhBMrkpHYkVj2JTl1nWpQHom0WxB2cLHD9p+GMbrkt9DKKDlFzxyTlb TmzD9zI9G59B77HOiebP3PB0Ew8kUXEk2C/zzeqKG4HkjHgS+LECmy4IA3GxvNnP+EFz bnTWqHGS/SSj8RsFy99cFNR/Fc5XBb+8FFitCA36nSonMN4t6hfGjLAQX7XETAfB0iQB 39O0bJiFxL5+3Ja1OyRTrP77T63pE1HY7hZpYHORU2HBhbCdfYbDGRUD8ISxiS3+DuO7 zM31iVUpLlmZVdnNgC5QTI3MT5lprpy1olFB+eG5hsRrgHGonKVmANNwaL07tXXMSk1Y 8j4Q== X-Gm-Message-State: AOAM531ji4twGcuovFHesNEyOJ6szkrZ1v+kJATWPRg/bEL7QT/aHSZ4 cFkcVCrf3OAAjp6nxaVLsj3G6g== X-Google-Smtp-Source: ABdhPJyykVmUp2+uL524zpEVpdzv1pv0gVNB4w0uBgg1/3eS2V8TRDR8U1hnV+vjiLEctppv61IqLQ== X-Received: by 2002:a05:651c:1257:: with SMTP id h23mr769675ljh.49.1629161716645; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55: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: [RFC PATCH 04/15] ath10k: add support for pwrseq sequencing Date: Tue, 17 Aug 2021 03:54:56 +0300 Message-Id: <20210817005507.1507580-5-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Power sequencing for Qualcomm WiFi+BT chipsets are being reworked to use pwrseq rather than individually handling all the regulators. Add support for pwrseq to ath10k SNOC driver. Signed-off-by: Dmitry Baryshkov --- drivers/net/wireless/ath/ath10k/snoc.c | 63 ++++++++++++++++++++------ drivers/net/wireless/ath/ath10k/snoc.h | 2 + 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index ea00fbb15601..870ed28d01a6 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "ce.h" #include "coredump.h" @@ -42,7 +43,6 @@ static char *const ce_name[] = { }; static const char * const ath10k_regulators[] = { - "vdd-0.8-cx-mx", "vdd-1.8-xo", "vdd-1.3-rfa", "vdd-3.3-ch0", @@ -1010,10 +1010,17 @@ static int ath10k_hw_power_on(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); - ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); + if (ar_snoc->pwrseq) + ret = pwrseq_full_power_on(ar_snoc->pwrseq); + else + ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); if (ret) return ret; + ret = regulator_enable(ar_snoc->vreg_cx_mx); + if (ret) + goto vreg_bulk_off; + ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); if (ret) goto vreg_off; @@ -1021,7 +1028,13 @@ static int ath10k_hw_power_on(struct ath10k *ar) return ret; vreg_off: - regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); + regulator_disable(ar_snoc->vreg_cx_mx); +vreg_bulk_off: + if (ar_snoc->pwrseq) + pwrseq_power_off(ar_snoc->pwrseq); + else + regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); + return ret; } @@ -1033,6 +1046,14 @@ static int ath10k_hw_power_off(struct ath10k *ar) clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); + regulator_disable(ar_snoc->vreg_cx_mx); + + if (ar_snoc->pwrseq) { + pwrseq_power_off(ar_snoc->pwrseq); + + return 0; + } + return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); } @@ -1691,20 +1712,36 @@ static int ath10k_snoc_probe(struct platform_device *pdev) goto err_release_resource; } - ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); - ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs, - sizeof(*ar_snoc->vregs), GFP_KERNEL); - if (!ar_snoc->vregs) { - ret = -ENOMEM; + ar_snoc->pwrseq = devm_pwrseq_get_optional(&pdev->dev, "wifi"); + if (IS_ERR(ar_snoc->pwrseq)) { + ret = PTR_ERR(ar_snoc->pwrseq); + if (ret != -EPROBE_DEFER) + ath10k_warn(ar, "failed to acquire pwrseq: %d\n", ret); goto err_free_irq; } - for (i = 0; i < ar_snoc->num_vregs; i++) - ar_snoc->vregs[i].supply = ath10k_regulators[i]; - ret = devm_regulator_bulk_get(&pdev->dev, ar_snoc->num_vregs, - ar_snoc->vregs); - if (ret < 0) + if (!ar_snoc->pwrseq) { + ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); + ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs, + sizeof(*ar_snoc->vregs), GFP_KERNEL); + if (!ar_snoc->vregs) { + ret = -ENOMEM; + goto err_free_irq; + } + for (i = 0; i < ar_snoc->num_vregs; i++) + ar_snoc->vregs[i].supply = ath10k_regulators[i]; + + ret = devm_regulator_bulk_get(&pdev->dev, ar_snoc->num_vregs, + ar_snoc->vregs); + if (ret < 0) + goto err_free_irq; + } + + ar_snoc->vreg_cx_mx = devm_regulator_get(&pdev->dev, "vdd-0.8-cx-mx"); + if (IS_ERR(ar_snoc->vreg_cx_mx)) { + ret = PTR_ERR(ar_snoc->vreg_cx_mx); goto err_free_irq; + } ar_snoc->num_clks = ARRAY_SIZE(ath10k_clocks); ar_snoc->clks = devm_kcalloc(&pdev->dev, ar_snoc->num_clks, diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h index 5095d1893681..16cfd72180cd 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.h +++ b/drivers/net/wireless/ath/ath10k/snoc.h @@ -72,8 +72,10 @@ struct ath10k_snoc { struct timer_list rx_post_retry; struct regulator_bulk_data *vregs; size_t num_vregs; + struct regulator *vreg_cx_mx; struct clk_bulk_data *clks; size_t num_clks; + struct pwrseq *pwrseq; struct ath10k_qmi *qmi; unsigned long flags; bool xo_cal_supported; From patchwork Tue Aug 17 00:54:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439551 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31212C19F39 for ; Tue, 17 Aug 2021 00:55:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1725F6044F for ; Tue, 17 Aug 2021 00:55:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236733AbhHQA4I (ORCPT ); Mon, 16 Aug 2021 20:56:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235487AbhHQAzv (ORCPT ); Mon, 16 Aug 2021 20:55:51 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1686BC0613A4 for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id x7so30109856ljn.10 for ; Mon, 16 Aug 2021 17:55: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=qJ5eiPWaLvWUNxF9WbotbzWszu9llFOajdlXgdOU7d0=; b=qMAiUgEGNh+9rlauuO1jEMSV8lgH5wtHqDnO1B0ckyR/jLV2muMdSXsRMwgzqmcn05 m59J6xNAKDhl6kmrHHmie1HaxTIuUhvFdFHqfw+GUhBoEbR5Yp7bnTYpu1kkOetHKFCw 2ikcgMCkNDkIzXKQBmN/Pu15kh6MULoZ4GM20FeWdFh++3Hs8Q1ZaA/t//MD6e4BoE4W 9oo6yiYO3a74WGzwgz9Rm2jMI1OSavobPI+ziU33bcl5xuzoZmd8UQvxDuPZZIaiO0Q6 CyBN0bIZ6vrzOlnRYOG/YApJ6LFUTNeyLDxLILpZhMcI5+xFPOKJlSoaIzbQ+PXUnQ1t 1sqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qJ5eiPWaLvWUNxF9WbotbzWszu9llFOajdlXgdOU7d0=; b=juanr0QIEOB8TKpAkiOihQuE7b3LByDPKc99ist23dl3vvVSa0YVT/CWDLzgxC00lH JNsMf3Orp3bR42brtZX3HlyLb/FWJuO0/0IlsC3GfSyY0r5NtXG0toz6NEst7TGi3h8Y 1EkPKgUxD/63lm6Kip4e6Z/ywSankfwCTu309/wpbO/j3IpZf0wO83O0AxROqMQjMy5+ bqJAocSAlNhs3nm2LsvIGsH7U4GiOh9fj6g/irQvWlSB2Z5gIg6xBtJvRZL1VQu9sWA4 AMZb2Zfx0s+oPXX5g5RtXbFB4FtR+wQF4fkStb6yiU0B4mlLHbw1yBj6FHC82Enh26XZ /OBA== X-Gm-Message-State: AOAM5302Xjb4/h5Z9TsaW8IfyAnEiKolkBYxu/LlZeFqBBtlTqTiAkZq fUee1oyexfXZrXetVED8Fn4zBw== X-Google-Smtp-Source: ABdhPJzGmIlWBq0I5j5m1JI2zbtOW50H9nlDmsNz7c6bsSxYOPOHpku/kkRIXTEliyjxJIRth96PwA== X-Received: by 2002:a2e:bd11:: with SMTP id n17mr785200ljq.480.1629161717429; Mon, 16 Aug 2021 17:55:17 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:17 -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: [RFC PATCH 05/15] Bluetooth: hci_qca: merge qca_power into qca_serdev Date: Tue, 17 Aug 2021 03:54:57 +0300 Message-Id: <20210817005507.1507580-6-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org There is no need to separate struct qca_power from the rest of struct qca_serdev. Squash qca_power into the main struct, to simplify the driver. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 60 +++++++++++++------------------------ 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 53deea2eb7b4..a21cec44720a 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -205,23 +205,15 @@ struct qca_device_data { 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 regulator_bulk_data *vreg_bulk; + int num_vregs; + bool vregs_on; u32 init_speed; u32 oper_speed; const char *firmware_name; @@ -1602,7 +1594,7 @@ static int qca_regulator_init(struct hci_uart *hu) * 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) @@ -1940,20 +1932,19 @@ 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 %d regulators)", qcadev->num_vregs); - ret = regulator_bulk_enable(power->num_vregs, power->vreg_bulk); + ret = regulator_bulk_enable(qcadev->num_vregs, qcadev->vreg_bulk); if (ret) return ret; - power->vregs_on = true; + qcadev->vregs_on = true; ret = clk_prepare_enable(qcadev->susclk); if (ret) @@ -1964,38 +1955,34 @@ static int qca_regulator_enable(struct qca_serdev *qcadev) 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; + regulator_bulk_disable(qcadev->num_vregs, qcadev->vreg_bulk); + qcadev->vregs_on = false; clk_disable_unprepare(qcadev->susclk); } -static int qca_init_regulators(struct qca_power *qca, +static int qca_init_regulators(struct qca_serdev *qcadev, struct device *dev, 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); + bulk = devm_kcalloc(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); + ret = devm_regulator_bulk_get(dev, num_vregs, bulk); if (ret < 0) return ret; @@ -2005,8 +1992,8 @@ static int qca_init_regulators(struct qca_power *qca, return ret; } - qca->vreg_bulk = bulk; - qca->num_vregs = num_vregs; + qcadev->vreg_bulk = bulk; + qcadev->num_vregs = num_vregs; return 0; } @@ -2037,21 +2024,15 @@ static int qca_serdev_probe(struct serdev_device *serdev) (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, + + err = qca_init_regulators(qcadev, &serdev->dev, data->vregs, data->num_vregs); if (err) { BT_ERR("Failed to init regulators:%d", err); return err; } - qcadev->bt_power->vregs_on = false; + qcadev->vregs_on = false; qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); @@ -2135,11 +2116,10 @@ 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); From patchwork Tue Aug 17 00:54: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: 12439553 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB0ADC41537 for ; Tue, 17 Aug 2021 00:55:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D296F60C40 for ; Tue, 17 Aug 2021 00:55:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236665AbhHQA4H (ORCPT ); Mon, 16 Aug 2021 20:56:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235960AbhHQAzw (ORCPT ); Mon, 16 Aug 2021 20:55:52 -0400 Received: from mail-lj1-x236.google.com (mail-lj1-x236.google.com [IPv6:2a00:1450:4864:20::236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D111FC0612A5 for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x236.google.com with SMTP id s3so1080086ljp.11 for ; Mon, 16 Aug 2021 17:55:19 -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=Cz2cdyq9bfTQbWydu62Y30PBEuomfVq7X4iE+OcyqAc=; b=DXOv9zywG0v5J0JH95Tt8TXDFmxZ6qUNwRVvFf1Uj2RpuzZM0XTVLTllvnNUBCs5H3 3DzQPj2wZI5FFR1EGWl7Ywp1K4Yg0kiYXVj3OOYLfrAsJ+/BX5wxCKKwzBu6wDNYhPOB b1jW+JPrFTFUd+2q/QG4OfBeFr8WCXCuuiLfHKmwqvokiQH1V9qfUHnygHfFJDQu2Aif Klla4JwL9uV1qHozO8/8WweWpBiTBoF/QuXen8Miu0ssquD2cNiI5GJEkPjqLw6gFoNi XWPm1vyRP01A1mAfNnH9mQuLaimALgKU+u9BRppYw2UuwHDQ6Vu5l8Li9/pSxjsuWWu1 Zgrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Cz2cdyq9bfTQbWydu62Y30PBEuomfVq7X4iE+OcyqAc=; b=Ll0wcOEKmELUY6yhEpl1VGYB7suMpXzVTalne2ofW634SWDJ0eV5AIbdFmJzklHG1A xnzKoJLCYI+DaQ/SuiAbAbvhm88CcYLWdhW45aoWPXdENlEA9D8P1A788fwm8uzMHOzj YD0yzG1ZTVu49HJjlsaBu6Yk83b6wQj1m48wVX9oPKQtZPa7cl2En+lB7gFBjLya7/y9 GDuNykHzQhQoNooIwW3VNHPb61AI75hIWG7AiG2VhJ6AQZXbQG85aUwXrHhdpVx70fIx rrFvPRUNku4Rgi4SQzP5rrw8W65FzW8+nfXslhVOHZBzTbT181du+l1yDoBO8di/4Tyn nXyw== X-Gm-Message-State: AOAM532H0ha/QCZP4b9Hc4zjA1JuXJOZJ269uSKJYXtrRmNC91x3BS0O Zi3C+jnTA375hVrlDn1tD8mELA== X-Google-Smtp-Source: ABdhPJxjM9khOl2mTz77h1I67+yFB2G6eXp+QyBPa0lv71WVFHCclb5KEzUp1athAqLgve0EIpTp+w== X-Received: by 2002:a2e:b8c5:: with SMTP id s5mr796868ljp.36.1629161718233; Mon, 16 Aug 2021 17:55:18 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:17 -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: [RFC PATCH 06/15] Bluetooth: hci_qca: merge init paths Date: Tue, 17 Aug 2021 03:54:58 +0300 Message-Id: <20210817005507.1507580-7-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org The hci_qca driver has almost identical init paths. Merge them together to remove duplication in preparation to adding power sequencer support. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 76 ++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index a21cec44720a..279b802f0952 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2020,11 +2020,12 @@ 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))) { + if (data) qcadev->btsoc_type = data->soc_type; + else + qcadev->btsoc_type = QCA_ROME; + if (data && data->num_vregs) { err = qca_init_regulators(qcadev, &serdev->dev, data->vregs, data->num_vregs); if (err) { @@ -2033,48 +2034,33 @@ static int qca_serdev_probe(struct serdev_device *serdev) } qcadev->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) { + qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", + GPIOD_OUT_LOW); + if (!qcadev->bt_en) { + if (qca_is_wcn6750(data->soc_type)) { 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; - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (!qcadev->bt_en) { + } else if (!qca_is_wcn399x(data->soc_type)) { dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); power_ctrl_enabled = 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); - } + qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", + GPIOD_IN); + if (!qcadev->sw_ctrl && qca_is_wcn6750(data->soc_type)) + 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); + } + + if (!qca_is_wcn399x(data->soc_type) && + !qca_is_wcn6750(data->soc_type)) { err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); if (err) return err; @@ -2082,13 +2068,17 @@ static int qca_serdev_probe(struct serdev_device *serdev) 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"); + err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); + if (err) { + BT_ERR("QCA serdev registration failed"); + + if (!qca_is_wcn399x(data->soc_type) && + !qca_is_wcn6750(data->soc_type)) clk_disable_unprepare(qcadev->susclk); - return err; - } + + return err; } hdev = qcadev->serdev_hu.hdev; From patchwork Tue Aug 17 00:54:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439549 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92191C4338F for ; Tue, 17 Aug 2021 00:55:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7D3FA60184 for ; Tue, 17 Aug 2021 00:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236623AbhHQA4H (ORCPT ); Mon, 16 Aug 2021 20:56:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235974AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -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 9E411C0613C1 for ; Mon, 16 Aug 2021 17:55:20 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id i9so17306133lfg.10 for ; Mon, 16 Aug 2021 17:55:20 -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=/8xXh4uAYLmC7B9Fj6XTx3aEzPEiY8DHDrOWM6RLdAY=; b=XT63hjpTOqal34rG4WIVTZFSl+hNwylMZJ6S2NC8YTo9uxqLGQKO6SvPZQBQbcNhjB u8LEZMD4oFHnetVUjrHH0NqAeNbv1CgPOo4zlrPobiGRBJX0qAQ11Oy2FqrT720M9934 C+Vy4UecnQKRS6gyDDrnXlxbicjJxVLKtQyNqEGfxxcgcg9cr+UWCDGUrWFZq2bWUkuW x9bYMO+fSsZhwvzSDGTtzGG979snI6EXtQHYLXsiyQZgelrJQUvmGxST9h5uszdIilKj uKaaFsBEe/djtWOHnWt5p17myYUs0gmn6eOMOKlJaVb1XV0Ko6nxYbe3qpxrY/T3FgC5 tYYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/8xXh4uAYLmC7B9Fj6XTx3aEzPEiY8DHDrOWM6RLdAY=; b=Uz+Bio4b67mXlqk4LsXUxaPrHNjIMTawyNLvTRQLMwm+GSiI0jKYvfYYRSBW3DR+9O Nz4Ur4aS8KKPccs4nOFtgKBufIL8139/ynx7mOYmAvrOplOVsnB/A3CAjceqorIrxfU6 i09u8vpqfhndK7g1BILGacAquwnGVEIE0JOZ5IAYR2wnd+7BgQIRvnjEWlvoPmWFyvhR o8SnQTPeXJI2CAt3uAk3L2NDACNUBUhnC+rWkicRYrhnpQxkRjfJ+2e8UfizvLxo/u6n pl02atvw4Jpap5guoWCiK60U87ofUoZvLbT2nzNr1gNsI3Im9mY3tSHGmdo0hI71uJ6T E3YA== X-Gm-Message-State: AOAM531sAfiAHeUvlJHhzzJ5HaPpd0vRZLaJdWND1tRQimGvc9ZQQRNc Rt4PP20ZKcige7PLXbKAz8vbYA== X-Google-Smtp-Source: ABdhPJyZ0zGdRSpfLJNcqsKT1e5xL6W6PntlPXhz2BykpLrQMBmSIjUKGP66GrGiWhrsFuR+5YQ2RA== X-Received: by 2002:a05:6512:3041:: with SMTP id b1mr414095lfb.122.1629161719017; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55: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: [RFC PATCH 07/15] Bluetooth: hci_qca: merge qca_power_on with qca_regulators_init Date: Tue, 17 Aug 2021 03:54:59 +0300 Message-Id: <20210817005507.1507580-8-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org With wcn6750 support added, regulator-based code was extended with the bt_en gpio support. Now there is no need to keep regulator and non-regulator code paths separate. Merge both code paths. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 64 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 279b802f0952..ad7e8cdc94f3 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1583,13 +1583,21 @@ static bool qca_prevent_wake(struct hci_dev *hdev) return !wakeup; } -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; bool sw_ctrl_state; + /* Non-serdev device usually is powered by external power + * and don't need additional action in driver for power on + */ + if (!hu->serdev) + return 0; + /* Check for vregs status, may be hci down has turned * off the voltage regulator. */ @@ -1607,27 +1615,29 @@ static int qca_regulator_init(struct hci_uart *hu) } } - if (qca_is_wcn399x(soc_type)) { - /* Forcefully enable wcn399x to enter in to boot mode. */ - host_set_baudrate(hu, 2400); - ret = qca_send_power_pulse(hu, false); - if (ret) - 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); + msleep(150); 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)) { + /* Forcefully enable wcn399x to enter in to boot mode. */ + host_set_baudrate(hu, 2400); + ret = qca_send_power_pulse(hu, false); + if (ret) + return ret; + } + + 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); @@ -1647,38 +1657,12 @@ static int qca_regulator_init(struct hci_uart *hu) return ret; } - hci_uart_set_flow_control(hu, false); - - return 0; -} - -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; - - /* Non-serdev device usually is powered by external power - * and don't need additional action in driver for power on - */ - 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); - } - } + qca_is_wcn6750(soc_type)) + hci_uart_set_flow_control(hu, false); clear_bit(QCA_BT_OFF, &qca->flags); + return ret; } From patchwork Tue Aug 17 00:55:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439547 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAD68C432BE for ; Tue, 17 Aug 2021 00:55:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A0B2160C40 for ; Tue, 17 Aug 2021 00:55:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236010AbhHQA4G (ORCPT ); Mon, 16 Aug 2021 20:56:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236043AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 705AFC06124C for ; Mon, 16 Aug 2021 17:55:21 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id n7so30226010ljq.0 for ; Mon, 16 Aug 2021 17:55: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=7qagkQtaTlZmPxAEgYPi9rpyWnwBJTQJebKsAKhdvfc=; b=bPom6hkXdRt2fzsZMrGQmnn9MtSyxylCOyNHRvgpVhawiJNrQh6QUqc9ih5gcp1PF6 x7+c0V9DfcVHe25Z00kgH9T2ng5nSvCBz+o704oipZiwi9g3Q79aomTtYCVE5rKr2XID isIpULaSopsDHVzvsUaGca7+jYh21REPOXKcvjZZGkmiuKDdDMalE24Btv637HBybtde t/oUVFkzkQdO3xkPAa1rKVrvYHSiS5YVlrimA71K0GOp0sLQSWff7XvQCNLH8ZIoI4OM Vibzz8QCOKSRXuoZjssW8pbA1Sg2PRC097Zq5t0AlYgDWr4OE5w7ViGN5v013nB2yfv5 yl8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7qagkQtaTlZmPxAEgYPi9rpyWnwBJTQJebKsAKhdvfc=; b=Bsq5F/5aAUAUEXszmK7zbj0YtFntFBNW+aagEr09Ic3DrFfQhBQ8QappgPWMX9u/B1 AfO/aRxtQzffOxGB9IY0V4hO6rEthInHguTZa+ZN7HJVlkD50n3e6QU1w2qTz+ro5YFE EZtRMGFxw4MJzdmvn7gMpsZ5vL61V6DV/pAnea4dwGr2hfGR7kDjZRcSGhhlhd40+v6/ 3SBpt8KqTLD8w1keiewYXl1vEXVFdVdmeMnoyLQScYkEmzFcVBE6dXK3sA/5RMj3uF/f k2HbFI5IMXxYZX3tof43BLJJA2Qolk2qYH9u6vl7sRU9RGFBCePsbjmQi6EU0UHJ8sI5 68JQ== X-Gm-Message-State: AOAM530ZiR0C0VQoCLoRBDd+vbbDIJBk9FNUK0fIVFI0zE0RLRbOmTl6 IJIRODI41ZFaAPwtKdUoLp0r4g== X-Google-Smtp-Source: ABdhPJy0Vxzbay2lg9uLfmPVEif7TuCf//2e8I2PdIm8X8c7CC97prs3p0qNiSFLC6TRElLB99wqvQ== X-Received: by 2002:a2e:9751:: with SMTP id f17mr777675ljj.422.1629161719792; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:19 -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: [RFC PATCH 08/15] Bluetooth: hci_qca: futher rework of power on/off handling Date: Tue, 17 Aug 2021 03:55:00 +0300 Message-Id: <20210817005507.1507580-9-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Further rework of power on/off handling. Move bt_en and sw_ctl handling close to regulator enable/disable, so that this code can be easily extended with pwrseq support. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 126 +++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index ad7e8cdc94f3..2d23e8a3ca14 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1590,7 +1590,6 @@ static int qca_power_on(struct hci_dev *hdev) struct qca_serdev *qcadev; struct qca_data *qca = hu->priv; int ret; - bool sw_ctrl_state; /* Non-serdev device usually is powered by external power * and don't need additional action in driver for power on @@ -1602,29 +1601,15 @@ static int qca_power_on(struct hci_dev *hdev) * off the voltage regulator. */ qcadev = serdev_device_get_drvdata(hu->serdev); - if (!qcadev->vregs_on) { - serdev_device_close(hu->serdev); - ret = qca_regulator_enable(qcadev); - if (ret) - return ret; - - ret = serdev_device_open(hu->serdev); - if (ret) { - bt_dev_err(hu->hdev, "failed to open port"); - return ret; - } - } + serdev_device_close(hu->serdev); + ret = qca_regulator_enable(qcadev); + if (ret) + 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(150); - 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); - } + ret = serdev_device_open(hu->serdev); + if (ret) { + bt_dev_err(hu->hdev, "failed to open port"); + return ret; } if (qca_is_wcn399x(soc_type)) { @@ -1856,7 +1841,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 @@ -1878,18 +1862,8 @@ 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); } @@ -1919,20 +1893,39 @@ static int qca_regulator_enable(struct qca_serdev *qcadev) int ret; /* Already enabled */ - if (qcadev->vregs_on) - return 0; + if (!qcadev->vregs_on) { + BT_DBG("enabling %d regulators)", qcadev->num_vregs); - BT_DBG("enabling %d regulators)", qcadev->num_vregs); + ret = regulator_bulk_enable(qcadev->num_vregs, qcadev->vreg_bulk); + if (ret) + return ret; - ret = regulator_bulk_enable(qcadev->num_vregs, qcadev->vreg_bulk); - if (ret) - return ret; + qcadev->vregs_on = true; - qcadev->vregs_on = true; + if (qca_is_wcn399x(qcadev->btsoc_type) || + qca_is_wcn6750(qcadev->btsoc_type)) { + ret = clk_prepare_enable(qcadev->susclk); + if (ret) { + regulator_bulk_disable(qcadev->num_vregs, qcadev->vreg_bulk); + return ret; + } + } + } - ret = clk_prepare_enable(qcadev->susclk); - if (ret) - qca_regulator_disable(qcadev); + /* 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(150); + } + + if (qcadev->sw_ctrl) { + bool sw_ctrl_state; + + sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); + bt_dev_dbg(qcadev->serdev_hu.hdev, "SW_CTRL is %d", sw_ctrl_state); + } return ret; } @@ -1942,14 +1935,27 @@ static void qca_regulator_disable(struct qca_serdev *qcadev) if (!qcadev) return; + if (qcadev->bt_en) { + gpiod_set_value_cansleep(qcadev->bt_en, 0); + msleep(100); + } + /* Already disabled? */ - if (!qcadev->vregs_on) - return; + if (qcadev->vregs_on) { + regulator_bulk_disable(qcadev->num_vregs, qcadev->vreg_bulk); + qcadev->vregs_on = false; - regulator_bulk_disable(qcadev->num_vregs, qcadev->vreg_bulk); - qcadev->vregs_on = false; + if (qca_is_wcn399x(qcadev->btsoc_type) || + qca_is_wcn6750(qcadev->btsoc_type)) + clk_disable_unprepare(qcadev->susclk); + } + + if (qcadev->sw_ctrl) { + bool sw_ctrl_state; - clk_disable_unprepare(qcadev->susclk); + sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); + bt_dev_dbg(qcadev->serdev_hu.hdev, "SW_CTRL is %d", sw_ctrl_state); + } } static int qca_init_regulators(struct qca_serdev *qcadev, struct device *dev, @@ -2018,17 +2024,17 @@ static int qca_serdev_probe(struct serdev_device *serdev) } qcadev->vregs_on = false; - } - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (!qcadev->bt_en) { - if (qca_is_wcn6750(data->soc_type)) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - power_ctrl_enabled = false; - } else if (!qca_is_wcn399x(data->soc_type)) { - dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); - power_ctrl_enabled = false; + qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", + GPIOD_OUT_LOW); + if (!qcadev->bt_en) { + if (qca_is_wcn6750(data->soc_type)) { + dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); + power_ctrl_enabled = false; + } else if (!qca_is_wcn399x(data->soc_type)) { + dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); + power_ctrl_enabled = false; + } } } From patchwork Tue Aug 17 00:55: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: 12439571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FF0CC3F6A3 for ; Tue, 17 Aug 2021 00:56:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6749860E78 for ; Tue, 17 Aug 2021 00:56:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237406AbhHQA47 (ORCPT ); Mon, 16 Aug 2021 20:56:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236121AbhHQAzz (ORCPT ); Mon, 16 Aug 2021 20:55:55 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 336D2C0611C2 for ; Mon, 16 Aug 2021 17:55:22 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id q21so8573292ljj.6 for ; Mon, 16 Aug 2021 17:55:22 -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=osWd7o/rbNiDPvWTS+l0GmKDa+5+wAZOkcYrzBBA3b8=; b=lT5ChW9T1u195uYv4Esr58dfWbudSm+C+kKwpf9Lruop4z4jZ6yU7Ttg9iNOslMEl1 oBIrCmYc74WXZoj21FXZG3tPQJyveSrh3Y0P5uLh9Yzj81tKblayMrjJH11cc3CMi8iY 6JCW94lFgA93lhEAZuZJbU5TlePL3EYs9PoOfiJv2rXd1rb9Dqbj4ZhlTpm1uAkMnDCZ 2ria0E26+y7SN+qI5WoqxXgtjfINcQftMJIonKwmrtKYVykoASrT298MBPclrLJuia9V moSbwQz/KefZctVj3YxvN0y4HmHsoKXCExcUs1nfkKesvsCiD+WzeSBD9/2LPA64+n7u hLZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=osWd7o/rbNiDPvWTS+l0GmKDa+5+wAZOkcYrzBBA3b8=; b=bIzcG6gpIuym27ko9oy2eD+zGMTRM/u5emfMA4XadqM2gIQUfrmna1iRpXQXd6D6Kp ci3grGptZ+OiPsjkjkCCg/KW5qmi7/MTRXKIs+wgNXoJwaeBN2iOJMtRxJ5CyKqpvAK3 Gx3Z/o0yuC5CA6YYMdDE01Q1Q7kNk9NeHk5T6SBRLMoHjQZilhPOr3iKcB1hxeLhNoIq c8Yb3hn5JIFzFbJYh25H0u3W1RKOIanAVyyx9whHyd67g0IUvuJkVhahdW3JTluXRq4Z 9sUQ4KpI9oYsE969cgz9+yPdIBToELdTCvs7OmE2rgd8tci1tC+HxsIN3ubgbq68vJWW sijg== X-Gm-Message-State: AOAM531iM0bdGUHW0Wl50pKbQbElAF13vBYq92I0eMqok0/l+3efHwIx 2pl3nWdaRSP1WcSUE0ckNTpxyA== X-Google-Smtp-Source: ABdhPJz0uYwW8+HUPLaLEIGd3/MVOQML6ZV+enuZ/lIlsO1SnklxizPta3pJuzgtBrngpxzwl2Cuyg== X-Received: by 2002:a2e:9a50:: with SMTP id k16mr793082ljj.308.1629161720605; Mon, 16 Aug 2021 17:55:20 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:20 -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: [RFC PATCH 09/15] Bluetooth: hci_qca: add support for pwrseq Date: Tue, 17 Aug 2021 03:55:01 +0300 Message-Id: <20210817005507.1507580-10-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Support using pwrseq for powering up and down the QCA BT chips. Signed-off-by: Dmitry Baryshkov --- drivers/bluetooth/hci_qca.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 2d23e8a3ca14..a908a952c0ef 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -211,6 +212,7 @@ struct qca_serdev { struct gpio_desc *sw_ctrl; struct clk *susclk; enum qca_btsoc_type btsoc_type; + struct pwrseq *pwrseq; struct regulator_bulk_data *vreg_bulk; int num_vregs; bool vregs_on; @@ -1602,7 +1604,10 @@ static int qca_power_on(struct hci_dev *hdev) */ qcadev = serdev_device_get_drvdata(hu->serdev); serdev_device_close(hu->serdev); - ret = qca_regulator_enable(qcadev); + if (qcadev->pwrseq) + ret = pwrseq_full_power_on(qcadev->pwrseq); + else + ret = qca_regulator_enable(qcadev); if (ret) return ret; @@ -1863,7 +1868,10 @@ static void qca_power_shutdown(struct hci_uart *hu) host_set_baudrate(hu, 2400); qca_send_power_pulse(hu, false); } - qca_regulator_disable(qcadev); + if (qcadev->pwrseq) + pwrseq_power_off(qcadev->pwrseq); + else + qca_regulator_disable(qcadev); set_bit(QCA_BT_OFF, &qca->flags); } @@ -2015,7 +2023,15 @@ static int qca_serdev_probe(struct serdev_device *serdev) else qcadev->btsoc_type = QCA_ROME; - if (data && data->num_vregs) { + qcadev->pwrseq = devm_pwrseq_get_optional(&serdev->dev, "bt"); + if (IS_ERR(qcadev->pwrseq)) { + err = PTR_ERR(qcadev->pwrseq); + BT_ERR("Failed to init regulators:%d", err); + return err; + + } + + if (!qcadev->pwrseq && data && data->num_vregs) { err = qca_init_regulators(qcadev, &serdev->dev, data->vregs, data->num_vregs); if (err) { From patchwork Tue Aug 17 00:55:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93593C00144 for ; Tue, 17 Aug 2021 00:56:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7DF2360295 for ; Tue, 17 Aug 2021 00:56:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237753AbhHQA47 (ORCPT ); Mon, 16 Aug 2021 20:56:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235755AbhHQAzz (ORCPT ); Mon, 16 Aug 2021 20:55:55 -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 01E62C061764 for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lf1-x133.google.com with SMTP id z2so38112646lft.1 for ; Mon, 16 Aug 2021 17:55:22 -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=OyMcME5CPxd5fEDXOPivzdNGVP2TOxFQZsKew1Sf58Y=; b=Czi0W4Nhq43NtkSUG+X51s0lmTQg+bbrUi1EttZ1loEmsFgomXBNVuPFl0Q1mjvkTA KGBVpKs4/A8VK1L37AQqiD0bc20FrR03junR3sQHmXqoA1Nt1Jpmfw11JC9NvOtp3Y1/ mOFcmbn8lfJ+NCdLUu3dVhA4C5gsVhPkkQw6Kyfv+fFhblpU/ZwqwJ+UZ8pkAzHH9+63 SO/x5NmnKniSGedqUC03UzH0e8TrsJEk9Cjkhu/57I5wUkHk+SHWL91LJaXjlinhWGT3 NqWEeXCvuSiwUYiDmjUhux67G34rqEd8OubHTffuxitjc88jxy+yPM/ERVT19tii2idL KpGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OyMcME5CPxd5fEDXOPivzdNGVP2TOxFQZsKew1Sf58Y=; b=nMNNQWGFCO7mr+xR2wkWEg7JXkanyjTRTBrNTgrQJ07tCfqc0HMoeIivqZRLg3WOvl wOKHy848hRTCRL9MLo+E9kjMduMM+pT3xI2FnR9cXzeRF32EJD+JtN46B7x/tPNhkOVS NhVT3nSfobKVW0EDMy3/BePUSDeWmU5eskKnqoenIiATmMVqGs07LeY8IdhRxOyC7MAn cUEEZfoDjEK6WzxP3S873vfTgHHiMVWKniirSErHy+L1JrvKuH2vbDLpu4u8rZPKw6Vb DXXKbJW3euctdsvA4M0O1jXqypuFi310iXti2KjhbVuisioUSZrZMYGP7zYjxFpgE+iu tAfA== X-Gm-Message-State: AOAM5316Kptss4HOqthxGGCISdGpDc+65XZxxllTAjIvlhRnIWrRWeId c1eehX6fec4VYYq4zkNT2+BpEw== X-Google-Smtp-Source: ABdhPJzlD7npfSA11fru0oQjFEQU2xdEJ1zr2fVBLDpj54foXqcHc0pnM+9JI8M/ZAGlr6Km3w2I+Q== X-Received: by 2002:a05:6512:98c:: with SMTP id w12mr406590lft.638.1629161721349; Mon, 16 Aug 2021 17:55:21 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:21 -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: [RFC PATCH 10/15] pwrseq: add support for QCA BT+WiFi power sequencer Date: Tue, 17 Aug 2021 03:55:02 +0300 Message-Id: <20210817005507.1507580-11-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@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 | 290 ++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 drivers/power/pwrseq/pwrseq_qca.c diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig index 36339a456b03..990c3164144e 100644 --- a/drivers/power/pwrseq/Kconfig +++ b/drivers/power/pwrseq/Kconfig @@ -19,6 +19,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..3421a4821126 --- /dev/null +++ b/drivers/power/pwrseq/pwrseq_qca.c @@ -0,0 +1,290 @@ +// 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 + +/* + * 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 { + struct qca_vreg vddio; + struct qca_vreg *vregs; + size_t num_vregs; + bool has_bt_en; + bool has_wifi_en; +}; + +struct pwrseq_qca; +struct pwrseq_qca_one { + struct pwrseq_qca *common; + struct gpio_desc *enable; +}; + +#define PWRSEQ_QCA_WIFI 0 +#define PWRSEQ_QCA_BT 1 + +#define PWRSEQ_QCA_MAX 2 + +struct pwrseq_qca { + struct regulator *vddio; + struct gpio_desc *sw_ctrl; + struct pwrseq_qca_one pwrseq_qcas[PWRSEQ_QCA_MAX]; + int num_vregs; + struct regulator_bulk_data vregs[]; +}; + +static int pwrseq_qca_power_on(struct pwrseq *pwrseq) +{ + struct pwrseq_qca_one *qca_one = pwrseq_get_data(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 vddio_off; + + if (qca_one->enable) { + gpiod_set_value_cansleep(qca_one->enable, 0); + msleep(50); + 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; + +vddio_off: + 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_data(pwrseq); + + if (qca_one->enable) { + gpiod_set_value_cansleep(qca_one->enable, 0); + msleep(50); + } + + 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 = { + .power_on = pwrseq_qca_power_on, + .power_off = pwrseq_qca_power_off, +}; + +static int pwrseq_qca_regulators_init(struct device *dev, struct pwrseq_qca *pwrseq_qca, + const struct qca_device_data *data) +{ + int ret, i; + + pwrseq_qca->vddio = devm_regulator_get(dev, data->vddio.name); + if (IS_ERR(pwrseq_qca->vddio)) + return PTR_ERR(pwrseq_qca->vddio); + + ret = regulator_set_load(pwrseq_qca->vddio, data->vddio.load_uA); + if (ret) + return ret; + + pwrseq_qca->num_vregs = data->num_vregs; + + for (i = 0; i < pwrseq_qca->num_vregs; i++) + pwrseq_qca->vregs[i].supply = data->vregs[i].name; + + ret = devm_regulator_bulk_get(dev, pwrseq_qca->num_vregs, pwrseq_qca->vregs); + if (ret) + return ret; + + for (i = 0; i < pwrseq_qca->num_vregs; i++) { + if (!data->vregs[i].load_uA) + continue; + + ret = regulator_set_load(pwrseq_qca->vregs[i].consumer, data->vregs[i].load_uA); + if (ret) + return ret; + } + + return 0; +} + +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) + return -EINVAL; + + pwrseq_qca = devm_kzalloc(dev, struct_size(pwrseq_qca, 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_regulators_init(dev, pwrseq_qca, data); + if (ret) + return ret; + + if (data->has_wifi_en) { + pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_WIFI].enable = devm_gpiod_get(dev, "wifi-enable", GPIOD_OUT_LOW); + if (IS_ERR(pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_WIFI].enable)) { + return dev_err_probe(dev, PTR_ERR(pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_WIFI].enable), + "failed to acquire WIFI enable GPIO\n"); + } + } + + if (data->has_bt_en) { + pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_BT].enable = devm_gpiod_get(dev, "bt-enable", GPIOD_OUT_LOW); + if (IS_ERR(pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_BT].enable)) { + return dev_err_probe(dev, PTR_ERR(pwrseq_qca->pwrseq_qcas[PWRSEQ_QCA_BT].enable), + "failed to acquire BT enable GPIO\n"); + } + } + + pwrseq_qca->sw_ctrl = devm_gpiod_get_optional(dev, "swctrl", GPIOD_IN); + if (IS_ERR(pwrseq_qca->sw_ctrl)) { + return dev_err_probe(dev, PTR_ERR(pwrseq_qca->sw_ctrl), + "failed to acquire SW_CTRL gpio\n"); + } else if (!pwrseq_qca->sw_ctrl) + dev_info(dev, "No SW_CTRL gpio\n"); + + for (i = 0; i < PWRSEQ_QCA_MAX; i++) { + pwrseq_qca->pwrseq_qcas[i].common = pwrseq_qca; + + pwrseq = devm_pwrseq_create(dev, &pwrseq_qca_ops, &pwrseq_qca->pwrseq_qcas[i]); + if (IS_ERR(pwrseq)) + return PTR_ERR(pwrseq); + + 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 = (struct qca_vreg []) { + /* 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_bt_en = true, + .has_wifi_en = true, +}; + +/* Shared between wcn3990 and wcn3991 */ +static const struct qca_device_data qca_soc_data_wcn3990 = { + .vddio = { "vddio", 15000 }, + .vregs = (struct qca_vreg []) { + { "vddxo", 80000 }, + { "vddrfa", 300000 }, + { "vddch0", 450000 }, + { "vddch1", 450000 }, + }, + .num_vregs = 4, +}; + +static const struct qca_device_data qca_soc_data_wcn3998 = { + .vddio = { "vddio", 10000 }, + .vregs = (struct qca_vreg []) { + { "vddxo", 80000 }, + { "vddrfa", 300000 }, + { "vddch0", 450000 }, + { "vddch1", 450000 }, + }, + .num_vregs = 4, +}; + +static const struct qca_device_data qca_soc_data_wcn6750 = { + .vddio = { "vddio", 5000 }, + .vregs = (struct qca_vreg []) { + { "vddaon", 26000 }, + { "vddbtcxmx", 126000 }, + { "vddrfacmn", 12500 }, + { "vddrfa0p8", 102000 }, + { "vddrfa1p7", 302000 }, + { "vddrfa1p2", 257000 }, + { "vddrfa2p2", 1700000 }, + { "vddasd", 200 }, + }, + .num_vregs = 8, + .has_bt_en = true, + .has_wifi_en = true, +}; + +static const struct of_device_id pwrseq_qca_of_match[] = { + { .compatible = "qcom,qca6390-pwrseq", .data = &qca_soc_data_qca6390 }, + { .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 Tue Aug 17 00:55:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6494BC4320E for ; Tue, 17 Aug 2021 00:56:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 45A396054E for ; Tue, 17 Aug 2021 00:56:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237774AbhHQA5A (ORCPT ); Mon, 16 Aug 2021 20:57:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236295AbhHQAz6 (ORCPT ); Mon, 16 Aug 2021 20:55:58 -0400 Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E074C0613A4 for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id y6so13343069lje.2 for ; Mon, 16 Aug 2021 17:55:23 -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=OF+bSNrekE/+0wO+D2wfK4wViZM9bqH0gp92GYiunF8=; b=cM7uNQKuu5dnPNA/r3uzwOSlkZGPgMBXADPm8THNYFEDMOjOGxMvMjdB3F7ehvUI0P jSQA1m7WSHuioIu9NDWPO3OdHn8GAH0tzSEWc8j+mykFH4nrhKP5NzOx5cWlQkMdu0Dc RA2uWCHVYIgOAWJ6jR9xFlJUQMdSzdNHIHTvXNti55cFv1as17iQHUl5vsZK8TFY2K61 exYI8oCWgFFX8pQABZBDMWguDSKljIB0UJPlHFiOj7SGwv6L2gJ6PL3xjWYwtE6FdD5K vCdq3wGKZ851VeJQtub1ZdI7Y9d9Uu8uVXKZNBQLtLYE08MNV9fV3CjZzD2ejwh6ZdDx m85g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OF+bSNrekE/+0wO+D2wfK4wViZM9bqH0gp92GYiunF8=; b=pIkGImKXwFEDBw62WJzUiGGCJkLEqgunazRNPZY450t4NGGbUkt6VOK4bu4coArmU2 L3A1K84DMnrQvEvbVIajMJcoDhtmb20ZSw2O5IqxElfxG6pyX/UFgX+3vlThB2WK8yxq W3GtEM556w4in/H4lA8YfKSmBWHy9JIVvc5RGiDUofcxgdHUJEQvlSMIdUHTe+vFME7U rC784SDj3gzYx3SALeZ75EgOOoDhRLc62XCHJVFZERoxGIPojsvU/NRA6XyPQw4isw20 gUSvtvrXvl0um6ZFyDTrbV7qFaGoviPmMXA4OVprImEihkbVXugxc5X8bp/hZ0/7QHGh D9LQ== X-Gm-Message-State: AOAM530fRISB8Z8ReKhYOMJ6L4CiAYuvuGqmu898R6y6So6IjFUrEYgO A5gPuMSsadiI5zELgd1C41FooQ== X-Google-Smtp-Source: ABdhPJxJzCYv9Dq92ptE7pADX3DwMYSV+uy30xcy0SMHC/VUEZ9Cq33n8a04O6lvZVB3SkR+ZA4+Yw== X-Received: by 2002:a05:651c:1507:: with SMTP id e7mr795429ljf.368.1629161722074; Mon, 16 Aug 2021 17:55:22 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:21 -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: [RFC PATCH 11/15] arm64: dts: qcom: sdm845-db845c: switch bt+wifi to qca power sequencer Date: Tue, 17 Aug 2021 03:55:03 +0300 Message-Id: <20210817005507.1507580-12-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Switch sdm845-db845c device tree to use new power sequencer driver rather than separate regulators. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 21 ++++++++++++++------- arch/arm64/boot/dts/qcom/sdm845.dtsi | 6 ++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 2d5533dd4ec2..c9b694e934d4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -629,6 +629,16 @@ &qupv3_id_1 { status = "okay"; }; +&qca_pwrseq { + status = "okay"; + + vddio-supply = <&vreg_s4a_1p8>; + + vddxo-supply = <&vreg_l7a_1p8>; + vddrfa-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l25a_3p3>; +}; + &sdhc_2 { status = "okay"; @@ -916,10 +926,8 @@ &uart6 { bluetooth { compatible = "qcom,wcn3990-bt"; - vddio-supply = <&vreg_s4a_1p8>; - vddxo-supply = <&vreg_l7a_1p8>; - vddrf-supply = <&vreg_l17a_1p3>; - vddch0-supply = <&vreg_l25a_3p3>; + bt-pwrseq = <&qca_pwrseq 1>; + max-speed = <3200000>; }; }; @@ -1036,9 +1044,8 @@ &wifi { status = "okay"; vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; - vdd-1.8-xo-supply = <&vreg_l7a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + + wifi-pwrseq = <&qca_pwrseq 0>; qcom,snoc-host-cap-8bit-quirk; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 0a86fe71a66d..78e889b2c8dd 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1051,6 +1051,12 @@ psci { method = "smc"; }; + qca_pwrseq: qca-pwrseq { + compatible = "qcom,wcn3990-pwrseq"; + #pwrseq-cells = <1>; + status = "disabled"; + }; + soc: soc@0 { #address-cells = <2>; #size-cells = <2>; From patchwork Tue Aug 17 00:55:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DBE5C4338F for ; Tue, 17 Aug 2021 00:56:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0B958603E7 for ; Tue, 17 Aug 2021 00:56:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237118AbhHQA4d (ORCPT ); Mon, 16 Aug 2021 20:56:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235960AbhHQA4I (ORCPT ); Mon, 16 Aug 2021 20:56:08 -0400 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C2C6C0612A6 for ; Mon, 16 Aug 2021 17:55:24 -0700 (PDT) Received: by mail-lj1-x233.google.com with SMTP id y7so30167497ljp.3 for ; Mon, 16 Aug 2021 17:55:24 -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=YQt/DuSx0bT+fggEeQl7bKu3DF9WLrIbpvPtKTp1n3Q=; b=VDg7sgLR5PvBlQfeFtYC652lbHyUalwcdJFv+rouf/RrFSyuQcjGXyE9RXHErNdVHS qYGPxJMlLyv3bB2tVrucSjwatYAWM33+Ey7Ag6Mja6333jByHyjvAysGFQm0eLpXTKY1 j7onx9jAPSxJPFAWf7O19mkHQD7hHKG7LfJ54Awmii3BXn8dCKMtmqxqbbsW1Vw92h4w DCnVwPdgnxImZ/OghvlON0r0uaI126uxDcGek3Qi4Ok8/vHc+eUuIyehPiLU2S8Gmp72 uzNeiSTkrDgWP1xt4Tuj/8HB5wFcRubflkt8itoTdK/D+V1rV+ha9O3hS2Lf2ZwwE4pf vhiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YQt/DuSx0bT+fggEeQl7bKu3DF9WLrIbpvPtKTp1n3Q=; b=bhlQFkFXHoaAxmfpOj2Jb6ssDEVRxAiLyda73W1mH8Irn+npygOa2CPDxuFJMeYX2q LELVnS1mHiJJ3z50BjH4/HnObZ27911MQjAiKiq2/b7ZfzwyM5FcoPBBya7wESBRdSJU dMkpMwE1cH9E2iGrM6/x18/92pPD3dFanqIwRQO50iIhVQclbpLzefnkQsRLoHAvz/Ge LuwLPiI3Uvi96Libj64w/L0x6+c4G1N9mzgrQV5k9+CgRwGvusqAxKhE8eSUNHA+VQbx 96Rm943ZGDorAHBh+OszBc2VBuhwZIa8qt6OYeUPkLxbXxzG37LGI7AbErrv3yMpCjXf zBlA== X-Gm-Message-State: AOAM533I1No+75oM6wNTo74jTjS6Koz9TM/g7ovKPj5MDT7/7SkL0zoM 2SSO/vP2HrmUNOusJtGBlbeN6A== X-Google-Smtp-Source: ABdhPJyNLUS2dwSRaqJ5H76SvBhAQ9S/S789/Y5Oq9VF9A4kizqCDRIBv075Pxe7Gma8nrJ/Cpt1Eg== X-Received: by 2002:a05:651c:985:: with SMTP id b5mr797712ljq.78.1629161722852; Mon, 16 Aug 2021 17:55:22 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:22 -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: [RFC PATCH 12/15] arm64: dts: qcom: qrb5165-rb5: add bluetooth support Date: Tue, 17 Aug 2021 03:55:04 +0300 Message-Id: <20210817005507.1507580-13-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Add support for the bluetooth part of the QCA6391 BT+WiFi chip present on the RB5 board. WiFi is not supported yet, as it requires separate handling of the PCIe device power. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 8ac96f8e79d4..326330f528fc 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -19,6 +19,7 @@ / { aliases { serial0 = &uart12; + serial1 = &uart6; sdhc2 = &sdhc_2; }; @@ -98,6 +99,25 @@ lt9611_3v3: lt9611-3v3 { regulator-always-on; }; + qca_pwrseq: qca-pwrseq { + compatible = "qcom,qca6390-pwrseq"; + + #pwrseq-cells = <1>; + + vddaon-supply = <&vreg_s6a_0p95>; + vddpmu-supply = <&vreg_s2f_0p95>; + vddrfa1-supply = <&vreg_s2f_0p95>; + vddrfa2-supply = <&vreg_s8c_1p3>; + vddrfa3-supply = <&vreg_s5a_1p9>; + vddpcie1-supply = <&vreg_s8c_1p3>; + vddpcie2-supply = <&vreg_s5a_1p9>; + vddio-supply = <&vreg_s4a_1p8>; + + bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; + wifi-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; + swctrl-gpios = <&tlmm 124 GPIO_ACTIVE_HIGH>; + }; + thermal-zones { conn-thermal { polling-delay-passive = <0>; @@ -804,6 +824,26 @@ lt9611_rst_pin: lt9611-rst-pin { }; }; +&qup_uart6_default { + ctsrx { + pins = "gpio16", "gpio19"; + drive-strength = <2>; + bias-disable; + }; + + rts { + pins = "gpio17"; + drive-strength = <2>; + bias-disable; + }; + + tx { + pins = "gpio18"; + drive-strength = <2>; + bias-pull-up; + }; +}; + &qupv3_id_0 { status = "okay"; }; @@ -1193,6 +1233,16 @@ sdc2_card_det_n: sd-card-det-n { }; }; +&uart6 { + status = "okay"; + bluetooth { + compatible = "qcom,qca6390-bt"; + clocks = <&sleep_clk>; + + bt-pwrseq = <&qca_pwrseq 1>; + }; +}; + &uart12 { status = "okay"; }; From patchwork Tue Aug 17 00:55:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439559 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E457C43216 for ; Tue, 17 Aug 2021 00:56:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7758A6054E for ; Tue, 17 Aug 2021 00:56:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237351AbhHQA4c (ORCPT ); Mon, 16 Aug 2021 20:56:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236734AbhHQA4I (ORCPT ); Mon, 16 Aug 2021 20:56:08 -0400 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E356C0612A9 for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id y7so30167516ljp.3 for ; Mon, 16 Aug 2021 17:55: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=u12rwXg8g4PJq/ZBmPuac8Qj8YYRwwb7Uj5T/LSY2zo=; b=EAAYpRI2iVZDTfCZlb3Xqro7/P2wtZ+jkRMZf1Bmh7AZuZINyv+zBfw/ockT4XoYLT QB/cN8F4orqXktrhSOfkliEEResJ0b5pqmxQ62pjSZViPa/GvUh+J3F3jdLlzCMrQQIM xHQTiw2dvd3RmKMMmpg1bP25EHiY+NSdxghJmhccESTLR3y+C9/fwa4EXqi7iu9nI/FP OCrg6JQtgfr5ilE4Qypv60EKDcw8RS1WESxnJs9KflYa6JFtcIzkXeVXPxktb31oRcch UteYQcWAA0Gb2cpQn7rQLebStwfVY9moW4BolAL9a3QqdepGzKAdBMrNAF0UC3z45+BR 7PXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=u12rwXg8g4PJq/ZBmPuac8Qj8YYRwwb7Uj5T/LSY2zo=; b=LEDt/srEUnycgLBh0tDhfiPqyq3MeFhsDlf57Bi/+gj/QihctAeJB6qOoP0QQDVDkm jTq2/EbFHdag79NVcyxhCpOjJCryDC8S4P8B+WumzDvZs+T9g3cn67M7Ls0EH6eOGYFT 9QvnenbS2aMIwGpnEjKAgQsGd5Fomxhp/FXGVN3DY/KMba2zJzeZZPjmYV85Nb5Z5LLp p3RExqaqMMKeFwxAsQYQVfnqq1W6ehltH8KwtIfRbcV9jUXOJK8aGJ51ScfENBu9MI8Z vsIPz3Kw3uNuwI3t3uhu9ceNKi5Bm+UbmuTlAckWlLzzSfyg9b602yIRewRWpWfnCMgW Ib5Q== X-Gm-Message-State: AOAM531iQI3N0GxXzoi1nQFcwWlcWRWBcBCS2XzIRqftjl+SDireIUpV DxOSJfLJp+YwEo12d5dZe+uf+w== X-Google-Smtp-Source: ABdhPJykxVR6EeoPt1Rvlafv3t+KywFGvitTYNxwTI9ilss5IuaqKndgqB3OhVtT7EruboGWfnj6lQ== X-Received: by 2002:a05:651c:1057:: with SMTP id x23mr757286ljm.377.1629161723606; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55: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: [RFC PATCH 13/15] arm64: dts: qcom: sdm845-db845c: add second channel support to qca power sequencer Date: Tue, 17 Aug 2021 03:55:05 +0300 Message-Id: <20210817005507.1507580-14-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index c9b694e934d4..3025e5efd556 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -342,6 +342,12 @@ vreg_l21a_2p95: ldo21 { regulator-initial-mode = ; }; + vreg_l23a_3p3: ldo23 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = ; + }; + vreg_l24a_3p075: ldo24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; @@ -637,6 +643,7 @@ &qca_pwrseq { vddxo-supply = <&vreg_l7a_1p8>; vddrfa-supply = <&vreg_l17a_1p3>; vddch0-supply = <&vreg_l25a_3p3>; + vddch1-supply = <&vreg_l23a_3p3>; }; &sdhc_2 { From patchwork Tue Aug 17 00:55: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: 12439555 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C34B5C4338F for ; Tue, 17 Aug 2021 00:55:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB536603E7 for ; Tue, 17 Aug 2021 00:55:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237077AbhHQA4Q (ORCPT ); Mon, 16 Aug 2021 20:56:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236866AbhHQA4K (ORCPT ); Mon, 16 Aug 2021 20:56:10 -0400 Received: from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com [IPv6:2a00:1450:4864:20::22e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3B31C0611BD for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x22e.google.com with SMTP id i28so8805486ljm.7 for ; Mon, 16 Aug 2021 17:55: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=TpzWYLTlVm4a1u+cpDX/DibFOc/Y83As8pftjQgWXKY=; b=q9pVfUjjkZl1dsYvBgGfBt7HOGtu8qETGZwnHj79FxZbGPuB6WTuhL+bUDVxMkCegv WEQR1iewhQkT/FqzCRDxANG/lounhB5oawM+/8Wvjz87lWryGQuJU1Ie+0L8IS/wI9xd 6MQqcTbuWam46/QnO7n0r47+m4ZYylm/I0O1HTHqkqs/KB85IKXpeGKM+en0wo82yZ/W +wePJePJbzKU5tK97xy6yr5AwOC5V53tgIhaJs1E6spLUJAM9eiDG+8iQodQveBAnmPE Cr4OTMeadYhTN6g7Gvg91Z1gyUXuIDc2CvtECs4MkTfSy29nmzr39Mte6ecmEI1CyRtK aeKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TpzWYLTlVm4a1u+cpDX/DibFOc/Y83As8pftjQgWXKY=; b=IM03sxaDX0ZPiiTYs4IZzI11yFFqBh/G5WO+uz5jQ/NnQL8CeVZZJghxmR9HrLtffX PwGWA4KM4Y6HRmkaDyGLxNFYodNk2CA1tP6dWIP4DiQ3uR2x5JETM6vz/E0VFqACMqjK Ai7CEGJPX/FcyoSomN4GmxIeIZdkLklACPjaOk6iYGKxXb0DiVpHrtqVLqsnmL2Pig8j O7rjwtDkL/gUT7muNjx5DRoVPUxRiHQIN6ANXOf61eYoNsYmH7xoL8hfaK88P/xaLg1N CFCiuQqbc3UgWGjXRCyQ7ao9uY7Si0nCnQx7zqTftipqO0nX6mgVsY3RB7+Ts+4d0gFg xFbw== X-Gm-Message-State: AOAM530HJ/AK1RXhNmUlxhWysWq/YqygA3yFk6HC8iTUFCapVOYIzGgu u/Lq3g3uH/m2QqMbRI1Q7qxwAQ== X-Google-Smtp-Source: ABdhPJzVEZqzzw5axwOZZ57yFH4IQjnro9z1ocsbY1Qd55La4H98eGgaiJDN30TJHy6/Q48qtg1yYw== X-Received: by 2002:a05:651c:1142:: with SMTP id h2mr776331ljo.289.1629161724341; Mon, 16 Aug 2021 17:55:24 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:24 -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: [RFC PATCH 14/15] WIP: PCI: qcom: use pwrseq to power up bus devices Date: Tue, 17 Aug 2021 03:55:06 +0300 Message-Id: <20210817005507.1507580-15-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@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 +++++++++++++ drivers/power/pwrseq/pwrseq_qca.c | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 8a7a300163e5..a60d41fbcd6f 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_optional(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); diff --git a/drivers/power/pwrseq/pwrseq_qca.c b/drivers/power/pwrseq/pwrseq_qca.c index 3421a4821126..4107f0a9c05d 100644 --- a/drivers/power/pwrseq/pwrseq_qca.c +++ b/drivers/power/pwrseq/pwrseq_qca.c @@ -1,3 +1,4 @@ +#define DEBUG // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, Linaro Ltd. From patchwork Tue Aug 17 00:55:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12439557 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05271C4338F for ; Tue, 17 Aug 2021 00:55:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E39D560295 for ; Tue, 17 Aug 2021 00:55:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237184AbhHQA4U (ORCPT ); Mon, 16 Aug 2021 20:56:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237031AbhHQA4O (ORCPT ); Mon, 16 Aug 2021 20:56:14 -0400 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A424DC061147 for ; Mon, 16 Aug 2021 17:55:26 -0700 (PDT) Received: by mail-lf1-x12d.google.com with SMTP id z2so38112799lft.1 for ; Mon, 16 Aug 2021 17:55:26 -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=Pgxc5wTtAPJJ0DGyppg9xAOqF0AZtpwhIIHZ/fU+CFw=; b=HwDbiofct0TMB65omGXGchoWcB9pqFmXgylYFqrV+IPCkhhIk+Lc+xUFVyK+iwexVh BaN/elu+aEntGCLUZUMK9LwbqVepb8vBqq3+KkGl5eq8ph6kQo8uBRg3iNbL9p8MQDRk AGUcbP/cOzbyQR0fSHRxKQKuYlF8U3Tqb0kDQ0693qSsC1JRhX7XsgaFSljyZZND0yDD daJBvqi3qdAEnp9q9MoUaMSI4eshxddlIFStgVVccRzTIoWvtzhSNPzZkYDrQNyIV1sk 5uteB81rUcjsgWOQpQlN8qjpaUmFXIbrjX4RVsaLWEcCoZJ7LnZpbhjwzWkAm3w2ipSa fPnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pgxc5wTtAPJJ0DGyppg9xAOqF0AZtpwhIIHZ/fU+CFw=; b=A+QTgNjicYfUI4WIUrI32su6cRU4QD+56L7lCgZ6UAH0jq5JOWHDqJOriSSqn3CLO0 dedBsuP0DmKBOuaTX7xhz+TL7a3aof4/jrgWYSG89RQNcL4M/TCAMFSc1hriLbMCfZlI LLBFijpkTidJJIydBtf6uA1EODCQeb0ze/kQuYYjUGWcl+6mdQsGf8uyoVjLajI2Uq+B LRCdoBOrk29ioiFSgY/KmD8WwtVj4GuTpQkxGwJOqfwP69Po1rbSXBnwo+v5EjCUkRvf OE/mSA42d6HP9BrjNGQeEzStPEFGBAY+AXaGymThJ/enlp4HFfeQdag4JVVMWO4hGZ2J WuwA== X-Gm-Message-State: AOAM533UP6LjAIkFk89NOnK2W5FTrIyK89+CzGKSayTSwLesVJ0927lM 2zTrQJgu6Jn6NVnO9dW7oRFljg== X-Google-Smtp-Source: ABdhPJxyuF7Jousa0ekVBo+HPfYk8A5Rq4PfYVTtE7a4QI12mfqo2ijMQkjYqeBcThS28ycqDu/ONA== X-Received: by 2002:a05:6512:3a83:: with SMTP id q3mr420518lfu.28.1629161725069; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id z6sm40719lfb.251.2021.08.16.17.55.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 17:55:24 -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: [RFC PATCH 15/15] WIP: arm64: dts: qcom: qrb5165-rb5: add bus-pwrseq property to pcie0 Date: Tue, 17 Aug 2021 03:55:07 +0300 Message-Id: <20210817005507.1507580-16-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> References: <20210817005507.1507580-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 326330f528fc..0c347cb6f8e0 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -689,6 +689,7 @@ wifi-therm@1 { &pcie0 { status = "okay"; + bus-pwrseq = <&qca_pwrseq 0>; }; &pcie0_phy {