Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp3572115imm; Wed, 5 Sep 2018 02:20:03 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdbl3nw9kCh4E7ZwsHVj0yHQonyyp4XA4pcLI8HQsKfvbDsjH2ImjVbQ9hIofdJZ5TV/bA3N X-Received: by 2002:a17:902:8506:: with SMTP id bj6-v6mr37265948plb.210.1536139203172; Wed, 05 Sep 2018 02:20:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536139203; cv=none; d=google.com; s=arc-20160816; b=UzmTbbPHBCFk/AcpuvtWJkROapWwpmUDcf/c3MJtZLAmfLppuMHb8B5a6Zqi79GKUJ PzMMdUEWZeDESls0AUy+A8dzQWk/AGy2MxFNeR86AJ06ATDR6ITRF0s+IHDPnbVOFG07 4R5mQUpXS/YeP+jMaGx+VF4SfXvARJy233g2yKMSvakROBx87PRyZvU8bBpLs3lGCSDB 3eVVUwTAezeIvL1HvExJ0tnfJZ2UcsaV8RuFbjLDHzeoMPKygtegp+RPa7Ukefja5i3/ 06s7DcimJGpiQAQwEaRbBejLUdEgAK8XN098iiDOt7oHTPt4r8GSSF2w6w/n24PcM5rz e/mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from; bh=6l6J8Cz+bUynKQFJdD6h+vpab5odPVTht2b/Q4DdDcs=; b=Hh8zvLb7qXA196jnwT2j9qJUxjjed41H//f02VfjcN6p/nW6qtzK1sYi5BKPRvXqw5 VMRwOeNgWKohlheJ1VWMELyQNu+h3XihriUTSXCMCBqIwGSmD5unSSZhqn9+oNNnFftA ORCfR861cL0ie/TljT6s2AFWaXF6rc5PX/b43XUX51PTJG9ZlQdx3sj7czyLznQx2m4V GcfyYkek9j3jpfItZLpDzPNzTOIX3tbjcl2U89qIOBVOiYZUbMmCEZYGgBN14IzMVsrP SqNnVcQxx+HE3/e71FnBdCMO53JmsBuGqbk0OWMNiRgbH94OQkUMlTeJZBBCZqQ3GTbU fu8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m124-v6si1510830pfm.303.2018.09.05.02.19.48; Wed, 05 Sep 2018 02:20:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728130AbeIENqM (ORCPT + 99 others); Wed, 5 Sep 2018 09:46:12 -0400 Received: from mail.bootlin.com ([62.4.15.54]:39619 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726090AbeIENqM (ORCPT ); Wed, 5 Sep 2018 09:46:12 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 556BD206F6; Wed, 5 Sep 2018 11:16:54 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost (AAubervilliers-681-1-92-107.w90-88.abo.wanadoo.fr [90.88.33.107]) by mail.bootlin.com (Postfix) with ESMTPSA id 1DB6220737; Wed, 5 Sep 2018 11:16:44 +0200 (CEST) From: Maxime Ripard To: Kishon Vijay Abraham I , Boris Brezillon Cc: Thomas Petazzoni , Laurent Pinchart , linux-media@vger.kernel.org, Archit Taneja , Andrzej Hajda , Chen-Yu Tsai , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, Krzysztof Witos , Rafal Ciepiela , Maxime Ripard Subject: [PATCH 02/10] phy: Add configuration interface Date: Wed, 5 Sep 2018 11:16:33 +0200 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The phy framework is only allowing to configure the power state of the PHY using the init and power_on hooks, and their power_off and exit counterparts. While it works for most, simple, PHYs supported so far, some more advanced PHYs need some configuration depending on runtime parameters. These PHYs have been supported by a number of means already, often by using ad-hoc drivers in their consumer drivers. That doesn't work too well however, when a consumer device needs to deal multiple PHYs, or when multiple consumers need to deal with the same PHY (a DSI driver and a CSI driver for example). So we'll add a new interface, through two funtions, phy_validate and phy_configure. The first one will allow to check that a current configuration, for a given mode, is applicable. It will also allow the PHY driver to tune the settings given as parameters as it sees fit. phy_configure will actually apply that configuration in the phy itself. Signed-off-by: Maxime Ripard --- drivers/phy/phy-core.c | 62 ++++++++++++++++++++++++++++++++++++++++++- include/linux/phy/phy.h | 42 ++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 35fd38c5a4a1..6eaf655e370f 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -408,6 +408,68 @@ int phy_calibrate(struct phy *phy) EXPORT_SYMBOL_GPL(phy_calibrate); /** + * phy_configure() - Changes the phy parameters + * @phy: the phy returned by phy_get() + * @mode: phy_mode the configuration is applicable to. + * @opts: New configuration to apply + * + * Used to change the PHY parameters. phy_init() must have + * been called on the phy. + * + * Returns: 0 if successful, an negative error code otherwise + */ +int phy_configure(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts) +{ + int ret; + + if (!phy) + return -EINVAL; + + if (!phy->ops->configure) + return 0; + + mutex_lock(&phy->mutex); + ret = phy->ops->configure(phy, mode, opts); + mutex_unlock(&phy->mutex); + + return ret; +} + +/** + * phy_validate() - Checks the phy parameters + * @phy: the phy returned by phy_get() + * @mode: phy_mode the configuration is applicable to. + * @opts: Configuration to check + * + * Used to check that the current set of parameters can be handled by + * the phy. Implementations are free to tune the parameters passed as + * arguments if needed by some implementation detail or + * constraints. It will not change any actual configuration of the + * PHY, so calling it as many times as deemed fit will have no side + * effect. + * + * Returns: 0 if successful, an negative error code otherwise + */ +int phy_validate(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts) +{ + int ret; + + if (!phy) + return -EINVAL; + + if (!phy->ops->validate) + return 0; + + mutex_lock(&phy->mutex); + ret = phy->ops->validate(phy, mode, opts); + mutex_unlock(&phy->mutex); + + return ret; +} + +/** * _of_phy_get() - lookup and obtain a reference to a phy by phandle * @np: device_node for which to get the phy * @index: the index of the phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 9cba7fe16c23..3cc315dcfcd0 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -44,6 +44,12 @@ enum phy_mode { }; /** + * union phy_configure_opts - Opaque generic phy configuration + */ +union phy_configure_opts { +}; + +/** * struct phy_ops - set of function pointers for performing phy operations * @init: operation to be performed for initializing phy * @exit: operation to be performed while exiting @@ -60,6 +66,38 @@ struct phy_ops { int (*power_on)(struct phy *phy); int (*power_off)(struct phy *phy); int (*set_mode)(struct phy *phy, enum phy_mode mode); + + /** + * @configure: + * + * Optional. + * + * Used to change the PHY parameters. phy_init() must have + * been called on the phy. + * + * Returns: 0 if successful, an negative error code otherwise + */ + int (*configure)(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts); + + /** + * @validate: + * + * Optional. + * + * Used to check that the current set of parameters can be + * handled by the phy. Implementations are free to tune the + * parameters passed as arguments if needed by some + * implementation detail or constraints. It must not change + * any actual configuration of the PHY, so calling it as many + * times as deemed fit by the consumer must have no side + * effect. + * + * Returns: 0 if the configuration can be applied, an negative + * error code otherwise + */ + int (*validate)(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts); int (*reset)(struct phy *phy); int (*calibrate)(struct phy *phy); struct module *owner; @@ -164,6 +202,10 @@ int phy_exit(struct phy *phy); int phy_power_on(struct phy *phy); int phy_power_off(struct phy *phy); int phy_set_mode(struct phy *phy, enum phy_mode mode); +int phy_configure(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts); +int phy_validate(struct phy *phy, enum phy_mode mode, + union phy_configure_opts *opts); static inline enum phy_mode phy_get_mode(struct phy *phy) { return phy->attrs.mode; -- git-series 0.9.1