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: 12439703 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 C3570C432BE for ; Tue, 17 Aug 2021 00:56:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ACE3C60C40 for ; Tue, 17 Aug 2021 00:56:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237190AbhHQA5R (ORCPT ); Mon, 16 Aug 2021 20:57:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235503AbhHQAzt (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 042B8C061796 for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id c12so17068047ljr.5 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=T7k/JBSIF6HQoj9uXmXxNotbphNK2riQWSeYSoMtG2Hh6yu0QTSDUt89wAusNtNZka GsjliZZX7kDWM5HHZWIKQLWUxfNd8O7BAYzM+79Tt1FJB1pftHECCsMamuTeb4BVbGtA dqnSAR13uiZ3TIws6spRL0bV8Z3MOyVH/EMNcjFAZnwDNXSB3QiXxT484Seag8hWk3Y6 T/B1PGRTiIbE0oAGl3vK/Oyotq2M1EgvnYhqISUJux+oxlV3Kko9vXuQFomYvbmYpVT0 47dAVs0ov3LHAZBQE4wdX0vbhdkePKQ5ZQe73bIdFijiog6pGMDL6voOOgBCpEdZJNyf D2wg== X-Gm-Message-State: AOAM530VemUfHGeK93rJypunfj97OTzWK3TlIGHKq1Vjnx+p61CUNeRv LR6KL7f/MYgXKR4UB1ULffFd5w== 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-bluetooth@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: 12439697 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 B991BC00144 for ; Tue, 17 Aug 2021 00:56:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9B0C76054E for ; Tue, 17 Aug 2021 00:56:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237230AbhHQA4s (ORCPT ); Mon, 16 Aug 2021 20:56:48 -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 S235650AbhHQAzt (ORCPT ); Mon, 16 Aug 2021 20:55:49 -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 BBEA4C0613A3 for ; Mon, 16 Aug 2021 17:55:16 -0700 (PDT) Received: by mail-lj1-x22c.google.com with SMTP id h17so30043325ljh.13 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=DntqhwJqBQFhk8bECbIp1pMgsfoxwNIz/I6I6jVwLWxUIyswzLmZQBNKmbELSPXEKt /QbFXa0MFo72YY5q58GyAPnM4zgJQfzwg7dm380JdD0zNM1M37Sqt3vI+RyfSIYoh/E8 iJ5pKcbWgegxc2TuSKtodZi4MIhayk2iD+S90EMB6gpXO17ySqaXiDhaF6I86iCpJ5uU +j3v3pTnOajvfCuu5jLo3slGuq3xitpLn7LV7GsZ4aFqTNfQaB4xJNDFOasVSZenQi93 BhPaMgZsNup1FS4rmQIFv/ijkDXZGiXzmy5AqcGKlqCLOkVxkwRS1jcmfPymqakpwKpL DyZA== X-Gm-Message-State: AOAM532dR9D+VhssJEUYbGbRt4rkgiCWoBWNiBYtYZd0sQ5tuW2DYQ3l hMK34Uum8PnKe6L2xrY/OEE1ww== 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-bluetooth@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: 12439673 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 55C1BC43214 for ; Tue, 17 Aug 2021 00:55:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 365D260F14 for ; Tue, 17 Aug 2021 00:55:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236033AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235767AbhHQAzu (ORCPT ); Mon, 16 Aug 2021 20:55:50 -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 6BE6CC06129F for ; Mon, 16 Aug 2021 17:55:17 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id s3so1079993ljp.11 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=HBxFVIvlyzapxZc9wCf0ZPamA42lEOUNh80TdTxMyL9mckxdEYtrYgLxQFyVYVGZg1 XiEGRWmijjr5PhSRkPTjxQ8qKsB7MfIPC8puvEiC1OuSxPrvN/rn/aUU7STBIkdLkex3 PEYxH9t+jNwH7UmaH5HiAl1/nykLVMb2OVRiuXGGGLAG605Mp6YZCHUQjfMy9Ty95H4W aZ5PhdJ1zi5J+zl4yFLRoh44X6TASoRT5LKpejFuzLfX0DnqMluixh0A1GrFIUJpLSBn CFyPoqWZOhm/fVxx3MKiaTkH4TXnpknlVRWbjCDLczTXGsXVNl8ffOlorOhEhtmb2EhK 1sgA== X-Gm-Message-State: AOAM533MAWJN0vaueIPgHwDWLQtw5kAP87vHG9Ep3iLB5aaV7Iw7aZAO QUE9eqkb/kXdSrrelWUcsKRnJA== 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-bluetooth@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: 12439677 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 48386C4338F for ; Tue, 17 Aug 2021 00:55:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3168B60F14 for ; Tue, 17 Aug 2021 00:55:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236168AbhHQAz4 (ORCPT ); Mon, 16 Aug 2021 20:55:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235819AbhHQAzu (ORCPT ); Mon, 16 Aug 2021 20:55:50 -0400 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6508EC06179A for ; Mon, 16 Aug 2021 17:55:18 -0700 (PDT) Received: by mail-lj1-x233.google.com with SMTP id h17so30043423ljh.13 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=NQyb5YWSh5w6+eNcvtFRsb7DTKnSb1UKbElDRAikqb+NK2+TU0+xDdtGyfG12nuSrb ci0isCeijZ9cnbNFfUzN8IzNWVGCFlJwc0ZW3c1Q7fWHh8oaAjttIq2gRV5JGXOWYyFD Pg0sn6VphBR2kxoHG48JzC2lb0c6W9lXy9STrTlrgHk4jkhnYulYelLsZGTf5Xc1XTNI NusnMBIUWzBlWfNqzUaHGm3hcZDN0HyEuURWYmPhE5nbN5hlTaZI9gQcsQialSZHRvqD 7MQT3qXIRGi5lt2OCdd1oorc36dRQvSE97Hnl6hocPC7oDhFil0jTMXZMJM9H+3Pm4WT k8aw== X-Gm-Message-State: AOAM53169P0q/I+N2EyAfANPQ19i3vUEHMR4RIatCR5zH1APq5Hcm6hw t/9DjWbQlpQYFzBrh5jfC3KQ2Q== 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-bluetooth@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: 12439687 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 A9235C432BE for ; Tue, 17 Aug 2021 00:55:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 969C260295 for ; Tue, 17 Aug 2021 00:55:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236715AbhHQA4I (ORCPT ); Mon, 16 Aug 2021 20:56:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235874AbhHQAzv (ORCPT ); Mon, 16 Aug 2021 20:55:51 -0400 Received: from mail-lj1-x236.google.com (mail-lj1-x236.google.com [IPv6:2a00:1450:4864:20::236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1851EC0612E7 for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x236.google.com with SMTP id q21so8573173ljj.6 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=XAObNQB06eOfr84OaSLw8GMC5BWD5j1/gTY+n27gpACsGNfAmZORIXR3/CPwlo4Yb9 eFV4p5dvukXi8+xL9y8SSTMf1aszDalXdzKWjqJhx+UsaeiJRAzpr8JzzGvr2Bf1Q/4I QQB7hC0wxVxMHTYl7dWuxpRJ1mY1lOuv/f6eegceX5zcA8xr70NXUC1vT3bu5q5Uc+qc 9QXg4wl1NbTbAeT0Vz3jWYdCsR3ogHQyBLqf3ajIbNWeOK1vt+NHRMZ2GUTNqbq7SD1p 5eBYaXMDs+uQH/JzRjmzQvW7S6Q+Qo5o5zC9LCQ/YnbAAp5If0AhnivWjMeK5HCkwz9A ejog== X-Gm-Message-State: AOAM5327i8sFFk62dI9UbVRQNlmf1o6W3UfFmEFoGLmbDa4qKIaT0WJe EDCEuMQYkSP2U3KEeJNY0FA3FQ== 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-bluetooth@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: 12439675 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 2DDEBC432BE 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 1A66860FD8 for ; Tue, 17 Aug 2021 00:55:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236242AbhHQAz6 (ORCPT ); Mon, 16 Aug 2021 20:55:58 -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 S235953AbhHQAzw (ORCPT ); Mon, 16 Aug 2021 20:55:52 -0400 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CEEF6C06129F for ; Mon, 16 Aug 2021 17:55:19 -0700 (PDT) Received: by mail-lj1-x233.google.com with SMTP id d16so11986035ljq.4 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=CaBZ4zHbQgki5VHGEDjkayALTVpjDJZ/ODoxkhy/5AMU76YyOnJvjlOdmkDsbM52Wz gRKwwowkOG0wzZjy/UbfaccLzRXIlCrrmoJCauJa83UZemfVq+QgahBd32wv3Yg77gDe 2MDtYD561p21ABTNylMwOhFhLOX14bN1X1rKlG/INhuxPPdUk9UXsXdrxdIVzD9Zo2Ka CCp4pb98oqwxSXErc+qOXicm7E6p8Fbemeq9FFhfSPoFFWoCtgCr1+O47GekLFppbVVL MjtNTjGUeOAcfJUJjo1SBGTUVe6ufbg8D8LWPzabQQIew0Drj/SXhqxgJcp5wX2VnG6D ddGQ== X-Gm-Message-State: AOAM533NZBZE0Fd62mDE2HEgVhDKh+DRETHuBPOFOpeqiyBLEpkzwL3I w88vDraf1Qtx9QQY/zb59YXeqg== 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-bluetooth@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: 12439685 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 0141CC4338F for ; Tue, 17 Aug 2021 00:55:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC56D6054E for ; Tue, 17 Aug 2021 00:55:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236822AbhHQA4J (ORCPT ); Mon, 16 Aug 2021 20:56:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236003AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A09F5C0612AB for ; Mon, 16 Aug 2021 17:55:20 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id p38so38223592lfa.0 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=N2a8dnczUlF2rlKS56YPhfGQSmv8vlPNETqD8FlwwM8NfKQ237HcpleDCnPxzf0WHl /vW4EZEdWR8CVpSmLXnshYKN3cMdK8+eqs3nqKdxvt7nRVMm8gksWCzosi2ljRRedqYN xhjZKQPDqKWvwPnGNFBRixfZhfejznlzPcIC27wl+un+/TVcyY/+QFAJGZbY+CkGzo4X 4bYP8ZrwokDy11GmLECjOQKt/XSsEvUKEzzMotSJEFAaOrypijpHAsy7Xiu1I5z0sS8z 1zuRfo/CqTWiLIQf8GmBpekGnRHTUySdOdLa2eOTJ3E25GQGExzBgjKj1Mw9Rsfhaygs j8KQ== X-Gm-Message-State: AOAM531yhJRmd8fcJCjZM6H0P3y7H/KHjRakujBuUp5L3ZUD33JwYWmb kamG1gMnSk9Xt5i3Jya/9woMFg== 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-bluetooth@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: 12439679 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 073C9C43214 for ; Tue, 17 Aug 2021 00:55:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E58CA60F14 for ; Tue, 17 Aug 2021 00:55:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236898AbhHQA4L (ORCPT ); Mon, 16 Aug 2021 20:56:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40102 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236080AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7BAEFC061224 for ; Mon, 16 Aug 2021 17:55:21 -0700 (PDT) Received: by mail-lj1-x229.google.com with SMTP id y7so30167380ljp.3 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=kMbCekR4/Egiunh0nc/YdQiGVtxPVWQ5IOad17JY0iDq+ejzPWp9UipOuxp5FPkldr NVW6hI5JE0ber7KlBUitx6zkmFrTB/snRxjKNa7BhyRBf36ITMazeohPCt4UWC+Ec1/I zJmGg2GXi/84wmq//OWtvFwBqTFUqTbW22L0ZZjWnVwGMomAIJ/895qTfOtoyZF07qot u9CG4CCfdWwhIFbwiwOyvdXtD2c134yRqePVs4JQD/EDN9Gggyzul+ddYA8sWNAiQxKo XU5ep+8SD0fpx7IM0p7+s7GocdQ5muShEdNvIbR9yAxNmIhg9GPrzXDOPiEiQbMIfqSz DUAg== X-Gm-Message-State: AOAM531x6nboL5sLQbJX7xTomcDaTiPnmz/A+PT1YPB0x0qvCSlIiH+H LySAisaoHfOvde8a5NWn1OZyOw== 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-bluetooth@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: 12439695 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 8E17CC4320E for ; Tue, 17 Aug 2021 00:56:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7607D60EE0 for ; Tue, 17 Aug 2021 00:56:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237070AbhHQA4r (ORCPT ); Mon, 16 Aug 2021 20:56:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236095AbhHQAzy (ORCPT ); Mon, 16 Aug 2021 20:55:54 -0400 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E676C0613CF for ; Mon, 16 Aug 2021 17:55:22 -0700 (PDT) Received: by mail-lj1-x233.google.com with SMTP id n7so30226032ljq.0 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=fQ0HInia8aYqWFZfFF93c0qBkZUuhd7OKH5dvlqT2hf5wx2h1Md5m5txg0qu9dR9GH mNdAmtjjZeqOLrQ+xLu1A6p/V/f3pERVrJWMrirbTZvW049ki0hR8XDqVSf+i9q1Ia6T VFag7hem9dfShClsRBeF5wDUyGjey6F8re2B71Aoysmw6vFjGCJpZ1rc3QoywCqioDS6 uTAWczqP82MjBbn8BXquvJB5HJoLZvdofjlzi/p46EF3ewuM5xOpx/J4dwCuEqKfkt4+ DdrmK3dA/5FNT8JpXt2ZbWlyhmkmMJo8tYC72Ko33rEsaHqEEkbrV+reWdPG7qxLF9kS tM0Q== X-Gm-Message-State: AOAM533e3BpaDjZmiKniIk48A9XmXscOjPQGlAIkt+zNQ0az+zRnYYbR vr2RHcFpBmnIiSOsrNWTbNRgrQ== 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-bluetooth@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: 12439693 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 7FFCEC432BE for ; Tue, 17 Aug 2021 00:56:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B8FC6044F for ; Tue, 17 Aug 2021 00:56:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235870AbhHQA4o (ORCPT ); Mon, 16 Aug 2021 20:56:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236236AbhHQAz6 (ORCPT ); Mon, 16 Aug 2021 20:55:58 -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 03D95C0617AE for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lf1-x12f.google.com with SMTP id u22so6890454lfq.13 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=Mo1s9Up9ae+NaNLuwlgPJpsjFjf9Ek3WMHMfisWqa9ZxUMfPyDvFuT6ayk0FRcF9Zc q88qfOCmH9Iyv4VPiZMfWEH7DdsJNwnsQOOxaYC+Z6ty5WSFbrebo93u5GxtiIa2aubN ts2mwKpnwwdGLX4Tw15AtQEhN2HGqA7cwi192rgMFDgfmQnmf3Z/xKOQU5h5eHYuxfPh FnhoJO85Q/dOwK/SnXV6s2BQZ2nGnYXw9Wjga5ryMOFvfmszUBqchLosbwMVrdV+rlIn uXRrOgcDOyhoSRx6REsFrWuR1bSgPJji75/QDC4xtBQCooi2MeSVwGLGgM7ee/lxFcKr 0ueA== X-Gm-Message-State: AOAM530CMJutW5YiJOesgpRUM05FfBP9+JSa8CpWnrJeYZ6UHdH4Wzn5 A2WAFq6f04gV2YXxsL7DsTFDAw== 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-bluetooth@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: 12439699 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 81E41C4320E 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 6D85E60C40 for ; Tue, 17 Aug 2021 00:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236490AbhHQA4q (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 S236354AbhHQA4A (ORCPT ); Mon, 16 Aug 2021 20:56:00 -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 A0FB4C06129E for ; Mon, 16 Aug 2021 17:55:23 -0700 (PDT) Received: by mail-lj1-x22b.google.com with SMTP id c12so17068360ljr.5 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=YvY/0KWyw1jbn6oJH00l/i8t+oPyim/m6BjPF/cwW2mgI+xd6h/E2Z3uh4xwUDT08s 4gct4jS+WFd/w0/Sk6Qpv0KGYKw4wpN3cP5lsydGBqQPzGda43NAsMaLUQzv83TI7aNs UFrZh4bPSCXDlbqch1T8mKva56YFv3plKHkb84hV6Fci3R8Pjpbm+tI2QMxBPmZLOsv7 Lb0IwUpWB327OsQytLEean6Igrpb/S7maRyJgySXEItrrmxmFP1QCqAIegvwMHzqevFD f/u3g3xDl+d0qnQpR3bBcCsmMmrzIMIgQClRa9yKY8vulus8AF/e9S583J0Y6OwY5mpU r1nw== X-Gm-Message-State: AOAM530mAhLldiFWb4dzrfU/HSR8ZgLyiLFWpIamA4oCcYV5iSjsUMtT aA3T9w7IzPyyTHyk+lAIN9RQpA== 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-bluetooth@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: 12439691 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 9C2B1C41537 for ; Tue, 17 Aug 2021 00:56:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8AE47603E7 for ; Tue, 17 Aug 2021 00:56:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237400AbhHQA4c (ORCPT ); Mon, 16 Aug 2021 20:56:32 -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 S236730AbhHQA4I (ORCPT ); Mon, 16 Aug 2021 20:56:08 -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 7D918C0612A7 for ; Mon, 16 Aug 2021 17:55:24 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id h17so30043717ljh.13 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=E8tYClrfhyyFflIWlmHiI7YvT2VQ72DhzuHEzSzdE20pTNPLbWwNdYh6qRXl9NcU4x PbcqYQpfZ1ChVsasfIN8jttXj8EajGd1LurGFfkfyeJTDj4ZBxTsgu1qefMXdWrhdQX8 E4oAv1KHAFYPXJylkNg+Z8OH3hZI6YJK1WZOBeFtmzEV9dU2e9px9gy9hKf3Q3UZ/rfW wj+Q7XptxVztNbE+NZ4i8GUOvSdPkH6JGU4wKyZFV4HF9Qs5sedDOuqarvoMADSiKCRs sDTo7a2uEblt9J9cAVkAba2b3YCqRriaFq40fTexIWoXzKWRQ5etbvpbAGAwTyd54KAJ LmTQ== X-Gm-Message-State: AOAM532XwCzFBkoLGrKQsZAFfK/ezYCaYI7fLjVfvN/5B4N1B0+NNfWD 3QyrMVTaMqNAUafsz9FKN/LKEQ== 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-bluetooth@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: 12439681 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 1C488C43214 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 0D97460184 for ; Tue, 17 Aug 2021 00:55:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236828AbhHQA4S (ORCPT ); Mon, 16 Aug 2021 20:56:18 -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 S235874AbhHQA4J (ORCPT ); Mon, 16 Aug 2021 20:56:09 -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 32E92C0611F8 for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x22c.google.com with SMTP id q21so8573422ljj.6 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=LRcZYD24GmmEuKdBbhxWYQlunh8Qb+jOgfiZB/7rhfwFhwkcIqzB5fItCAIK+Qyl1+ sqVY7IRlbNnB5ks+IVxJ5fDcJoKfxLHotm9fAYC6KLin5eIfYLZ+Jj5Jihd7xG1MVEyy pG8NQiRQLguLmDGTYOJj4rJJoScVRMdyi7yAdUwAIs6JauEKrvAaS8sQOVxyt+HweZi9 vPPjOBMkDJ1+4AyFq0shyT7dK3V6mVqG4fxQ270j3iIrpeAUFvz1ZsRxsLrUiihoVtcx m923JneHond5VFn/F8T9tlLqfNnKkTPeJxIJZgXc/FdJI+YvIiD3mPGnu/oYsFKtj7Jj srQQ== X-Gm-Message-State: AOAM533fYX08YGLs6CjrDa3Kg3EOVOG7lGVAeHK3nuU2jsIh7K2/OYy5 DgbAywevDgEhxcJkWFFW7NSS7Q== 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-bluetooth@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: 12439683 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 BEEDFC4320E 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 A8B5E603E7 for ; Tue, 17 Aug 2021 00:55:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237089AbhHQA4R (ORCPT ); Mon, 16 Aug 2021 20:56:17 -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 S236860AbhHQA4K (ORCPT ); Mon, 16 Aug 2021 20:56:10 -0400 Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3166C0611BC for ; Mon, 16 Aug 2021 17:55:25 -0700 (PDT) Received: by mail-lj1-x231.google.com with SMTP id n7so30226214ljq.0 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=iGimVnhcW3v84DG5aHNQcwDMWjNPJsmqByzdqNMc4v/iW2nJspkgmX181r8/ftdTHI nlpiXGb6yyEjWyNca41G2sEtZFOvUeWoKCClBHFj+FBPdaeEJdM/zC0cF4DrVRat+k7c VTGLl7p1B/pjPztgaBhKmlKxPCJDfyKD0NE4EwHylpVelj+WKYF9HiDuFgMqrfopsHqV 9QjJs9/JQM8LKzu9N840h9TMGiyPBM3at/CtVJXEyItitKkImmIKe6xtM8ZiOqSwAAWN jFJF/Jco5ktueF0eeJPn+tHvCJRNz71EDLIuW+7kZA3icyJz+gl48vnHzs4ElG5l2W0g jblQ== X-Gm-Message-State: AOAM532y+XIjZOJz/QacGrgCADcDW74uev5QRn1XiFRfvwdDmF+4i+P2 u3zC5GpNrjcXu8v7p/LC64oDAw== 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-bluetooth@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: 12439689 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 7B5BAC4320A 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 65A7B603E7 for ; Tue, 17 Aug 2021 00:56:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237062AbhHQA42 (ORCPT ); Mon, 16 Aug 2021 20:56:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237005AbhHQA4N (ORCPT ); Mon, 16 Aug 2021 20:56:13 -0400 Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A144DC061141 for ; Mon, 16 Aug 2021 17:55:26 -0700 (PDT) Received: by mail-lf1-x130.google.com with SMTP id i28so11336432lfl.2 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=DK17qIf9CSPXn3D8cNLe8g/Y6dr9cc4qy7VXsLdWd/WJz0R+tz7kW/6ECysJHgB4su 3OX14WpihzH55Ip82yllQ2MzrV17xCYywEc1V+VPWdThTvHGoTdAyshW6uC1WHa+354e CGrIT7o/+ko61E35e/97bM9GPZteNGSzxpksKrsGF6sElgdkXpt0JOJgHZc7HbU2kQ1/ IAz4NJUCcJKcGTb8cc7fm47ec1K+oawvY+f1YF4OWX4d4yj8IuoDHkZxE0rlS8D8A/5F aIfWUGUSRlwA/7/EBdTb2eOIGYjri/yjgYOOPSS5tcbWG15PaEU4hK6piuxc4NB/vlhK /JCA== X-Gm-Message-State: AOAM533lGgvJ3S8CQnWpiNBn4rUMM96NWmq7KhX4SxBammRedLcsSH9T SmW3gd1qbBoRfj2GESkCSAgGDA== 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-bluetooth@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 {