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: 12439607 X-Patchwork-Delegate: johannes@sipsolutions.net 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 BBDF1C4338F for ; Tue, 17 Aug 2021 00:56:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A2EDA60C40 for ; Tue, 17 Aug 2021 00:56:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236797AbhHQA5R (ORCPT ); Mon, 16 Aug 2021 20:57:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235548AbhHQAzt (ORCPT ); Mon, 16 Aug 2021 20:55:49 -0400 Received: from mail-lj1-x22b.google.com (mail-lj1-x22b.google.com [IPv6:2a00:1450:4864:20::22b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C3A6C06179A for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x22b.google.com with SMTP id f2so8412200ljn.1 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=bu/ZXz74RbyHhBGIy/8YyQoUIiX+vpJ1pX/6gpPCxrJi9pi1e40bVhHwiSodOuBeZu 4hyMT3PRvVdWyeYRVCFHuKe4KfI+UYNoT9LypZkiGJSlAtRwOiq1hP4YE424LiKT2/b9 kLkNCPZC/PEvanGe4S+X0VKR4L6Sev5dnEf7o4iS3wc4oag1Heae5haaiuZQNx7nVxAt x2rvMhMQOijqETSpMRMVzmiVef8Bzn24TdCuR8G8Y9A/PSUT6QMOmkaC7PxatTsbuYie QvvtvCus7kUr2cXTgMG011dPPboOeNpQNOX6/rgtPkKu9n/peYpEftboeGtYMDlm4nXN IoiA== X-Gm-Message-State: AOAM533MQO1wavMq23Bf4mNKMVBvtERiCZqt7TNvyf9Zu4cW+iiTSSLL FG/PBSil9UoyDskhuHwYC4TTEQ== 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-wireless@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: 12439581 X-Patchwork-Delegate: johannes@sipsolutions.net 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 B454AC432BE for ; Tue, 17 Aug 2021 00:55:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9681260FC3 for ; Tue, 17 Aug 2021 00:55:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236177AbhHQAz4 (ORCPT ); Mon, 16 Aug 2021 20:55:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235139AbhHQAzt (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 CE9CAC061292 for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id q21so8573082ljj.6 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=RnQCTZqVGVFmM3TkJsQGrrK0O5ADoMBBSwEt5aaeXMrCn9HQBWNnnrIwMhcTRk+MMq wBfpTKmiWh2sOi8yEQxS11MuxHNxKko78Ub3p4ZQHuEcOi8bb0RgEL1HI078y4txgD5c 7znDK533+kJQ3WfS0Rujqi9jLl069lrfa68yYiWjZbQMOxiDvw/XEwO65aGKfNwin2NW 30ROJiBgsWkl7whu2bOXIEXvUZun7oPG6Y8GZINpsOg1VAnQ7WWFvZXOO5fltrehVdt+ K0ZaIVOSeGIQcONQCRyzpCGLFpZ+wHfZ5zoEk6KAFvIRYdVA7D+q2HiqDQJ1fD+dom/W kkig== X-Gm-Message-State: AOAM532fgxpWBzbZ1R6H0RocLpCRL/pveJXcIlobOoVGjVhEOuLeaJld VfKLVq2pwPhJAhyAF2BQ9r+plg== 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-wireless@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: 12439579 X-Patchwork-Delegate: johannes@sipsolutions.net 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 BC147C4338F for ; Tue, 17 Aug 2021 00:55:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9985B60FC3 for ; Tue, 17 Aug 2021 00:55:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235964AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235755AbhHQAzu (ORCPT ); Mon, 16 Aug 2021 20:55:50 -0400 Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6ACB6C06129D for ; Mon, 16 Aug 2021 17:55:17 -0700 (PDT) Received: by mail-lj1-x230.google.com with SMTP id h17so30043368ljh.13 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=jLTK+fG0a3aM9SAGCLCUHlsHv/nc8nt7FqdceS2wCAsMbhTEXVistit2fgEjWhQWv2 OJDq7A0MmtqOqmluXWW4rxvMtYlp5ZMkBo2YnUhPNKym8uabf4BF/WCjyQlIHHVn2JdG 44afUH/5xc571zmcCIOf45QTxRwS9bnPwriqMzsvjigil25RHHYHyIMcv1dfilvZp+91 3wc6EkdTfB5+xDYJE91cUhqfI1dZlqWab1FjIKprX1nyQv2XU/b/XEC23AlmcLir4gpf Lnj0BIHPCqyx+QsfDFWcauEqx8IuwbHEB6C5A5Z45dW2BnfVNp6DSDSrs0hUCzUqvGc7 1R8g== X-Gm-Message-State: AOAM531tol4UlSbkI1G9F9DQrUO4EkwdujMo2vW1bHhravhLTO3gGRi6 alqUDKKAPIIa/GEDjoBzJSl5PA== 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-wireless@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: 12439605 X-Patchwork-Delegate: kvalo@adurom.com 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 785E5C4338F for ; Tue, 17 Aug 2021 00:56:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6211760E76 for ; Tue, 17 Aug 2021 00:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236429AbhHQA4q (ORCPT ); Mon, 16 Aug 2021 20:56:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235775AbhHQAzu (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 4681FC0613C1 for ; Mon, 16 Aug 2021 17:55:18 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id f2so8412326ljn.1 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=Bn0Z/7EsAGJsPiuHO86efrTfO5+cXYqlHUPgwcxvIz7S0PuSKkpv32E5VlqZzvW501 166dU1cdqOhBWhyT+iQMoc+x5/Rrj2UV+LOMiUSpEO1EYJXAZgfgHYGDV7hE7OFbbu9C /xsk5Ih47FE93uHkpdbRL9Nn5mvRmsQnFCja9N98dIxADTm86AIQlR0SQBjXocQQ4d8l HB+FsyWocEXSJVpMy0OtFeoaJxfJy9ySL7dV+0cYTDxEs3Mn3SFIN1Q+j3QLWAvT/ca/ +gFNvYQeKoxYKI/DrUFjt2vQ89erfCAegH6p30CuZ2X3RrXcPRprHjiM2cDZ+iSBQ8GC 7VRw== X-Gm-Message-State: AOAM533IAfFCxX2bAUvscfF/1OWb1vm/ZShPJ5La0snVz28j5E5dVw6J nSBez1a/hlSxu685oj2xqQsCvg== 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-wireless@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: 12439587 X-Patchwork-Delegate: johannes@sipsolutions.net 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 E8550C4320A 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 D27326044F for ; Tue, 17 Aug 2021 00:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236650AbhHQA4H (ORCPT ); Mon, 16 Aug 2021 20:56:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233167AbhHQAzv (ORCPT ); Mon, 16 Aug 2021 20:55:51 -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 14F25C0613A3 for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x22e.google.com with SMTP id c12so17068197ljr.5 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=jHFLyA/1Jr4t96R+nI/whWC90cZzIw1rcqYwOFZJUK+vNTuVeBXLNBf8MZdNV84+ag L8qhztfPIqUxD1iCna3yWt880ol15ApdvU6d789zruylTqCfhjzQK5kDvz9e8Y3fcVNZ AC1foitswdXypZ1Rh0BzlAa48JuwI5k8phFkQosyoEM97rukQLzadR+x63sYTq8YrkTW imUE6MfmM0+gau8hJmBuuGA2xweN32XcjtI7UJtQ7Q0n/8SngdllzDjaVqaARG3IwgsA 0zCC/8htIra6GWW7YL0v3BvyhEPqYLXjPk5JYTVSe8IsS8/vAKegw1blXWn1KGEVoJJm rcRA== X-Gm-Message-State: AOAM530QXqUkjRjl86/hBDnrZnqBgGddEdSPWr/JSJCx6onRw2dJvSGp wkJBNqQqYXYe8SiAaYmeBGiYOg== 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-wireless@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: 12439585 X-Patchwork-Delegate: johannes@sipsolutions.net 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 D3937C43216 for ; Tue, 17 Aug 2021 00:55:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BBB4060184 for ; Tue, 17 Aug 2021 00:55:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236258AbhHQAz6 (ORCPT ); Mon, 16 Aug 2021 20:55:58 -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 S235967AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D17F1C0612A6 for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x22c.google.com with SMTP id i28so8805182ljm.7 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=JJxjOFHWQn0XlYp7sJejZ6GyeZHyG/DpGjGuAbbj07ol6yUgvQyxAysOAbANU06SNc 6FhNh00MbLn/0j2aTlTMqlOl1/NsYMjqSU4r4ObLc4y6zuCSZhM5QcWHCWMLQTrqBdFB YHXghUb4S+ZJKDR7ap6OsNsTD+6Fmd2YaUm8I8+KV2h7Kk0NINjRmdeaxusOFgc0cL0u bULVjOSkP+xt7Lm9wTqw3PrGa1eNzshFxXNWzRxNI8CTmiss/XgbSdx8bnpItJghIFiA 5B8XxQawlxekxhrZuBRhlfmm6CKMplbePGi9cHtWqwO9qZyP5jQb6MYroKaTBM+XlDFd BPhA== X-Gm-Message-State: AOAM532ecdx455cgA3d5/AYGBgq+0Qof1EZ+QmFpzwgQwIjSGPsJHxMk lzX+3R0zrnmgydAuuYHE4RQS+Q== 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-wireless@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: 12439583 X-Patchwork-Delegate: johannes@sipsolutions.net 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 7CDD8C432BE for ; Tue, 17 Aug 2021 00:55:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F91860F39 for ; Tue, 17 Aug 2021 00:55:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236365AbhHQA4A (ORCPT ); Mon, 16 Aug 2021 20:56:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235983AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FD61C0612A8 for ; Mon, 16 Aug 2021 17:55:20 -0700 (PDT) Received: by mail-lf1-x12f.google.com with SMTP id i9so17306134lfg.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=SqmMCpAhg8fwsDNyz76s30Zx7vjdqZAcH3kN/GXCX22uUCmsh9plQHQ7ApQpKG91+W mjhF8YutklX5Jj5w2Q9/egKGLHHKUdAJs0VFEPsd/ghiQHPg/MVrGQrHh8DlWv85yDZX JolrAqNEC9oim+5kOm2zuq+GOz1x2m0Ic5yypGE930+35oLBjKX5XUaCJuyE25oIA4pV JWW5agxSH/GesfsJx8/Zyu7vO7jAmuIx1AKVh9b3+C7tMUrTL0RmLU+kbWkS+a+OlAo9 jK8WNrWlHSMhWVRur4CdBIQ74SGM1U9Lbw2mbXU0U7f1gpkjG3oKr2H3RzswRV7xYFUu Xanw== X-Gm-Message-State: AOAM531qDYg+r25xm7Zex5iX64Zuh14WbXIvlQX6yuheiwUpZsz8PIG7 DMPi4JrXjvNLoekGjROss7frzQ== 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-wireless@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: 12439589 X-Patchwork-Delegate: johannes@sipsolutions.net 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 D7C2CC4320E 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 C165560295 for ; Tue, 17 Aug 2021 00:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236026AbhHQA4G (ORCPT ); Mon, 16 Aug 2021 20:56:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236051AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -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 81841C061226 for ; Mon, 16 Aug 2021 17:55:21 -0700 (PDT) Received: by mail-lj1-x22a.google.com with SMTP id f2so8412484ljn.1 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=QpjFPNn5HGgoA3uwteLohBimAoxbbfXn9lZ9oOD/alnKkszWWllqOWwQkxmweOdLJ/ ivn8EH84D1lzsKfeV5I70BrOh7Z5LssXbE8ZyjQG6oRPi3QmMEnxXX5lO1Gw2bc2UoF1 RaFSUxNViUOovXNAM/OUZbHBSPCtrORL+zuYiE271q632BN7pD7uBYDVhVTP/nVNfw4v 4u2NP8YTjGd2eElg0x0hvZeBBIlt2hARVT0vKlV7yMj95BC0/ud0TVJLvJSwn1OiRXIA H88Geh+GtOGH2cBRZJuxcAyZgtsLj16cP8Rx9QTbq5dVxCq12MCzDYqbGYflEtHntTxR D0SQ== X-Gm-Message-State: AOAM530zThJUj+Ofv72mmiW4MHldieAj/zYKVTnxeJO+g97HrmXEG1cE 7FF6ECQx50iZCLEyh/lcMQcCuA== 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-wireless@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: 12439603 X-Patchwork-Delegate: johannes@sipsolutions.net 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 610E1C4320E for ; Tue, 17 Aug 2021 00:56:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47C9660E76 for ; Tue, 17 Aug 2021 00:56:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237169AbhHQA4s (ORCPT ); Mon, 16 Aug 2021 20:56:48 -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 S236096AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 301F2C0617AF for ; Mon, 16 Aug 2021 17:55:22 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id i28so8805311ljm.7 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=WAEhd0CRLM2NCq7mVyWUFtjOAnWvYJo6GtZyWPkJF+dgSamXBkuUHIMIo/ou8KmikF KHxIn444xYefm+bHWQCXhVijeNxzf5qjVvGLavd0+PLyzv/1luLjN2gxnZC+L9BcJJXl l18oOZaePHmx3FdodqBpbxKNxzoZjYTr8xFXp6E213ddoagO8FpijnK5MNRejHjCvRJZ wdSXG5iN8cnh/g/2qC+O9dt33++izqVNdQY8qGn12TcTyUvlzy6nezvPHvy1dVxvBSKW P2+frt6BSo/lyzQRJ/97InMteUU+3p89m2PbbiEpxq+j3U3f00MHwAfJcU5eThHYLAEH /2VA== X-Gm-Message-State: AOAM531ZOdnvKBb92XtKtJqinGCezkGvXi4BruQFoNdmbwWs6WmE90m9 eHQ403KHbBc2+EH7l+VYPVsjHQ== 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-wireless@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: 12439599 X-Patchwork-Delegate: johannes@sipsolutions.net 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 DBED5C41537 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 C5FA46054E for ; Tue, 17 Aug 2021 00:56:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237668AbhHQA45 (ORCPT ); Mon, 16 Aug 2021 20:56:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236131AbhHQAzz (ORCPT ); Mon, 16 Aug 2021 20:55:55 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 030ABC0617AD for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id g13so37976008lfj.12 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=fHYFc2Ua4avgAezGFv/bR81TGjcf46l1dPaeicc6W2TfuQLRyo7oLPMMuJPPtgliCV tMWkcO/Ji6MSYW6TH+CMgYMm9sdTYAqIfQW/1XJP6bVd3ZG/72jcH+VH9FPywdeOlMLd hYqAoh7MvUPSHRqjOrOSV5C8LN73EJAJrr6TGuC/B2V+6ys7MxEcpOFR+An9hu7OotXK zX1wOL3CaYeDusu063UHpAChKvlgYsVH3YchfxvVvrbcan1JDsY4+0MN88CUB94vU3z4 lAdN+V0TPC75HY1yRUeJ6UYuQroKLEoTnltsB3BvLamiYFKuJqioSURMW7Z7ELmoGksV J2PA== X-Gm-Message-State: AOAM533iPAU4ovuieYZOdScaSleSOktecX+eLjw3WdHjcvzclKZGrYb+ w9L/uNcbVCk8ooi0cs3/DDJlmQ== 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-wireless@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: 12439601 X-Patchwork-Delegate: johannes@sipsolutions.net 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 204B0C19F37 for ; Tue, 17 Aug 2021 00:56:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E063260EFF for ; Tue, 17 Aug 2021 00:56:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237749AbhHQA47 (ORCPT ); Mon, 16 Aug 2021 20:56:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236284AbhHQAz6 (ORCPT ); Mon, 16 Aug 2021 20:55:58 -0400 Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E5B5C0612E7 for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lj1-x22d.google.com with SMTP id d16so11986176ljq.4 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=D4GF3FRKtMy+Z/XfA9IfVqbtb2CMYnDg2xOyFIdxT+pdb2OBY5Jp8rpzwNgSr6wcEL eQykY/83hEWSq0ebJcLXp+SvuMHI5VDaxVdez496PafhtrbLYQbQyRANUj7OqY9LUXPd nFjBwI7kgss2sdmBvNVN82ktKMhiV7BT079b5dsLZWv0IWyJIbklOFKN95LKnCCz/GpU povNmZXduUxmYHo4Zt2iwNp5zUj+MGyLCWSRTI328Ff2TenU5Diii8nTL9cJQ2y7U05+ 7wv+4osPA4heA7WB0hfu6xTKRVAuXtEtxH1PlYRjRY5JL9g++Xzl/2nlTLjTl8UcYToi iGwQ== X-Gm-Message-State: AOAM532XmJKHDN0Vm17VuAKJ1y9+VnJIzPDePzSWwL9BgoiVyKNXQByE iExKG3pTWkrZyo6SuQZTWrY+qw== 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-wireless@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: 12439597 X-Patchwork-Delegate: johannes@sipsolutions.net 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 03E01C4320E for ; Tue, 17 Aug 2021 00:56:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3B8E6044F for ; Tue, 17 Aug 2021 00:56:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236574AbhHQA4i (ORCPT ); Mon, 16 Aug 2021 20:56:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236579AbhHQA4G (ORCPT ); Mon, 16 Aug 2021 20:56:06 -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 78C47C0612A5 for ; Mon, 16 Aug 2021 17:55:24 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id h9so30119251ljq.8 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=uO8TjU2rQ8F7IIG/YuUQAJJjo7zN2QCe1u4g/69VbRSvLuQmuDA0m1mhvewzeQtIZv zBlpo4MFm7vGvuew3AaINYBlXXheacH4U4CWhsISzExwHp+nIAFHESc+64TMiiIvydHV zosniQ4qITj9usZMXyvEqV6dBvBhpDYgX9m40d1363skNrkUu8GMaiw3vvn+3ltbzg8u 9NPH4npirSqcFY71REcPYbTTY+snh/Df0W3d8dIX26fEo5yrFclCJFkzdvNgmvn0gFhD QkjP8JA1ma8MGPiVkVF8nQoSullubUCsXxK6b2g8NMoI2XKiEHNca/WtcyG4Vu5RWn1p o8AA== X-Gm-Message-State: AOAM530CvnUuHfixKY2oYmfeXw2SA4+taY4AKFPu4Tp/rZOCu1GIIq0K aRpyZU1nM6Xn9npiyzi1Gwkg6Q== 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-wireless@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: 12439593 X-Patchwork-Delegate: johannes@sipsolutions.net 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 F3602C4338F for ; Tue, 17 Aug 2021 00:55:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E375660184 for ; Tue, 17 Aug 2021 00:55:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237097AbhHQA4T (ORCPT ); Mon, 16 Aug 2021 20:56:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236741AbhHQA4J (ORCPT ); Mon, 16 Aug 2021 20:56:09 -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 31176C0611DD for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id h9so30119267ljq.8 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=E2Er100nJBONNHf/dHnhBz8EeP1bIoYE7HlUHx0VJq9l1/Nq3n8/Ug4paxfgH7o+c9 H5ysIH4gUksz3PZVuXXb+9qeWkB/8SvDorvOTpWkVkxLnesisAYLKF8UJXUpbAvSwizs sOcf7synyMscWenWaKXBTN0FtJov5HmBtr1fhd/sHuFf5i5anCy3z2HB/IGPMnUgbaWV 2GjnuaA/WMxAxTHptnmAo1jGVbIroB8CY8Cj93w3otPCD1TNc7EJIZ0fsGC57UAjWRhB yL3znlMS6n9ovGlU4loyZ4x6SAXTUx/kbuq1WXCPGUdb965jvv184/8IBPjjIbQbFLL5 oO6g== X-Gm-Message-State: AOAM530cid0SE4qUJ2G2W8rGrOqsg7ZhnwA+djXcFiSXTNPIpDQvNyX6 dTfCqAFH0PDTL1G92JzJAsBFOw== 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-wireless@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: 12439591 X-Patchwork-Delegate: johannes@sipsolutions.net 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 AC48EC432BE for ; Tue, 17 Aug 2021 00:55:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 99C5360295 for ; Tue, 17 Aug 2021 00:55:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237088AbhHQA4Q (ORCPT ); Mon, 16 Aug 2021 20:56:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235945AbhHQA4K (ORCPT ); Mon, 16 Aug 2021 20:56:10 -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 E4376C0611BE for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id f2so8412674ljn.1 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=Z0uhJ0nD4e5bV4P4tt/YMZey8bZU+P6YEdVZnYjWYO1OhwTyotgo7ZuIJMNXeqal2z Ij9NAoDoYJs68i8j97+kmynKmRTTt7whqDrLuO+t5ctFQyD2+/KvKiXsfxeKvDNUOwi2 q07bb/YvB5iG8W+rHf1Bn3MuEWuNCNxgxS93RP/OOi44VYlZMLe+Yg7pwI31hrE8pIDA HBx+WCnrDdXW9jwEQTF9/Icmieq0EPFVG1EnauvwZJygovqveAoysnhvvg3gFeizdqJP 2gqNytBgBLYpQURsmxl+F//Gp/CSsfXoYmIQLDBTnoqU5dDhtjzjZ08jieWw09Px5uKQ T8YA== X-Gm-Message-State: AOAM531TUGNnKo2TO6NhqY90fLgK6nv4KXw73KKEhTVLkT0Y7iXXSNFK hwaeVwkj97vkCE+v0m+jqtACQg== 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-wireless@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: 12439595 X-Patchwork-Delegate: johannes@sipsolutions.net 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 67251C4320E for ; Tue, 17 Aug 2021 00:56:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52C6C60295 for ; Tue, 17 Aug 2021 00:56:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237051AbhHQA42 (ORCPT ); Mon, 16 Aug 2021 20:56:28 -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 S237019AbhHQA4N (ORCPT ); Mon, 16 Aug 2021 20:56:13 -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 A2876C061145 for ; Mon, 16 Aug 2021 17:55:26 -0700 (PDT) Received: by mail-lf1-x12d.google.com with SMTP id y34so38034142lfa.8 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=ldBKl31CWr6ldI0LIyvyZAAxVSMYWRkXJDrD56lIhSd1fkfdQsxeYCSipq4Zpy73ei D7nd2rlsK9b5mHCObnHHqwmNyBiaS8hYxTfLBCTMxRlOpW3VUHQ8lDPKXo6WVrudR/F8 0iQ5iKPkEXC6P2PbDyzGRjicOtATn8WlFU0LKlf884aZ6jhd62IEwmoPsdqGJh/2KqTn LrzwsR3WqWyM+S/0dW/lFqaIToZL1vERIybj0nj8hF1a2GUxmuP2Mv6zHVJ1r8Noth8k LWCbRSxXonsI8xUM1K8kow7I+H64mRewGqP5lQELSoNqTSU/vGFBI5V32YIyLf5S7aqw hmhg== X-Gm-Message-State: AOAM532HbHL57UGdDhLket4kdD2RGYfaMjkXfaLtu62PchJyo2gQr1Xl A/T+RD1EKrczrK8BQ8MN7pyGuA== 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-wireless@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 {