From patchwork Sun Mar 26 17:00:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188372 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AB032C6FD1C for ; Sun, 26 Mar 2023 17:02:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=R35mCNTDN9csP+lPQzS4TNFUowYIiOnzIMTV5cg3t+g=; b=EDFuyYCnAuh6bg vs9eg8ZVpjo9gs3kkHiDwpNjj5TNbrItqPzzfh9Jf+nGBA7oqQj2PYbFrWHnxkKqBCNRyFJVm+k/9 gd0fp3DpBUhzs9zecfJcHyW0CPz5H2GPRUYcKABg3R5X5s174P5FnbY9UwiTa4QYi1DNLjxQXrkHF 6fephPEPRS2uA56jkKqXRkHN5KRSMGyeyJBTtCEXmQeNITfz+CGzLEUBDYjw+/n3eBWAFhpzaI/iy k1BC5l/beDd/6vvICK7ZLE3T/PvmgoHFVwhzS75o1FWTmqhK+OEOTJTbC4KAk+tJp/bw4H+Im8NCi Peu9jEbhc2IumcApGKIA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkJ-008qxl-0R; Sun, 26 Mar 2023 17:01:31 +0000 Received: from mail-ed1-x52d.google.com ([2a00:1450:4864:20::52d]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjm-008qq1-1F for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:00:59 +0000 Received: by mail-ed1-x52d.google.com with SMTP id eg48so26479260edb.13 for ; Sun, 26 Mar 2023 10:00:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850055; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GgdFnEC+G0UCGygoBkz7mAsO99oCv1F1QOJil/I+FSQ=; b=rSbRs0Ejz+MMl27sWojxGrzlH3aPN7wM/mRGklbiFbsSfzLE6SzDusJOrZmIGz89Sr eeVuXyjpeBnxO+O02Gwo/n6s8JMKjsR8vES1BqblAYE+XfmYSzIDvZ0MSK1jBWA8zHjU Lxsj9A8lpwGxaWjyg03HkOVceVnsFkzqERo1dxzw3LA49ehDc0jN2Vbw3Se+xao/NKpD TK354xn2UcUNSpsbFFJir3kjG2N0OzKLQqOrvNvQrz9lW9WPZtNOTMgA9vzBnVdOz8Y3 lj9VUlRgNTOZdkshZ4ylCM1wy5XQEq2eefSjI2MkuHuIlT71o9Rx99zwAR0kZs/CdCZO oAvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850055; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GgdFnEC+G0UCGygoBkz7mAsO99oCv1F1QOJil/I+FSQ=; b=0hpLHgqRKpsfzAz5T6Zt075EmMgyH1ZrCggsFrWV/e265EqpyjkjFJXxctZYMdklla iRVqgEVr5wBWVtAyqVv3nk0i1ju+k1b11yiwzQ9B9I0NotuoNnAFRhmCaQiMNxbQBp1g 9TTNyFYCa4grC6obuG07JyXsYaH72+en6kt4B9yaZFSacPmuKA+XORhoCoVQ/WWRktc+ UlIRlQ7Fx7om3JiKyT7bDjJWr8aSJu9N+HbAjS6MaPwGHIrZI+10KHkv43mP3LaPmV9X AyKZyFC0G3O4oUsnycYd2ZLITMOmsBcKpzajQj6hDJv/bLtXo1DemXIFD+5pTyEXgIbe WH9A== X-Gm-Message-State: AAQBX9ckGu8tWUiNoGvfJVJUV5xPXgkt4bebO5LQ8VrqAb/Kuvrs7NHb gETwz8cxwSN8LrZ0CU2Wgx5yEg== X-Google-Smtp-Source: AKy350YyNS3KsH2kUfOS1O4CATRcNe1sskoWPr1JyRQV1IsigQ2KYF8G1P2M2bXOhaWZiVn1xP/x+g== X-Received: by 2002:a17:907:3188:b0:8b1:781d:f9a4 with SMTP id xe8-20020a170907318800b008b1781df9a4mr10631709ejb.21.1679850055485; Sun, 26 Mar 2023 10:00:55 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id 27-20020a170906319b00b0093ba099fe64sm6650424ejy.182.2023.03.26.10.00.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:00:54 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 1/7] dpll: make ops function args const Date: Sun, 26 Mar 2023 19:00:46 +0200 Message-Id: <20230326170052.2065791-2-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100058_421399_9DB1A291 X-CRM114-Status: GOOD ( 11.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko Make ops args passed over *_register() functions const. Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_core.c | 25 ++++++++++++------------- include/linux/dpll.h | 9 +++++---- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index d478ab5e2001..7f8442b73fd8 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -89,7 +89,7 @@ dpll_device_get_by_name(const char *bus_name, const char *device_name) */ static int dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv) { struct dpll_pin_ref *ref; unsigned long i; @@ -189,7 +189,7 @@ dpll_xa_ref_pin_find(struct xarray *xa_pins, const struct dpll_pin *pin) */ static int dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, - struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv) { struct dpll_pin_ref *ref; unsigned long i; @@ -385,8 +385,9 @@ EXPORT_SYMBOL_GPL(dpll_device_put); * * 0 on success * * -EINVAL on failure */ -int dpll_device_register(struct dpll_device *dpll, struct dpll_device_ops *ops, - void *priv, struct device *owner) +int dpll_device_register(struct dpll_device *dpll, + const struct dpll_device_ops *ops, void *priv, + struct device *owner) { if (WARN_ON(!ops || !owner)) return -EINVAL; @@ -551,7 +552,7 @@ EXPORT_SYMBOL_GPL(dpll_pin_put); static int __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv, + const struct dpll_pin_ops *ops, void *priv, const char *rclk_device_name) { int ret; @@ -592,10 +593,9 @@ __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, * * -EINVAL - missing dpll or pin * * -ENOMEM - failed to allocate memory */ -int -dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv, - struct device *rclk_device) +int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv, + struct device *rclk_device) { const char *rclk_name = rclk_device ? dev_name(rclk_device) : NULL; int ret; @@ -661,10 +661,9 @@ EXPORT_SYMBOL_GPL(dpll_pin_unregister); * * -ENOMEM failed allocation * * -EPERM if parent is not allowed */ -int -dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv, - struct device *rclk_device) +int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv, + struct device *rclk_device) { struct dpll_pin_ref *ref; unsigned long i, stop; diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 2e516d91c343..496358df83a9 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -123,8 +123,9 @@ void dpll_device_put(struct dpll_device *dpll); * @owner: device struct of the owner * */ -int dpll_device_register(struct dpll_device *dpll, struct dpll_device_ops *ops, - void *priv, struct device *owner); +int dpll_device_register(struct dpll_device *dpll, + const struct dpll_device_ops *ops, void *priv, + struct device *owner); /** * dpll_device_unregister - deregister registered dpll @@ -200,7 +201,7 @@ struct dpll_pin * * -EBUSY - couldn't allocate id for a pin. */ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv, + const struct dpll_pin_ops *ops, void *priv, struct device *rclk_device); /** @@ -244,7 +245,7 @@ void dpll_pin_put(struct dpll_pin *pin); * * -EEXIST - pin already registered with this parent pin, */ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, - struct dpll_pin_ops *ops, void *priv, + const struct dpll_pin_ops *ops, void *priv, struct device *rclk_device); /** From patchwork Sun Mar 26 17:00:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 63378C761AF for ; Sun, 26 Mar 2023 17:02:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=+llWmHK7VUDGdN7R5JxeFlJLRPngJ6BYZU8QCU7O3IM=; b=HbOuqDwdvWyN9i tas2Des5JzsbB1ZoxtR6M57Pfx0ShBtuGcI4Rb9wMlOgxvR3lCD0tIuOF4/YJT6EUEjpxM6mLvRqW naDdfcruuvSYTN04Op9jFozrGW9ygkv0A5e//EZzvyHUgu9YCEf7THg9jyZ2OnHRnWPn37zCqa5zu YBqp7jSTG0MfpTqkxc9IGoa8FarDjhnTbkrF2yjsy8e5jOyfTiREkxcppCPKEUww/oFXpQU4rt/Vw vfWXB1l2Jna55mGclNG6MUdOdKYijKlf7aLAmu4CsT0WZdDJ/j4c6Hgl23qT40oXINmlHBIjONgB0 rP1ZDq72KMFTk1sPWPqQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkK-008qyL-0i; Sun, 26 Mar 2023 17:01:32 +0000 Received: from mail-ed1-x52f.google.com ([2a00:1450:4864:20::52f]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjm-008qqO-1U for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:00 +0000 Received: by mail-ed1-x52f.google.com with SMTP id eh3so26510777edb.11 for ; Sun, 26 Mar 2023 10:00:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850057; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jKvFgxFIOMcDomywgSDCrBRk0DXR5IUKz0LkYeOJtEs=; b=MqBkz9hDpJOSQidWrDvkJ50SCXAxGgp4KQaQ8as68UNv7r+sVy0Myx3RJ+JxS0ZWFy d8khfP7wEFyCx6DgShheqjpj9LRa9Q13baKFmGHjR4zUweb3OGaOGDkCAcQh6HNr+wX/ RPb14hkVRBOBwu+T950blOnTIkRPr5iA/Rp7TW2pM6Cmpju9g45PBpixLZRILCqB7/r2 uKDtc5sdPNJGCdk8qpxLT5V8RruB8MmKQ5kKvQvVa6fceDFUeV5+eedTl1YvmjlwZp3z Lgw7EVZx7lmKtKDBcBmWpLEPaOHh4ny5qzSs8YMxkUXgOdXQ7aLV2O1IYaTMWTvilQ9i cVJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850057; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jKvFgxFIOMcDomywgSDCrBRk0DXR5IUKz0LkYeOJtEs=; b=N5LR0Zsrj5aa9pIeYIy54s/QIjyABcoCzO7nCIXy2rmB9IBmzfWrpxRt+xyT2GN2Ux ZPIv3M/Vab97i75drW1UqSmoFAx5x9uAhBaOb3vMiw76NJffJ3+3IJ5953jjkaGzBaSq KX8pYLpOkUhsefaYL4f+92hqfx3zmQp3ULNE1fxZVw28lloaW5T3AtrB/K90YCM+rlpZ pOd1qs7/0/ETWs4F/YkohkFAvNaOK+d7xFNmAk8ATzHU3Up6HoqIEuZSTgJgyLu+Inqv B92cIwrYkPlkOx/kiHnwBssh6lap0QCBINXfeuqF4HCdlhC4aenKXAWQoDHilRe/0cIj ryJQ== X-Gm-Message-State: AAQBX9euuJANHSSR5T8yn/2i93bpixYuHMwy2MmGHda7vAUqxDjelmZj 607cwG+CrFz1MBr3cvm8Urklpg== X-Google-Smtp-Source: AKy350ZMSZEbVP7WntRh5N3QsB8+wW7gLpCzIK+IPhpkhbpXX0IYxYElgvFFPYGnqMCfRuH4dytvuw== X-Received: by 2002:a17:906:5fd9:b0:930:d17b:959b with SMTP id k25-20020a1709065fd900b00930d17b959bmr10024477ejv.22.1679850056882; Sun, 26 Mar 2023 10:00:56 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id w17-20020a170906b19100b0093fa8c2e877sm1996762ejy.80.2023.03.26.10.00.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:00:56 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 2/7] dpll: allow to call device register multiple times Date: Sun, 26 Mar 2023 19:00:47 +0200 Message-Id: <20230326170052.2065791-3-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100058_499402_D6F8B5F4 X-CRM114-Status: GOOD ( 22.59 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko Some devices allow to control a single dpll instance over multiple channels. In case of mlx5 for example, one dpll could be controlled over multiple PFs that reside on a single ASIC. These are equal. Allow each to register/unregister dpll device. Use the first ops and priv always as the is no difference in between those and the rest. Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_core.c | 85 +++++++++++++++++++++-- drivers/dpll/dpll_core.h | 11 ++- drivers/dpll/dpll_netlink.c | 29 ++++---- drivers/net/ethernet/intel/ice/ice_dpll.c | 4 +- drivers/ptp/ptp_ocp.c | 2 +- include/linux/dpll.h | 5 +- 6 files changed, 113 insertions(+), 23 deletions(-) diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index 7f8442b73fd8..6e50216a636a 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -293,6 +293,7 @@ dpll_device_alloc(const u64 clock_id, u32 dev_driver_id, if (!dpll) return ERR_PTR(-ENOMEM); refcount_set(&dpll->refcount, 1); + INIT_LIST_HEAD(&dpll->registration_list); dpll->dev.class = &dpll_class; dpll->dev_driver_id = dev_driver_id; dpll->clock_id = clock_id; @@ -366,12 +367,26 @@ void dpll_device_put(struct dpll_device *dpll) WARN_ON_ONCE(!xa_empty(&dpll->pin_refs)); xa_destroy(&dpll->pin_refs); xa_erase(&dpll_device_xa, dpll->id); + WARN_ON(!list_empty(&dpll->registration_list)); kfree(dpll); } mutex_unlock(&dpll_device_xa_lock); } EXPORT_SYMBOL_GPL(dpll_device_put); +static struct dpll_device_registration * +dpll_device_registration_find(struct dpll_device *dpll, + const struct dpll_device_ops *ops, void *priv) +{ + struct dpll_device_registration *reg; + + list_for_each_entry(reg, &dpll->registration_list, list) { + if (reg->ops == ops && reg->priv == priv) + return reg; + } + return NULL; +} + /** * dpll_device_register - register the dpll device in the subsystem * @dpll: pointer to a dpll @@ -389,19 +404,39 @@ int dpll_device_register(struct dpll_device *dpll, const struct dpll_device_ops *ops, void *priv, struct device *owner) { + struct dpll_device_registration *reg; + bool first_registration = false; + if (WARN_ON(!ops || !owner)) return -EINVAL; + mutex_lock(&dpll_device_xa_lock); - if (ASSERT_DPLL_NOT_REGISTERED(dpll)) { + reg = dpll_device_registration_find(dpll, ops, priv); + if (reg) { mutex_unlock(&dpll_device_xa_lock); return -EEXIST; } + + reg = kzalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) { + mutex_unlock(&dpll_device_xa_lock); + return -ENOMEM; + } + reg->ops = ops; + reg->priv = priv; + dpll->dev.bus = owner->bus; dpll->parent = owner; - dpll->ops = ops; dev_set_name(&dpll->dev, "%s_%d", dev_name(owner), dpll->dev_driver_id); - dpll->priv = priv; + + first_registration = list_empty(&dpll->registration_list); + list_add_tail(®->list, &dpll->registration_list); + if (!first_registration) { + mutex_unlock(&dpll_device_xa_lock); + return 0; + } + xa_set_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); mutex_unlock(&dpll_device_xa_lock); dpll_notify_device_create(dpll); @@ -413,14 +448,32 @@ EXPORT_SYMBOL_GPL(dpll_device_register); /** * dpll_device_unregister - deregister dpll device * @dpll: registered dpll pointer + * @ops: ops for a dpll device + * @priv: pointer to private information of owner * * Deregister device, make it unavailable for userspace. * Note: It does not free the memory */ -void dpll_device_unregister(struct dpll_device *dpll) +void dpll_device_unregister(struct dpll_device *dpll, + const struct dpll_device_ops *ops, void *priv) { + struct dpll_device_registration *reg; + mutex_lock(&dpll_device_xa_lock); ASSERT_DPLL_REGISTERED(dpll); + + reg = dpll_device_registration_find(dpll, ops, priv); + if (WARN_ON(!reg)) { + mutex_unlock(&dpll_device_xa_lock); + return; + } + list_del(®->list); + kfree(reg); + + if (!list_empty(&dpll->registration_list)) { + mutex_unlock(&dpll_device_xa_lock); + return; + } xa_clear_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); mutex_unlock(&dpll_device_xa_lock); dpll_notify_device_delete(dpll); @@ -760,6 +813,17 @@ struct dpll_pin *dpll_pin_get_by_idx(struct dpll_device *dpll, u32 idx) return NULL; } +static struct dpll_device_registration * +dpll_device_registration_first(struct dpll_device *dpll) +{ + struct dpll_device_registration *reg; + + reg = list_first_entry_or_null((struct list_head *) &dpll->registration_list, + struct dpll_device_registration, list); + WARN_ON(!reg); + return reg; +} + /** * dpll_priv - get the dpll device private owner data * @dpll: registered dpll pointer @@ -768,10 +832,21 @@ struct dpll_pin *dpll_pin_get_by_idx(struct dpll_device *dpll, u32 idx) */ void *dpll_priv(const struct dpll_device *dpll) { - return dpll->priv; + struct dpll_device_registration *reg; + + reg = dpll_device_registration_first((struct dpll_device *) dpll); + return reg->priv; } EXPORT_SYMBOL_GPL(dpll_priv); +const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) +{ + struct dpll_device_registration *reg; + + reg = dpll_device_registration_first(dpll); + return reg->ops; +} + /** * dpll_pin_on_dpll_priv - get the dpll device private owner data * @dpll: registered dpll pointer diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h index 876b6ac6f3a0..21ba31621b44 100644 --- a/drivers/dpll/dpll_core.h +++ b/drivers/dpll/dpll_core.h @@ -7,11 +7,18 @@ #define __DPLL_CORE_H__ #include +#include #include #include "dpll_netlink.h" #define DPLL_REGISTERED XA_MARK_1 +struct dpll_device_registration { + struct list_head list; + const struct dpll_device_ops *ops; + void *priv; +}; + /** * struct dpll_device - structure for a DPLL device * @id: unique id number for each device @@ -34,9 +41,8 @@ struct dpll_device { struct device dev; struct device *parent; struct module *module; - struct dpll_device_ops *ops; enum dpll_type type; - void *priv; + struct list_head registration_list; struct xarray pin_refs; u64 clock_id; unsigned long mode_supported_mask; @@ -84,6 +90,7 @@ struct dpll_pin_ref { refcount_t refcount; }; +const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll); struct dpll_device *dpll_device_get_by_id(int id); struct dpll_device *dpll_device_get_by_name(const char *bus_name, const char *dev_name); diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index d2c699015215..430c009d0a71 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -18,7 +18,7 @@ static u32 dpll_pin_freq_value[] = { }; static int -dpll_msg_add_dev_handle(struct sk_buff *msg, const struct dpll_device *dpll) +dpll_msg_add_dev_handle(struct sk_buff *msg, struct dpll_device *dpll) { if (nla_put_u32(msg, DPLL_A_ID, dpll->id)) return -EMSGSIZE; @@ -31,14 +31,15 @@ dpll_msg_add_dev_handle(struct sk_buff *msg, const struct dpll_device *dpll) } static int -dpll_msg_add_mode(struct sk_buff *msg, const struct dpll_device *dpll, +dpll_msg_add_mode(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) { + const struct dpll_device_ops *ops = dpll_device_ops(dpll); enum dpll_mode mode; - if (WARN_ON(!dpll->ops->mode_get)) + if (WARN_ON(!ops->mode_get)) return -EOPNOTSUPP; - if (dpll->ops->mode_get(dpll, &mode, extack)) + if (ops->mode_get(dpll, &mode, extack)) return -EFAULT; if (nla_put_u8(msg, DPLL_A_MODE, mode)) return -EMSGSIZE; @@ -50,11 +51,12 @@ static int dpll_msg_add_source_pin_idx(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) { + const struct dpll_device_ops *ops = dpll_device_ops(dpll); u32 source_pin_idx; - if (!dpll->ops->source_pin_idx_get) + if (!ops->source_pin_idx_get) return 0; - if (dpll->ops->source_pin_idx_get(dpll, &source_pin_idx, extack)) + if (ops->source_pin_idx_get(dpll, &source_pin_idx, extack)) return -EFAULT; if (nla_put_u32(msg, DPLL_A_SOURCE_PIN_IDX, source_pin_idx)) return -EMSGSIZE; @@ -66,11 +68,12 @@ static int dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) { + const struct dpll_device_ops *ops = dpll_device_ops(dpll); enum dpll_lock_status status; - if (WARN_ON(!dpll->ops->lock_status_get)) + if (WARN_ON(!ops->lock_status_get)) return -EOPNOTSUPP; - if (dpll->ops->lock_status_get(dpll, &status, extack)) + if (ops->lock_status_get(dpll, &status, extack)) return -EFAULT; if (nla_put_u8(msg, DPLL_A_LOCK_STATUS, status)) return -EMSGSIZE; @@ -82,11 +85,12 @@ static int dpll_msg_add_temp(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) { + const struct dpll_device_ops *ops = dpll_device_ops(dpll); s32 temp; - if (!dpll->ops->temp_get) + if (!ops->temp_get) return -EOPNOTSUPP; - if (dpll->ops->temp_get(dpll, &temp, extack)) + if (ops->temp_get(dpll, &temp, extack)) return -EFAULT; if (nla_put_s32(msg, DPLL_A_TEMP, temp)) return -EMSGSIZE; @@ -686,6 +690,7 @@ int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) static int dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info) { + const struct dpll_device_ops *ops = dpll_device_ops(dpll); struct nlattr *attr; enum dpll_mode mode; int rem, ret = 0; @@ -696,9 +701,9 @@ dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info) case DPLL_A_MODE: mode = nla_get_u8(attr); - if (!dpll->ops || !dpll->ops->mode_set) + if (!ops->mode_set) return -EOPNOTSUPP; - ret = dpll->ops->mode_set(dpll, mode, info->extack); + ret = ops->mode_set(dpll, mode, info->extack); if (ret) return ret; break; diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 87572ecc21e4..532ad7314f49 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1551,7 +1551,7 @@ static void ice_dpll_release_all(struct ice_pf *pf, bool cgu) if (dp->dpll) { mutex_lock(&pf->dplls.lock); if (cgu) - dpll_device_unregister(dp->dpll); + dpll_device_unregister(dp->dpll, &ice_dpll_ops, pf); dpll_device_put(dp->dpll); mutex_unlock(&pf->dplls.lock); dev_dbg(ice_pf_to_dev(pf), "PPS dpll removed\n"); @@ -1560,7 +1560,7 @@ static void ice_dpll_release_all(struct ice_pf *pf, bool cgu) if (de->dpll) { mutex_lock(&pf->dplls.lock); if (cgu) - dpll_device_unregister(de->dpll); + dpll_device_unregister(de->dpll, &ice_dpll_ops, pf); dpll_device_put(de->dpll); mutex_unlock(&pf->dplls.lock); dev_dbg(ice_pf_to_dev(pf), "EEC dpll removed\n"); diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index cc840d0e3265..5e7fceae2a6a 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -4431,7 +4431,7 @@ ptp_ocp_remove(struct pci_dev *pdev) struct ptp_ocp *bp = pci_get_drvdata(pdev); struct devlink *devlink = priv_to_devlink(bp); - dpll_device_unregister(bp->dpll); + dpll_device_unregister(bp->dpll, &dpll_ops, bp); dpll_device_put(bp->dpll); devlink_unregister(devlink); ptp_ocp_detach(bp); diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 496358df83a9..09863d66a44c 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -130,11 +130,14 @@ int dpll_device_register(struct dpll_device *dpll, /** * dpll_device_unregister - deregister registered dpll * @dpll: pointer to dpll + * @ops: ops for a dpll device + * @priv: pointer to private information of owner * * Unregister the dpll from the subsystem, make it unavailable for netlink * API users. */ -void dpll_device_unregister(struct dpll_device *dpll); +void dpll_device_unregister(struct dpll_device *dpll, + const struct dpll_device_ops *ops, void *priv); /** * dpll_priv - get dpll private data From patchwork Sun Mar 26 17:00:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4DD0AC74A5B for ; Sun, 26 Mar 2023 17:02:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Q3XaBLsniGfnvFWctl/MbN6qPSZGSK2aW77HKJQIEb4=; b=lDazsD1nzj/CaZ j2ZyBArNRAFexZEy/FOG5pgs8f+kg4mrk2LywUOz/hR85foRNfFInWE88TLC8mM1l2aZdmrU0IwSO iSoWi4LmCjJRL+Ylhy/xqb4WwjNPQyKtybSrORQby3OCxLJh+2/TyAJsFl9zbeGbmwRthCqunJqUl Jg/hDB3BtdaG/zyDCz28CeIDqXF0VERDE+/LoCEw/5Bjpw5wVDe+IovRBtsD3VmjHRcksgc+hTtP7 cyCyGJVSs5YvokozeeAausYAlIEFhZd4ISevfF+KPtoP2TfdEwr8jRCtD+Q7rNwJK+ATqHGX2xrlz Thv2vAF2JlvZWRikBlgQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkL-008qyn-1O; Sun, 26 Mar 2023 17:01:33 +0000 Received: from mail-ed1-x52f.google.com ([2a00:1450:4864:20::52f]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjn-008qqu-1t for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:01 +0000 Received: by mail-ed1-x52f.google.com with SMTP id eg48so26479533edb.13 for ; Sun, 26 Mar 2023 10:00:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850058; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=G9ZxDtIaWa6JS/i9pa4g+bZzhL99n85gnvJfpee8Jl8=; b=x53ZrdJ9DaTRVfmR9rAfOoLh6eAY6wPjpKcxw8+0btXTlch/Agw3cDQjeVdpzVYwMF FqQowgDd6PFzuH1/AhNqveBsTO7JDT8Tpm1+qDwFEndg09eHfjYyEb3Mg5Cb5AiEfQzd 8hzdgm4zh0NC3GJpSHO43szexqhv1HiibAwlP8pLLcqJ6+emGnKha1aaPqmCQUxXg+0g XjAdTDNhJYOh8nS4wCo+EgDWZzB9532KoCPL+HEnaEkPOxhByYiSG3hizfgw6GyPEVZ/ 9eBOjTmq9bUVJ4gUOdtkpBqNZBOfPDYLGwFNso0hUF+AU8tpCcoPM+iczh0jIzi0m0h9 3Pww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850058; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G9ZxDtIaWa6JS/i9pa4g+bZzhL99n85gnvJfpee8Jl8=; b=K3uTijm+OHvtK3H4rzFuPVy/hYZ6V5RgzuYypWqAokdV8gtRPEHzB2c9sLWqPbFs+N Iz6nU+B+/PvoOS+P9ciOLFyWTjWv9dp6pW7ecmVDWIMB2jHL2MQ7NRT/Iwpn1IJGSvVf Yr5JHso7JQmCt+v87lzylBLMNvEiYU3hCjHufXvFfh47vWPILHmR7BzMsQRQ6xRqmviu c90+iU4XbGfYhRDomTWbwW1610rLgqEVNlQfAkJ+rLU1wxHNmEcRi2HZB0xlw6fHC01A a4lrFyABsAl7c2dCUCEdQR3yMEu3iYEScrDMFNOSXnVLfJiObHBnM9owdp2YfV61kvif wa2Q== X-Gm-Message-State: AAQBX9c7bEwD+d8/nNmDRm5LyKgHodkj8kgk/M0gQncEn9SXNLWMX4Md u0iUS5gjoblO1+uCVzZxPL68mw== X-Google-Smtp-Source: AKy350Y5aQWqa9W2mRHP1x54fuPjQgpetEBmUNq81mEiwA2RuH5Nf8qb4iSMUWnV9kRNgeyh6Inzmg== X-Received: by 2002:a17:907:77d2:b0:886:50d:be8d with SMTP id kz18-20020a17090777d200b00886050dbe8dmr10980768ejc.13.1679850058382; Sun, 26 Mar 2023 10:00:58 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id ha8-20020a170906a88800b0093a6c591743sm7745266ejb.69.2023.03.26.10.00.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:00:57 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 3/7] dpll: introduce a helper to get first dpll ref and use it Date: Sun, 26 Mar 2023 19:00:48 +0200 Message-Id: <20230326170052.2065791-4-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100059_632187_0DC2F0E9 X-CRM114-Status: GOOD ( 16.58 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko No need to iterate xaarray in dpll_msg_add_pin_direction() and dpll_msg_add_pin_freq(). Just introduce a helper to get the first dpll reference and use that. Add a check for ops not being null in pin_register() function, not only for sake of this change, but also for the sake of existing code relying on it. Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_core.c | 12 ++++++++++++ drivers/dpll/dpll_core.h | 1 + drivers/dpll/dpll_netlink.c | 34 ++++++++++++---------------------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index 6e50216a636a..2f788d2349fe 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -267,6 +267,15 @@ dpll_xa_ref_dpll_find(struct xarray *xa_refs, const struct dpll_device *dpll) return NULL; } +struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs) +{ + struct dpll_pin_ref *ref; + unsigned long i = 0; + + ref = xa_find(xa_refs, &i, ULONG_MAX, XA_PRESENT); + WARN_ON(!ref); + return ref; +} /** * dpll_device_alloc - allocate the memory for dpll device @@ -610,6 +619,9 @@ __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, { int ret; + if (WARN_ON(!ops)) + return -EINVAL; + if (rclk_device_name && !pin->rclk_dev_name) { pin->rclk_dev_name = kstrdup(rclk_device_name, GFP_KERNEL); if (!pin->rclk_dev_name) diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h index 21ba31621b44..636dd4c6710e 100644 --- a/drivers/dpll/dpll_core.h +++ b/drivers/dpll/dpll_core.h @@ -99,6 +99,7 @@ struct dpll_pin_ref * dpll_xa_ref_pin_find(struct xarray *xa_refs, const struct dpll_pin *pin); struct dpll_pin_ref * dpll_xa_ref_dpll_find(struct xarray *xa_refs, const struct dpll_device *dpll); +struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs); extern struct xarray dpll_device_xa; extern struct xarray dpll_pin_xa; extern struct mutex dpll_device_xa_lock; diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 430c009d0a71..41e2f8a90aeb 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -134,18 +134,11 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, const struct dpll_pin *pin, static int dpll_msg_add_pin_direction(struct sk_buff *msg, const struct dpll_pin *pin, + struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) { enum dpll_pin_direction direction; - struct dpll_pin_ref *ref; - unsigned long i; - xa_for_each((struct xarray *)&pin->dpll_refs, i, ref) { - if (ref && ref->ops && ref->dpll) - break; - } - if (!ref || !ref->ops || !ref->dpll) - return -ENODEV; if (!ref->ops->direction_get) return -EOPNOTSUPP; if (ref->ops->direction_get(pin, ref->dpll, &direction, extack)) @@ -158,19 +151,12 @@ dpll_msg_add_pin_direction(struct sk_buff *msg, const struct dpll_pin *pin, static int dpll_msg_add_pin_freq(struct sk_buff *msg, const struct dpll_pin *pin, - struct netlink_ext_ack *extack, bool dump_any_freq) + struct dpll_pin_ref *ref, struct netlink_ext_ack *extack, + bool dump_any_freq) { enum dpll_pin_freq_supp fs; - struct dpll_pin_ref *ref; - unsigned long i; u32 freq; - xa_for_each((struct xarray *)&pin->dpll_refs, i, ref) { - if (ref && ref->ops && ref->dpll) - break; - } - if (!ref || !ref->ops || !ref->dpll) - return -ENODEV; if (!ref->ops->frequency_get) return -EOPNOTSUPP; if (ref->ops->frequency_get(pin, ref->dpll, &freq, extack)) @@ -325,10 +311,11 @@ dpll_cmd_pin_on_dpll_get(struct sk_buff *msg, struct dpll_pin *pin, return -EMSGSIZE; if (nla_put_u32(msg, DPLL_A_PIN_DPLL_CAPS, pin->prop.capabilities)) return -EMSGSIZE; - ret = dpll_msg_add_pin_direction(msg, pin, extack); + ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); + ret = dpll_msg_add_pin_direction(msg, pin, ref, extack); if (ret) return ret; - ret = dpll_msg_add_pin_freq(msg, pin, extack, true); + ret = dpll_msg_add_pin_freq(msg, pin, ref, extack, true); if (ret && ret != -EOPNOTSUPP) return ret; ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll); @@ -355,6 +342,7 @@ static int __dpll_cmd_pin_dump_one(struct sk_buff *msg, struct dpll_pin *pin, struct netlink_ext_ack *extack, bool dump_dpll) { + struct dpll_pin_ref *ref; int ret; if (nla_put_u32(msg, DPLL_A_PIN_IDX, pin->dev_driver_id)) @@ -363,10 +351,11 @@ __dpll_cmd_pin_dump_one(struct sk_buff *msg, struct dpll_pin *pin, return -EMSGSIZE; if (nla_put_u8(msg, DPLL_A_PIN_TYPE, pin->prop.type)) return -EMSGSIZE; - ret = dpll_msg_add_pin_direction(msg, pin, extack); + ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); + ret = dpll_msg_add_pin_direction(msg, pin, ref, extack); if (ret) return ret; - ret = dpll_msg_add_pin_freq(msg, pin, extack, true); + ret = dpll_msg_add_pin_freq(msg, pin, ref, extack, true); if (ret && ret != -EOPNOTSUPP) return ret; ret = dpll_msg_add_pins_on_pin(msg, pin, extack); @@ -920,7 +909,8 @@ dpll_event_device_change(struct sk_buff *msg, struct dpll_device *dpll, ret = dpll_msg_add_temp(msg, dpll, NULL); break; case DPLL_A_PIN_FREQUENCY: - ret = dpll_msg_add_pin_freq(msg, pin, NULL, false); + ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll); + ret = dpll_msg_add_pin_freq(msg, pin, ref, NULL, false); break; case DPLL_A_PIN_PRIO: ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll); From patchwork Sun Mar 26 17:00:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188375 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 007A2C6FD1C for ; Sun, 26 Mar 2023 17:02:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=90dg0CWxQbHRgjFH475LRwmJDO1nYOM6PLKPvn17bEg=; b=o3Ep6ufsHhtxmt IxelvaVI0UpPoi4stDijqndWSCSJ1KscitkiEHJSfTWLOm5Lus8m413i+U7x5g9OxhHhe6xMGmzFZ U9K8F4xd0Q2sw8PJYq+paKzpfyI4jo+LpdfsjFDgZyBotkCR5VZlqzuuGDBAHkw7z89qNhGNCsv2p L81d+BX/EaRHpOAyJotbfE9IkQEl6KtQ8X9OBIE4NUJ/eJieYgZz7/Mw591rnHNKdxvkJ7Sk0JrWg Vk5hCS/e4cIquLbdfhhPuqypzTTPmgBCVC8+2wG3mstXX3UvVlNw8x6bKzvjsyz5NQc9ZvEKcZHMo AeyvDW12mgL4AkEMXIwg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkP-008r0f-01; Sun, 26 Mar 2023 17:01:37 +0000 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjr-008qre-0r for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:09 +0000 Received: by mail-ed1-x535.google.com with SMTP id r11so26608225edd.5 for ; Sun, 26 Mar 2023 10:01:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=668o2k4Nn1fxnXh54mywli34jSX4IoNNpKzsc6h/awQ=; b=Xoa5KgJ08Zo4I18MXAfK4jZv6x2ycI0dUMCvDutflAM4KBUxE1fPfGXfIEqLzv25KT uVNNeCBbbgvUtKd0OwA7tOBLajKVIqqXYm+3eDrFJbNTFrJApH37BAw+hFEQ0LvO9Af5 YEqb8iqvDUKQwRlLpHvnmG73p7snY/uBkg6zpbF7kBtR8ihS22kqDZ4iCZArrB1kKJPR 7+R7R4DsCFP5jb18h0TgEy6waXzgU3F+XtdLy+J21tTr/9ZPoXvoUUF5ZvPZRM0xPCMj 40mr4sXgEDWxmpDBr0qJNnAJRSAU/fhI/Lys/hYhfg8hDuWANE6/yFyHBNdDffPvOsSY dzBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=668o2k4Nn1fxnXh54mywli34jSX4IoNNpKzsc6h/awQ=; b=gMlqoIXn+CL9/pXF2AC8Awyr0jbjmeN/BlxgtNeXBu6yNdeIqrN+uMt4jIRqG02+gU YP+2Ubg9qJRoAgU60Mzc9Wdg1b87W2szMJBqIN9CYF7Xar6hc58K2BztIiDw4ScYiA1m WFGCzs3Lx7vWehebJeRmO0Fe7wF/qpTIoms1c1VARBwz/5C2Cqoo6oAJzN9tuWCVANsL r4UE7F1HtmDXboSpKtN828uZJY0vEchqronywJLwrysdCh6ZJnEWyiREHlAQhlf9ew7o yxbqafpG6jDWhZtqlwJgQhJed+b7/3MznfYNsDiQFEC4dJBW7WS8TQfX5AtzuCt45XXn gbgw== X-Gm-Message-State: AAQBX9fJ63kuZZ1itP36B7S4m4Skh76MiiOYhMLc1yGwNcfQWtlg0bLo /srOxhKJEOqtNXBLRL5ol6zhvA== X-Google-Smtp-Source: AKy350aDM78BliaPSmIQXAF7QZlXug3YwSHicTayVwm1NuE+noFc+cwTmnEeawHX7ilYH8pc1DnafA== X-Received: by 2002:a17:906:ca0c:b0:930:1914:88fe with SMTP id jt12-20020a170906ca0c00b00930191488femr9309271ejb.68.1679850059899; Sun, 26 Mar 2023 10:00:59 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id c24-20020a50d658000000b00501d5432f2fsm8837945edj.60.2023.03.26.10.00.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:00:59 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 4/7] dpll: allow to call pin register multiple times Date: Sun, 26 Mar 2023 19:00:49 +0200 Message-Id: <20230326170052.2065791-5-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100105_543441_22BD6589 X-CRM114-Status: GOOD ( 22.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko Some devices allow to control a single dpll pin instance over multiple channels. In case of mlx5 for example, one dpll pin could be controlled over multiple PFs that reside on a single ASIC. These are equal. Allow each to register/unregister dpll pin. Use the first ops and priv always as the is no difference in between those and the rest. Replace the existing reference counting by the list of registrations as they serve the same purpose. Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_core.c | 212 +++++++++++++++------- drivers/dpll/dpll_core.h | 13 +- drivers/dpll/dpll_netlink.c | 69 ++++--- drivers/net/ethernet/intel/ice/ice_dpll.c | 18 +- include/linux/dpll.h | 8 +- 5 files changed, 220 insertions(+), 100 deletions(-) diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index 2f788d2349fe..dfff3e07fe43 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -73,6 +73,19 @@ dpll_device_get_by_name(const char *bus_name, const char *device_name) return ret; } +static struct dpll_pin_registration * +dpll_pin_registration_find(struct dpll_pin_ref *ref, + const struct dpll_pin_ops *ops, void *priv) +{ + struct dpll_pin_registration *reg; + + list_for_each_entry(reg, &ref->registration_list, list) { + if (reg->ops == ops && reg->priv == priv) + return reg; + } + return NULL; +} + /** * dpll_xa_ref_pin_add - add pin reference to a given xarray * @xa_pins: dpll_pin_ref xarray holding pins @@ -80,8 +93,8 @@ dpll_device_get_by_name(const char *bus_name, const char *device_name) * @ops: ops for a pin * @priv: pointer to private data of owner * - * Allocate and create reference of a pin or increase refcount on existing pin - * reference on given xarray. + * Allocate and create reference of a pin and enlist a registration + * structure storing ops and priv pointers of a caller registant. * * Return: * * 0 on success @@ -91,31 +104,48 @@ static int dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, const struct dpll_pin_ops *ops, void *priv) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; + bool ref_exists = false; unsigned long i; u32 idx; int ret; xa_for_each(xa_pins, i, ref) { - if (ref->pin == pin) { - refcount_inc(&ref->refcount); - return 0; + if (ref->pin != pin) + continue; + reg = dpll_pin_registration_find(ref, ops, priv); + if (reg) + return -EEXIST; + ref_exists = true; + break; + } + + if (!ref_exists) { + ref = kzalloc(sizeof(*ref), GFP_KERNEL); + if (!ref) + return -ENOMEM; + ref->pin = pin; + INIT_LIST_HEAD(&ref->registration_list); + ret = xa_alloc(xa_pins, &idx, ref, xa_limit_16b, GFP_KERNEL); + if (ret) { + kfree(ref); + return ret; } } - ref = kzalloc(sizeof(*ref), GFP_KERNEL); - if (!ref) + reg = kzalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) { + if (!ref_exists) + kfree(ref); return -ENOMEM; - ref->pin = pin; - ref->ops = ops; - ref->priv = priv; - ret = xa_alloc(xa_pins, &idx, ref, xa_limit_16b, GFP_KERNEL); - if (!ret) - refcount_set(&ref->refcount, 1); - else - kfree(ref); + } + reg->ops = ops; + reg->priv = priv; - return ret; + list_add_tail(®->list, &ref->registration_list); + + return 0; } /** @@ -124,25 +154,31 @@ dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, * @pin: pointer to a pin * * Decrement refcount of existing pin reference on given xarray. - * If all references are dropped, delete the reference and free its memory. + * If all registrations are lifted delete the reference and free its memory. * * Return: * * 0 on success * * -EINVAL if reference to a pin was not found */ -static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin) +static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; unsigned long i; xa_for_each(xa_pins, i, ref) { - if (ref->pin == pin) { - if (refcount_dec_and_test(&ref->refcount)) { - xa_erase(xa_pins, i); - kfree(ref); - } - return 0; - } + if (ref->pin != pin) + continue; + reg = dpll_pin_registration_find(ref, ops, priv); + if (WARN_ON(!reg)) + return -EINVAL; + list_del(®->list); + kfree(reg); + xa_erase(xa_pins, i); + WARN_ON(!list_empty(&ref->registration_list)); + kfree(ref); + return 0; } return -EINVAL; @@ -191,30 +227,48 @@ static int dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, const struct dpll_pin_ops *ops, void *priv) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; + bool ref_exists = false; unsigned long i; u32 idx; int ret; xa_for_each(xa_dplls, i, ref) { - if (ref->dpll == dpll) { - refcount_inc(&ref->refcount); - return 0; + if (ref->dpll != dpll) + continue; + reg = dpll_pin_registration_find(ref, ops, priv); + if (reg) + return -EEXIST; + ref_exists = true; + break; + } + + if (!ref_exists) { + ref = kzalloc(sizeof(*ref), GFP_KERNEL); + if (!ref) + return -ENOMEM; + ref->dpll = dpll; + INIT_LIST_HEAD(&ref->registration_list); + ret = xa_alloc(xa_dplls, &idx, ref, xa_limit_16b, GFP_KERNEL); + if (ret) { + kfree(ref); + return ret; } } - ref = kzalloc(sizeof(*ref), GFP_KERNEL); - if (!ref) + + reg = kzalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) { + if (!ref_exists) + kfree(ref); return -ENOMEM; - ref->dpll = dpll; - ref->ops = ops; - ref->priv = priv; - ret = xa_alloc(xa_dplls, &idx, ref, xa_limit_16b, GFP_KERNEL); - if (!ret) - refcount_set(&ref->refcount, 1); - else - kfree(ref); + } + reg->ops = ops; + reg->priv = priv; - return ret; + list_add_tail(®->list, &ref->registration_list); + + return 0; } /** @@ -226,19 +280,25 @@ dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, * If all references are dropped, delete the reference and free its memory. */ static void -dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll) +dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll, + const struct dpll_pin_ops *ops, void *priv) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; unsigned long i; xa_for_each(xa_dplls, i, ref) { - if (ref->dpll == dpll) { - if (refcount_dec_and_test(&ref->refcount)) { - xa_erase(xa_dplls, i); - kfree(ref); - } - break; - } + if (ref->dpll != dpll) + continue; + reg = dpll_pin_registration_find(ref, ops, priv); + if (WARN_ON(!reg)) + return; + list_del(®->list); + kfree(reg); + xa_erase(xa_dplls, i); + WARN_ON(!list_empty(&ref->registration_list)); + kfree(ref); + return; } } @@ -639,7 +699,7 @@ __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, return ret; ref_pin_del: - dpll_xa_ref_pin_del(&dpll->pin_refs, pin); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); rclk_free: kfree(pin->rclk_dev_name); return ret; @@ -681,27 +741,31 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, EXPORT_SYMBOL_GPL(dpll_pin_register); static void -__dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin) +__dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv) { - dpll_xa_ref_pin_del(&dpll->pin_refs, pin); - dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); + dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv); } /** * dpll_pin_unregister - deregister dpll pin from dpll device * @dpll: registered dpll pointer * @pin: pointer to a pin + * @ops: ops for a dpll pin ops + * @priv: pointer to private information of owner * * Note: It does not free the memory */ -int dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin) +int dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv) { if (WARN_ON(xa_empty(&dpll->pin_refs))) return -ENOENT; mutex_lock(&dpll_device_xa_lock); mutex_lock(&dpll_pin_xa_lock); - __dpll_pin_unregister(dpll, pin); + __dpll_pin_unregister(dpll, pin, ops, priv); mutex_unlock(&dpll_pin_xa_lock); mutex_unlock(&dpll_device_xa_lock); @@ -763,12 +827,12 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, xa_for_each(&parent->dpll_refs, i, ref) { if (i < stop) { mutex_lock(&dpll_device_xa_lock); - __dpll_pin_unregister(ref->dpll, pin); + __dpll_pin_unregister(ref->dpll, pin, ops, priv); mutex_unlock(&dpll_device_xa_lock); } } refcount_dec(&pin->refcount); - dpll_xa_ref_pin_del(&pin->parent_refs, parent); + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); unlock: mutex_unlock(&dpll_pin_xa_lock); return ret; @@ -779,20 +843,23 @@ EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); * dpll_pin_on_pin_unregister - deregister dpll pin from a parent pin * @parent: pointer to a parent pin * @pin: pointer to a pin + * @ops: ops for a dpll pin + * @priv: pointer to private information of owner * * Note: It does not free the memory */ -void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin) +void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv) { struct dpll_pin_ref *ref; unsigned long i; mutex_lock(&dpll_device_xa_lock); mutex_lock(&dpll_pin_xa_lock); - dpll_xa_ref_pin_del(&pin->parent_refs, parent); + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); refcount_dec(&pin->refcount); xa_for_each(&pin->dpll_refs, i, ref) { - __dpll_pin_unregister(ref->dpll, pin); + __dpll_pin_unregister(ref->dpll, pin, ops, priv); dpll_pin_parent_notify(ref->dpll, pin, parent, DPLL_A_PIN_IDX); } @@ -859,6 +926,17 @@ const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) return reg->ops; } +static struct dpll_pin_registration * +dpll_pin_registration_first(struct dpll_pin_ref *ref) +{ + struct dpll_pin_registration *reg; + + reg = list_first_entry_or_null(&ref->registration_list, + struct dpll_pin_registration, list); + WARN_ON(!reg); + return reg; +} + /** * dpll_pin_on_dpll_priv - get the dpll device private owner data * @dpll: registered dpll pointer @@ -869,13 +947,14 @@ const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) void *dpll_pin_on_dpll_priv(const struct dpll_device *dpll, const struct dpll_pin *pin) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; ref = dpll_xa_ref_pin_find((struct xarray *)&dpll->pin_refs, pin); if (!ref) return NULL; - - return ref->priv; + reg = dpll_pin_registration_first(ref); + return reg->priv; } EXPORT_SYMBOL_GPL(dpll_pin_on_dpll_priv); @@ -889,16 +968,25 @@ EXPORT_SYMBOL_GPL(dpll_pin_on_dpll_priv); void *dpll_pin_on_pin_priv(const struct dpll_pin *parent, const struct dpll_pin *pin) { + struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; ref = dpll_xa_ref_pin_find((struct xarray *)&pin->parent_refs, parent); if (!ref) return NULL; - - return ref->priv; + reg = dpll_pin_registration_first(ref); + return reg->priv; } EXPORT_SYMBOL_GPL(dpll_pin_on_pin_priv); +const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref) +{ + struct dpll_pin_registration *reg; + + reg = dpll_pin_registration_first(ref); + return reg->ops; +} + static int __init dpll_init(void) { int ret; diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h index 636dd4c6710e..2ab2d9e0a3cd 100644 --- a/drivers/dpll/dpll_core.h +++ b/drivers/dpll/dpll_core.h @@ -73,27 +73,30 @@ struct dpll_pin { refcount_t refcount; }; +struct dpll_pin_registration { + struct list_head list; + const struct dpll_pin_ops *ops; + void *priv; +}; + /** * struct dpll_pin_ref - structure for referencing either dpll or pins * @dpll: pointer to a dpll * @pin: pointer to a pin - * @ops: ops for a dpll pin - * @priv: pointer to private information of owner **/ struct dpll_pin_ref { union { struct dpll_device *dpll; struct dpll_pin *pin; }; - struct dpll_pin_ops *ops; - void *priv; - refcount_t refcount; + struct list_head registration_list; }; const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll); struct dpll_device *dpll_device_get_by_id(int id); struct dpll_device *dpll_device_get_by_name(const char *bus_name, const char *dev_name); +const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref); struct dpll_pin *dpll_pin_get_by_idx(struct dpll_device *dpll, u32 idx); struct dpll_pin_ref * dpll_xa_ref_pin_find(struct xarray *xa_refs, const struct dpll_pin *pin); diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 41e2f8a90aeb..125dc3c7e643 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -103,11 +103,12 @@ dpll_msg_add_pin_prio(struct sk_buff *msg, const struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); u32 prio; - if (!ref->ops->prio_get) + if (!ops->prio_get) return -EOPNOTSUPP; - if (ref->ops->prio_get(pin, ref->dpll, &prio, extack)) + if (ops->prio_get(pin, ref->dpll, &prio, extack)) return -EFAULT; if (nla_put_u32(msg, DPLL_A_PIN_PRIO, prio)) return -EMSGSIZE; @@ -120,11 +121,12 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, const struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); enum dpll_pin_state state; - if (!ref->ops->state_on_dpll_get) + if (!ops->state_on_dpll_get) return -EOPNOTSUPP; - if (ref->ops->state_on_dpll_get(pin, ref->dpll, &state, extack)) + if (ops->state_on_dpll_get(pin, ref->dpll, &state, extack)) return -EFAULT; if (nla_put_u8(msg, DPLL_A_PIN_STATE, state)) return -EMSGSIZE; @@ -137,11 +139,12 @@ dpll_msg_add_pin_direction(struct sk_buff *msg, const struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); enum dpll_pin_direction direction; - if (!ref->ops->direction_get) + if (!ops->direction_get) return -EOPNOTSUPP; - if (ref->ops->direction_get(pin, ref->dpll, &direction, extack)) + if (ops->direction_get(pin, ref->dpll, &direction, extack)) return -EFAULT; if (nla_put_u8(msg, DPLL_A_PIN_DIRECTION, direction)) return -EMSGSIZE; @@ -154,12 +157,13 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, const struct dpll_pin *pin, struct dpll_pin_ref *ref, struct netlink_ext_ack *extack, bool dump_any_freq) { + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); enum dpll_pin_freq_supp fs; u32 freq; - if (!ref->ops->frequency_get) + if (!ops->frequency_get) return -EOPNOTSUPP; - if (ref->ops->frequency_get(pin, ref->dpll, &freq, extack)) + if (ops->frequency_get(pin, ref->dpll, &freq, extack)) return -EFAULT; if (nla_put_u32(msg, DPLL_A_PIN_FREQUENCY, freq)) return -EMSGSIZE; @@ -196,10 +200,12 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin, int ret; xa_for_each(&pin->parent_refs, index, ref_parent) { - if (WARN_ON(!ref_parent->ops->state_on_pin_get)) + const struct dpll_pin_ops *ops = dpll_pin_ops(ref_parent); + + if (WARN_ON(!ops->state_on_pin_get)) return -EFAULT; - ret = ref_parent->ops->state_on_pin_get(pin, ref_parent->pin, - &state, extack); + ret = ops->state_on_pin_get(pin, ref_parent->pin, + &state, extack); if (ret) return -EFAULT; nest = nla_nest_start(msg, DPLL_A_PIN_PARENT); @@ -235,10 +241,11 @@ dpll_msg_add_pins_on_pin(struct sk_buff *msg, struct dpll_pin *pin, int ret; xa_for_each(&pin->parent_refs, index, ref) { - if (WARN_ON(!ref->ops->state_on_pin_get)) + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); + + if (WARN_ON(!ops->state_on_pin_get)) return -EFAULT; - ret = ref->ops->state_on_pin_get(pin, ref->pin, &state, - extack); + ret = ops->state_on_pin_get(pin, ref->pin, &state, extack); if (ret) return -EFAULT; nest = nla_nest_start(msg, DPLL_A_PIN_PARENT); @@ -452,7 +459,9 @@ dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a, return -EINVAL; xa_for_each(&pin->dpll_refs, i, ref) { - ret = ref->ops->frequency_set(pin, ref->dpll, freq, extack); + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); + + ret = ops->frequency_set(pin, ref->dpll, freq, extack); if (ret) return -EFAULT; dpll_pin_notify(ref->dpll, pin, DPLL_A_PIN_FREQUENCY); @@ -466,6 +475,7 @@ dpll_pin_on_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, u32 parent_idx, enum dpll_pin_state state, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops; struct dpll_pin_ref *ref; struct dpll_pin *parent; @@ -477,9 +487,10 @@ dpll_pin_on_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, ref = dpll_xa_ref_pin_find(&pin->parent_refs, parent); if (!ref) return -EINVAL; - if (!ref->ops || !ref->ops->state_on_pin_set) + ops = dpll_pin_ops(ref); + if (!ops->state_on_pin_set) return -EOPNOTSUPP; - if (ref->ops->state_on_pin_set(pin, parent, state, extack)) + if (ops->state_on_pin_set(pin, parent, state, extack)) return -EFAULT; dpll_pin_parent_notify(dpll, pin, parent, DPLL_A_PIN_STATE); @@ -491,6 +502,7 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, enum dpll_pin_state state, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops; struct dpll_pin_ref *ref; if (!(DPLL_PIN_CAPS_STATE_CAN_CHANGE & pin->prop.capabilities)) @@ -498,9 +510,10 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll); if (!ref) return -EFAULT; - if (!ref->ops || !ref->ops->state_on_dpll_set) + ops = dpll_pin_ops(ref); + if (!ops->state_on_dpll_set) return -EOPNOTSUPP; - if (ref->ops->state_on_dpll_set(pin, ref->dpll, state, extack)) + if (ops->state_on_dpll_set(pin, ref->dpll, state, extack)) return -EINVAL; dpll_pin_notify(ref->dpll, pin, DPLL_A_PIN_STATE); @@ -511,6 +524,7 @@ static int dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin, struct nlattr *prio_attr, struct netlink_ext_ack *extack) { + const struct dpll_pin_ops *ops; struct dpll_pin_ref *ref; u32 prio = nla_get_u8(prio_attr); @@ -519,9 +533,10 @@ dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin, ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll); if (!ref) return -EFAULT; - if (!ref->ops || !ref->ops->prio_set) + ops = dpll_pin_ops(ref); + if (!ops->prio_set) return -EOPNOTSUPP; - if (ref->ops->prio_set(pin, dpll, prio, extack)) + if (ops->prio_set(pin, dpll, prio, extack)) return -EINVAL; dpll_pin_notify(dpll, pin, DPLL_A_PIN_PRIO); @@ -540,7 +555,9 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct nlattr *a, return -EOPNOTSUPP; xa_for_each(&pin->dpll_refs, i, ref) { - if (ref->ops->direction_set(pin, ref->dpll, direction, extack)) + const struct dpll_pin_ops *ops = dpll_pin_ops(ref); + + if (ops->direction_set(pin, ref->dpll, direction, extack)) return -EFAULT; dpll_pin_notify(ref->dpll, pin, DPLL_A_PIN_DIRECTION); } @@ -920,13 +937,15 @@ dpll_event_device_change(struct sk_buff *msg, struct dpll_device *dpll, break; case DPLL_A_PIN_STATE: if (parent) { + const struct dpll_pin_ops *ops; + ref = dpll_xa_ref_pin_find(&pin->parent_refs, parent); if (!ref) return -EFAULT; - if (!ref->ops || !ref->ops->state_on_pin_get) + ops = dpll_pin_ops(ref); + if (!ops->state_on_pin_get) return -EOPNOTSUPP; - ret = ref->ops->state_on_pin_get(pin, parent, &state, - NULL); + ret = ops->state_on_pin_get(pin, parent, &state, NULL); if (ret) return ret; if (nla_put_u32(msg, DPLL_A_PIN_PARENT_IDX, diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 532ad7314f49..d39292ad102f 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1194,7 +1194,8 @@ ice_dpll_release_rclk_pin(struct ice_pf *pf) parent = pf->dplls.inputs[rclk->parent_idx[i]].pin; if (!parent) continue; - dpll_pin_on_pin_unregister(parent, rclk->pin); + dpll_pin_on_pin_unregister(parent, rclk->pin, + &ice_dpll_rclk_ops, pf); } dpll_pin_put(rclk->pin); rclk->pin = NULL; @@ -1202,6 +1203,7 @@ ice_dpll_release_rclk_pin(struct ice_pf *pf) /** * ice_dpll_release_pins - release pin's from dplls registered in subsystem + * @pf: board private structure * @dpll_eec: dpll_eec dpll pointer * @dpll_pps: dpll_pps dpll pointer * @pins: pointer to pins array @@ -1215,7 +1217,7 @@ ice_dpll_release_rclk_pin(struct ice_pf *pf) * * positive - number of errors encounterd on pin's deregistration. */ static int -ice_dpll_release_pins(struct dpll_device *dpll_eec, +ice_dpll_release_pins(struct ice_pf *pf, struct dpll_device *dpll_eec, struct dpll_device *dpll_pps, struct ice_dpll_pin *pins, int count, bool cgu) { @@ -1226,12 +1228,16 @@ ice_dpll_release_pins(struct dpll_device *dpll_eec, if (p && !IS_ERR_OR_NULL(p->pin)) { if (cgu && dpll_eec) { - ret = dpll_pin_unregister(dpll_eec, p->pin); + ret = dpll_pin_unregister(dpll_eec, p->pin, + &ice_dpll_source_ops, + pf); if (ret) err++; } if (cgu && dpll_pps) { - ret = dpll_pin_unregister(dpll_pps, p->pin); + ret = dpll_pin_unregister(dpll_pps, p->pin, + &ice_dpll_source_ops, + pf); if (ret) err++; } @@ -1532,7 +1538,7 @@ static void ice_dpll_release_all(struct ice_pf *pf, bool cgu) mutex_lock(&pf->dplls.lock); ice_dpll_release_rclk_pin(pf); - ret = ice_dpll_release_pins(de->dpll, dp->dpll, d->inputs, + ret = ice_dpll_release_pins(pf, de->dpll, dp->dpll, d->inputs, d->num_inputs, cgu); mutex_unlock(&pf->dplls.lock); if (ret) @@ -1540,7 +1546,7 @@ static void ice_dpll_release_all(struct ice_pf *pf, bool cgu) "source pins release dplls err=%d\n", ret); if (cgu) { mutex_lock(&pf->dplls.lock); - ret = ice_dpll_release_pins(de->dpll, dp->dpll, d->outputs, + ret = ice_dpll_release_pins(pf, de->dpll, dp->dpll, d->outputs, d->num_outputs, cgu); mutex_unlock(&pf->dplls.lock); if (ret) diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 09863d66a44c..be5717e1da99 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -211,6 +211,8 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, * dpll_pin_unregister - deregister pin from a dpll device * @dpll: pointer to dpll object to deregister pin from * @pin: pointer to allocated pin object being deregistered from dpll + * @ops: ops for a dpll pin ops + * @priv: pointer to private information of owner * * Deregister previously registered pin object from a dpll device. * @@ -219,7 +221,8 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, * * -ENXIO - given pin was not registered with this dpll device, * * -EINVAL - pin pointer is not valid. */ -int dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin); +int dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv); /** * dpll_pin_put - drop reference to a pin acquired with dpll_pin_get @@ -268,7 +271,8 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, * * -ENOMEM - failed to allocate memory, * * -EEXIST - pin already registered with this parent pin, */ -void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin); +void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv); /** * dpll_device_notify - notify on dpll device change From patchwork Sun Mar 26 17:00:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188371 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 73CA6C74A5B for ; Sun, 26 Mar 2023 17:02:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Ddufi+DtAtZq9jxYt4/12PGgXaTSZ1YBzAIeBgUgkYU=; b=uIqHB2c2Def2Av ZY01ggwT63owNEhFI7GKIHFd4CF/P8ETotqW+vqxu0+C22u97VKpk11DY4Avj8pk2Uh4Ik36umoaD AbMkK6cewoU4nrtm/hxS0AmD06s75ajccM4kcRIaj7FHEyW/FIsT+Be5/Gwz82ziXjXJqt3kYk5i+ LGFrCvmHVCuBbC9LXb2VXsmlYdWhvqe4mtcF0qdG0Qd2ERsHWCSvOlkELBklZBqdQKFMry2HWs4Kp su9nuiXbPIsshWmw3xaLmuCPu9Jd6xso9TOgMVGkwZMwqT/Stkxl8aSPmA9+g3bRh6qMuRNvU/pt0 pNZF5q6nRWj46AkmQ8GQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkM-008qzR-1w; Sun, 26 Mar 2023 17:01:34 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjt-008qsY-05 for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:06 +0000 Received: by mail-ed1-x533.google.com with SMTP id cn12so26640750edb.4 for ; Sun, 26 Mar 2023 10:01:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850061; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bwW6oUpD5h8cj23E/vde86PKPUzMAEIVBwgEWSiD3uA=; b=maShE7hQ0xVsk01dePT8Gyl+ZzjKlPhD4CBzQJx8U5K+HL4vf+tAy2IyFHqgOLz7V9 4au6EfidxkbYOBa8mB01sV8TLc2+RaUbM7pcXwv9/41bu0u0LJ/X52M090WluCeG5pN2 3InXvbCpLGcWUlhj0jS8I53HT9I879VPJSOehlH9ERkRAOVvAEjSojNUOD8EUYXVjquN BnmnvLeF/HzvaFH9VAPlD1L0pzsFab6SabwqVfkTONYS0sANTpLe+QFACxNVzG88wAE7 EQjd9w37QGfEdTrng5xsesLYMOJbBaF8anaWikTSAOPEshw8p5gbTWutIohked+ICaOJ 3bNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850061; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bwW6oUpD5h8cj23E/vde86PKPUzMAEIVBwgEWSiD3uA=; b=WZcMzh8xOhQWa131QG0r4KscDv3rxTQoQJXfFnRPIjkk1RgtczmuPuYkg07aGbluGa GC0GUHJXAWK1bHnlFpY+yEUSVW8w2yw4UdikZh2XmK0StAFK5qhoxXnJO6bglCSmD4YS 7FxUAvteWTm5US7ArPAo0xURYW8+Yzuz/2TqWwf7Rj0DIB1vPK7QDBDqnGt6KBxL04Y+ VIJqPq82LuB+E7J8GD1MmAAye0OuNrE+M0UHERNo8eGqDB5D8cCMN2okefMEOqAyQ8M+ awMWuX6rKf8CVNQEajwHaLfE3+2tyOTIUpckmj03qJAPOr7HinEaPs5IsY2CQamFSvaG h8tg== X-Gm-Message-State: AAQBX9fHe+iP12grBdcadLhEycABXVCEv3uNGhXPMIA/IefXgVyJUrUB BCFARuB1yyqYBwjLa5Z0IXq3cw== X-Google-Smtp-Source: AKy350aAoyrIBElGGuBqNIPvfAlr7j+pHNViwWZzsB345Jd6yv4nK48yXBcBagk0NV05PxljKZpuCg== X-Received: by 2002:a17:906:578c:b0:88f:a236:69e6 with SMTP id k12-20020a170906578c00b0088fa23669e6mr9545337ejq.7.1679850061356; Sun, 26 Mar 2023 10:01:01 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id m27-20020a170906259b00b0093a3a663ebdsm7941215ejb.154.2023.03.26.10.01.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:01:00 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 5/7] dpll: export dpll_pin_notify() Date: Sun, 26 Mar 2023 19:00:50 +0200 Message-Id: <20230326170052.2065791-6-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100105_573125_E1187874 X-CRM114-Status: GOOD ( 11.14 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko Export dpll_pin_notify() as it is needed to be called from drivers. Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_netlink.c | 1 + drivers/dpll/dpll_netlink.h | 3 --- include/linux/dpll.h | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 125dc3c7e643..cd77881ee1ec 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -1056,6 +1056,7 @@ int dpll_pin_notify(struct dpll_device *dpll, struct dpll_pin *pin, { return dpll_send_event_change(dpll, pin, NULL, attr); } +EXPORT_SYMBOL_GPL(dpll_pin_notify); int dpll_pin_parent_notify(struct dpll_device *dpll, struct dpll_pin *pin, struct dpll_pin *parent, enum dplla attr) diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h index 072efa10f0e6..952e0335595e 100644 --- a/drivers/dpll/dpll_netlink.h +++ b/drivers/dpll/dpll_netlink.h @@ -20,9 +20,6 @@ int dpll_notify_device_create(struct dpll_device *dpll); */ int dpll_notify_device_delete(struct dpll_device *dpll); -int dpll_pin_notify(struct dpll_device *dpll, struct dpll_pin *pin, - enum dplla attr); - int dpll_pin_parent_notify(struct dpll_device *dpll, struct dpll_pin *pin, struct dpll_pin *parent, enum dplla attr); diff --git a/include/linux/dpll.h b/include/linux/dpll.h index be5717e1da99..562b9b7bd001 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -287,5 +287,9 @@ void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, */ int dpll_device_notify(struct dpll_device *dpll, enum dplla attr); +int dpll_pin_notify(struct dpll_device *dpll, struct dpll_pin *pin, + enum dplla attr); + + #endif From patchwork Sun Mar 26 17:00:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C9889C74A5B for ; Sun, 26 Mar 2023 17:02:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1E1Ic9cp+ro3YRQVZY1jWMTatHieMi1LiIKFRi027fU=; b=C/YJfZnRM6rUFE Wmw7RCNSidjyHpYxdwXDNqVpQ6tfLjJsAix3kmphZo+bO01twTRDLy8cZj9iqJB+LbzgatB493y9E IO4/KEkqBeOi1jfkX/HtbACfndJpXMDfGQA+hOr2nMZIBVpoWzk2XsJfyL5AnDYvGqixRhBAj0TIW LLRFZHQBzw60ARvdUeAyDhvFFu8kvn99Vn6DH+ZcE+nr+m1xxHU9oQFujfM1LVWJNu/eJ+qd0LXpR nUglrxZ02Z7fCHNyija7QP3Bh5aT6go7GoRXJIBzbHo2L3QquFdglvW09LoxprSORmKGr8/0Fd2Ik /Ek5/9J5t98xT12gBDWg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkN-008r03-2f; Sun, 26 Mar 2023 17:01:35 +0000 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjs-008qsc-1j for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:07 +0000 Received: by mail-ed1-x532.google.com with SMTP id cn12so26640932edb.4 for ; Sun, 26 Mar 2023 10:01:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wVw8mNIYgBevA5WAbZRzEVceVuQ8FZJe/xIyNmE1HIg=; b=dtMeZISBFJD4Y1iX25nk1jG3zfNA4pZZRckmOUNi23elyCG5DI+bQgTtsvKVznEEt8 2YFMS1wYiK0bU9qQSUxvKODsdkfNjKXS12+MK9y+boBWd7iqfUvzApiPSYzcTxxgBkop TijJzXRK7I4WsE0YZwUTnpOdFkXv/Mx4Dtrs6Faj2s7igQ3O1WhzwKLE2Bu33WIo5SqW 7sy4xS2Gdb94ns/y9Mnt2ApBtzDR9qOutkzcJ6m1h4R6PZ35zOOlXA0aDnXGsKb+5DYD hpweIiHvFaIrs43D+y6A3cH4/AY62XkpX/oROBJmdtrbnVlbc0N4R0QNpBozsG0i59b+ Dq5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wVw8mNIYgBevA5WAbZRzEVceVuQ8FZJe/xIyNmE1HIg=; b=tE/+XXDXVi6Xh0UUvPJbXbXImvGqamgK3FbK55Lh3FjtIYCq80oKSEtlvaJdybX9qt +SPoRl9Pi/0RxaJfWWmHI9xj9BEbaNp2LPsfe7e6p+UbwrrBH8p8BlB11HgfxaoKXJ0w ZFjzrp9g4bnTzbe55IBvlHgnJK45mizm9nL1qd3rJoTiv64lVBKT0NgRnhbFbHeabsp9 KFieekSiN43dcsX7mloE2VNk3r6qn6dPEHh8cDEefCaTuM39rjv306Pu7ajWzEOmqXfI 2AtedOjXCIifD/XOF7kfKrODXRcmOqZESfKGHnzHLUCwF7hh8o0FvgUhtp+3B/MUVBpQ 1d3A== X-Gm-Message-State: AAQBX9ezs5ep6ynufmHqdql3K6yQKOHYCxQX6T4k+jc2A8otfxfgI8wt 7KPLzMwCMZxu1rO+9auQGsN/ww== X-Google-Smtp-Source: AKy350bjFaVpgOcNLLdrsugeYmhEfzcs6Xab2vP4Fh1lmBuaxXVpDg02V36R1QWwVKeawousjXcGJQ== X-Received: by 2002:a17:907:d22:b0:932:5b67:6dee with SMTP id gn34-20020a1709070d2200b009325b676deemr10652498ejc.27.1679850062898; Sun, 26 Mar 2023 10:01:02 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id c16-20020a170906925000b009327f9a397csm12566473ejx.145.2023.03.26.10.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:01:02 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 6/7] netdev: expose DPLL pin handle for netdevice Date: Sun, 26 Mar 2023 19:00:51 +0200 Message-Id: <20230326170052.2065791-7-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100105_555612_8709471D X-CRM114-Status: GOOD ( 20.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko In case netdevice represents a SyncE port, the user needs to understand the connection between netdevice and associated DPLL pin. There might me multiple netdevices pointing to the same pin, in case of VF/SF implementation. Add a IFLA Netlink attribute to nest the DPLL pin handle, similar to how is is implemented for devlink port. Add a struct dpll_pin pointer to netdev and protect access to it by RTNL. Expose netdev_dpll_pin_set() and netdev_dpll_pin_clear() helpers to the drivers so they can set/clear the DPLL pin relationship to netdev. Note that during the lifetime of struct dpll_pin the handle fields do not change. Therefore it is save to access them lockless. It is drivers responsibility to call netdev_dpll_pin_clear() before dpll_pin_put(). Signed-off-by: Jiri Pirko --- drivers/dpll/dpll_netlink.c | 28 ++++++++++++++++++++++---- include/linux/dpll.h | 20 +++++++++++++++++++ include/linux/netdevice.h | 7 +++++++ include/uapi/linux/if_link.h | 2 ++ net/core/dev.c | 20 +++++++++++++++++++ net/core/rtnetlink.c | 38 ++++++++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 4 deletions(-) diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index cd77881ee1ec..ac5cbf5a2e19 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -302,6 +302,24 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin, return ret; } +size_t dpll_msg_pin_handle_size(struct dpll_pin *pin) +{ + // TMP- THE HANDLE IS GOING TO CHANGE TO DRIVERNAME/CLOCKID/PIN_INDEX + // LEAVING ORIG HANDLE NOW AS PUT IN THE LAST RFC VERSION + return nla_total_size(4); /* DPLL_A_PIN_IDX */ +} +EXPORT_SYMBOL_GPL(dpll_msg_pin_handle_size); + +int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin) +{ + // TMP- THE HANDLE IS GOING TO CHANGE TO DRIVERNAME/CLOCKID/PIN_INDEX + // LEAVING ORIG HANDLE NOW AS PUT IN THE LAST RFC VERSION + if (nla_put_u32(msg, DPLL_A_PIN_IDX, pin->dev_driver_id)) + return -EMSGSIZE; + return 0; +} +EXPORT_SYMBOL_GPL(dpll_msg_add_pin_handle); + static int dpll_cmd_pin_on_dpll_get(struct sk_buff *msg, struct dpll_pin *pin, struct dpll_device *dpll, @@ -310,8 +328,9 @@ dpll_cmd_pin_on_dpll_get(struct sk_buff *msg, struct dpll_pin *pin, struct dpll_pin_ref *ref; int ret; - if (nla_put_u32(msg, DPLL_A_PIN_IDX, pin->dev_driver_id)) - return -EMSGSIZE; + ret = dpll_msg_add_pin_handle(msg, pin); + if (ret) + return ret; if (nla_put_string(msg, DPLL_A_PIN_DESCRIPTION, pin->prop.description)) return -EMSGSIZE; if (nla_put_u8(msg, DPLL_A_PIN_TYPE, pin->prop.type)) @@ -352,8 +371,9 @@ __dpll_cmd_pin_dump_one(struct sk_buff *msg, struct dpll_pin *pin, struct dpll_pin_ref *ref; int ret; - if (nla_put_u32(msg, DPLL_A_PIN_IDX, pin->dev_driver_id)) - return -EMSGSIZE; + ret = dpll_msg_add_pin_handle(msg, pin); + if (ret) + return ret; if (nla_put_string(msg, DPLL_A_PIN_DESCRIPTION, pin->prop.description)) return -EMSGSIZE; if (nla_put_u8(msg, DPLL_A_PIN_TYPE, pin->prop.type)) diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 562b9b7bd001..f9081e5fc522 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -92,6 +92,26 @@ enum dpll_pin_freq_supp { DPLL_PIN_FREQ_SUPP_MAX = (__DPLL_PIN_FREQ_SUPP_MAX - 1) }; +#if IS_ENABLED(CONFIG_DPLL) + +size_t dpll_msg_pin_handle_size(struct dpll_pin *pin); + +int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin); + +#else + +static inline size_t dpll_msg_pin_handle_size(struct dpll_pin *pin) +{ + return 0; +} + +static inline int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin) +{ + return 0; +} + +#endif + /** * dpll_device_get - find or create dpll_device object * @clock_id: a system unique number for a device diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7621c512765f..79a90b52ee77 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #ifdef CONFIG_DCB @@ -2403,6 +2404,10 @@ struct net_device { struct rtnl_hw_stats64 *offload_xstats_l3; struct devlink_port *devlink_port; + +#if IS_ENABLED(CONFIG_DPLL) + struct dpll_pin *dpll_pin; +#endif }; #define to_net_dev(d) container_of(d, struct net_device, dev) @@ -3939,6 +3944,8 @@ int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name); int dev_get_port_parent_id(struct net_device *dev, struct netdev_phys_item_id *ppid, bool recurse); bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b); +void netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); +void netdev_dpll_pin_clear(struct net_device *dev); struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again); struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 57ceb788250f..280573f723da 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -377,6 +377,8 @@ enum { IFLA_GSO_IPV4_MAX_SIZE, IFLA_GRO_IPV4_MAX_SIZE, + IFLA_DPLL_PIN, + __IFLA_MAX }; diff --git a/net/core/dev.c b/net/core/dev.c index c7853192563d..cf9f61cf33e2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8949,6 +8949,26 @@ bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b) } EXPORT_SYMBOL(netdev_port_same_parent_id); +static void netdev_dpll_pin_assign(struct net_device *dev, struct dpll_pin *dpll_pin) +{ + rtnl_lock(); + dev->dpll_pin = dpll_pin; + rtnl_unlock(); +} + +void netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) +{ + WARN_ON(!dpll_pin); + netdev_dpll_pin_assign(dev, dpll_pin); +} +EXPORT_SYMBOL(netdev_dpll_pin_set); + +void netdev_dpll_pin_clear(struct net_device *dev) +{ + netdev_dpll_pin_assign(dev, NULL); +} +EXPORT_SYMBOL(netdev_dpll_pin_clear); + /** * dev_change_proto_down - set carrier according to proto_down. * diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b7b1661d0d56..e29aed39625d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1052,6 +1052,16 @@ static size_t rtnl_devlink_port_size(const struct net_device *dev) return size; } +static size_t rtnl_dpll_pin_size(const struct net_device *dev) +{ + size_t size = nla_total_size(0); /* nest IFLA_DPLL_PIN */ + + if (dev->dpll_pin) + size += dpll_msg_pin_handle_size(dev->dpll_pin); + + return size; +} + static noinline size_t if_nlmsg_size(const struct net_device *dev, u32 ext_filter_mask) { @@ -1108,6 +1118,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + rtnl_prop_list_size(dev) + nla_total_size(MAX_ADDR_LEN) /* IFLA_PERM_ADDRESS */ + rtnl_devlink_port_size(dev) + + rtnl_dpll_pin_size(dev) + 0; } @@ -1769,6 +1780,30 @@ static int rtnl_fill_devlink_port(struct sk_buff *skb, return ret; } +static int rtnl_fill_dpll_pin(struct sk_buff *skb, + const struct net_device *dev) +{ + struct nlattr *dpll_pin_nest; + int ret; + + dpll_pin_nest = nla_nest_start(skb, IFLA_DPLL_PIN); + if (!dpll_pin_nest) + return -EMSGSIZE; + + if (dev->dpll_pin) { + ret = dpll_msg_add_pin_handle(skb, dev->dpll_pin); + if (ret < 0) + goto nest_cancel; + } + + nla_nest_end(skb, dpll_pin_nest); + return 0; + +nest_cancel: + nla_nest_cancel(skb, dpll_pin_nest); + return ret; +} + static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct net *src_net, int type, u32 pid, u32 seq, u32 change, @@ -1911,6 +1946,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, if (rtnl_fill_devlink_port(skb, dev)) goto nla_put_failure; + if (rtnl_fill_dpll_pin(skb, dev)) + goto nla_put_failure; + nlmsg_end(skb, nlh); return 0; From patchwork Sun Mar 26 17:00:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 13188377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3216DC761AF for ; Sun, 26 Mar 2023 17:02:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=CbMPu78keySI8aDKq35CyP+LjyJSMwNGoq/keuC9oqE=; b=iyG+NQ3qB6OHfu w0aftQ+cHfhD1LgdsOkuVnYd2jfXWgWmFGC/ithArp8k4/fb9+6YhHVO5AykZH3BiISVj8MTVo/NJ tzhMGgvW3FyO2xnq/xnBYWubpXVDGKjHbV0Nt747wZ41nArdZnxIHFU6A271k74i625mkvCppGiRW rVgZl1tY2R8W64o9iaMNOqXHVoanU6HgdxNyRltsMVfHXUzPpYyBV5EB/0M65nURASEQReIUxLdm/ XqCD2Ldkm4gPSkYL+5RO+mtpujaQo8MsbX9j3abkujt6DH8nGLK5BQSx/+XuQqzEFs7kVszNprZOj RctZ0iPxm9t+ODgU65ig==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pgTkQ-008r1a-13; Sun, 26 Mar 2023 17:01:38 +0000 Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pgTjx-008qsd-2X for linux-arm-kernel@lists.infradead.org; Sun, 26 Mar 2023 17:01:12 +0000 Received: by mail-ed1-x534.google.com with SMTP id h8so26573390ede.8 for ; Sun, 26 Mar 2023 10:01:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20210112.gappssmtp.com; s=20210112; t=1679850064; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nZXb2+qygNbjzLHXmsrj7zi5WUAuLCHh86RQvypcKFM=; b=q+sAgEA1tWrHayteteZXKjSxrxezbir3t+wBsdKGIAoBkOoTMMm3pKi4jRWImIKU6d bDWlamdhWgWdF4eOQ8L4wfw3AWzNIkqQgEGSSr/Xw/qFLeKiAXBUAT3UWFokg2kEPgID +vDHQ85sdPBUc6WAaUVeF82R2q9oASw3ss9vKFmdSQpkwULsDiweGL5xf8IhyveZahs0 wkYhuyX53dLvGvH6tQuZkKAEzMqAvOQ2htlJh4FPW6sAHkX+B3ENVx054nljW7s0f3Hl snM/ZmqY8BY/3+a8eL1TU3Puf5CS9P+mbJX9dGDF6H2oC3OjUk9AQMmUkienURbejifw bisg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679850064; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nZXb2+qygNbjzLHXmsrj7zi5WUAuLCHh86RQvypcKFM=; b=N0flLsWsrxQ61cHX7gwEi6xr28BpUcCV3zW/FJckY4yFLGUwxQYPxO3q+lYCZI05F8 7qsEdf62Ca20UixGceHTPJjjFcclgUo4qvBcoEFoDszNmoAinvjb21EMPKoaSfRJuntm 81Xo7H0+yjlz0CVHVZBvkQEUb3czReIMQgN7Y9qs+NiKIKi+JE6lV1vGsSMU0Uyh99Iz 7TKYjE7PpHHWB2WghD5GLjlIydPEnhMrifURiM2emDNqOqiE8ewVBOzwnCvJTrKxnVBh RcYxXGSRiWwPsXgz9Bqo+oW7+gUTLhuRw2Bb+j86wWdbnmwaN7MLxCeCx8SAUUTDwGrs SmFg== X-Gm-Message-State: AAQBX9dkN7sLpZkjMfpNmKscO9YhfO0KHV4IrYPCe8d2U1c72VP8xMOp huiXiiIkUMrtj7GqWHK5qejOkw== X-Google-Smtp-Source: AKy350Y8KqmSx4SJO/HdBUgJZAtE4an2+rgY5TSAdQyfaVzCo5KUni7h4KHnZ1X3U+S7dr1V3iHAuA== X-Received: by 2002:a17:906:d8d0:b0:932:3688:ae81 with SMTP id re16-20020a170906d8d000b009323688ae81mr9369494ejb.9.1679850064490; Sun, 26 Mar 2023 10:01:04 -0700 (PDT) Received: from localhost (host-213-179-129-39.customer.m-online.net. [213.179.129.39]) by smtp.gmail.com with ESMTPSA id u23-20020a170906409700b009334a6ef3e8sm11132772ejj.141.2023.03.26.10.01.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Mar 2023 10:01:03 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org, arkadiusz.kubalewski@intel.com, vadim.fedorenko@linux.dev, vadfed@meta.com Cc: kuba@kernel.org, jonathan.lemon@gmail.com, pabeni@redhat.com, poros@redhat.com, mschmidt@redhat.com, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [patch dpll-rfc 7/7] mlx5: Implement SyncE support using DPLL infrastructure Date: Sun, 26 Mar 2023 19:00:52 +0200 Message-Id: <20230326170052.2065791-8-jiri@resnulli.us> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230326170052.2065791-1-jiri@resnulli.us> References: <20230312022807.278528-1-vadfed@meta.com> <20230326170052.2065791-1-jiri@resnulli.us> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230326_100109_997787_C1590ADD X-CRM114-Status: GOOD ( 21.58 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jiri Pirko Implement SyncE support using newly introduced DPLL support. Make sure that each PFs/VFs/SFs probed with appropriate capability will spawn a dpll auxiliary device and register appropriate dpll device and pin instances. Signed-off-by: Jiri Pirko --- .../net/ethernet/mellanox/mlx5/core/Kconfig | 8 + .../net/ethernet/mellanox/mlx5/core/Makefile | 3 + drivers/net/ethernet/mellanox/mlx5/core/dev.c | 17 + .../net/ethernet/mellanox/mlx5/core/dpll.c | 429 ++++++++++++++++++ include/linux/mlx5/driver.h | 2 + include/linux/mlx5/mlx5_ifc.h | 59 ++- 6 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/dpll.c diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index bb1d7b039a7e..15a48d376eb3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig @@ -188,3 +188,11 @@ config MLX5_SF_MANAGER port is managed through devlink. A subfunction supports RDMA, netdevice and vdpa device. It is similar to a SRIOV VF but it doesn't require SRIOV support. + +config MLX5_DPLL + tristate "Mellanox 5th generation network adapters (ConnectX series) DPLL support" + depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE + select DPLL + help + DPLL support in Mellanox Technologies ConnectX NICs. + diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index 6c2f1d4a58ab..c2c864aba1f5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -123,3 +123,6 @@ mlx5_core-$(CONFIG_MLX5_SF) += sf/vhca_event.o sf/dev/dev.o sf/dev/driver.o irq_ # SF manager # mlx5_core-$(CONFIG_MLX5_SF_MANAGER) += sf/cmd.o sf/hw_table.o sf/devlink.o + +obj-$(CONFIG_MLX5_DPLL) += mlx5_dpll.o +mlx5_dpll-y := dpll.o diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index 445fe30c3d0b..7520e5987cb2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -227,6 +227,19 @@ static bool is_ib_enabled(struct mlx5_core_dev *dev) return err ? false : val.vbool; } +static bool is_dpll_supported(struct mlx5_core_dev *dev) +{ + if (!IS_ENABLED(CONFIG_MLX5_DPLL)) + return false; + + if (!MLX5_CAP_MCAM_REG2(dev, synce_registers)) { + mlx5_core_warn(dev, "Missing SyncE capability\n"); + return false; + } + + return true; +} + enum { MLX5_INTERFACE_PROTOCOL_ETH, MLX5_INTERFACE_PROTOCOL_ETH_REP, @@ -236,6 +249,8 @@ enum { MLX5_INTERFACE_PROTOCOL_MPIB, MLX5_INTERFACE_PROTOCOL_VNET, + + MLX5_INTERFACE_PROTOCOL_DPLL, }; static const struct mlx5_adev_device { @@ -258,6 +273,8 @@ static const struct mlx5_adev_device { .is_supported = &is_ib_rep_supported }, [MLX5_INTERFACE_PROTOCOL_MPIB] = { .suffix = "multiport", .is_supported = &is_mp_supported }, + [MLX5_INTERFACE_PROTOCOL_DPLL] = { .suffix = "dpll", + .is_supported = &is_dpll_supported }, }; int mlx5_adev_idx_alloc(void) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c new file mode 100644 index 000000000000..afb092fcbcae --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c @@ -0,0 +1,429 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#include +#include + +// POSSIBLE DPLL API EXTENSIONS: +// 1) Expose clock quality: MSECQ->local_ssm_code, MSECQ->local_enhanced_ssm_code +// Proposed enum: +// QL_DNU, +// QL_EEC1, +// QL_eEEC, +// QL_SSU_B, +// QL_SSU_A, +// QL_PRC, +// QL_ePRC, +// QL_PRTC, +// QL_ePRTC, +// 2) Expose possibility to do holdover: MSEES->ho_acq +// 3) DPLL Implementation hw-speficic values (debug?): MSEES->oper_freq_measure + +/* This structure represents a reference to DPLL, one is created + * per mdev instance. + */ +struct mlx5_dpll { + struct dpll_device *dpll; + struct dpll_pin *dpll_pin; + struct mlx5_core_dev *mdev; + struct workqueue_struct *wq; + struct delayed_work work; + struct { + bool valid; + enum dpll_lock_status lock_status; + enum dpll_pin_state pin_state; + } last; + struct notifier_block mdev_nb; + struct net_device *tracking_netdev; +}; + +static int mlx5_dpll_clock_id_get(struct mlx5_core_dev *mdev, u64 *clock_id) +{ + u32 out[MLX5_ST_SZ_DW(msecq_reg)] = {}; + u32 in[MLX5_ST_SZ_DW(msecq_reg)] = {}; + int err; + + err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), + MLX5_REG_MSECQ, 0, 0); + if (err) + return err; + *clock_id = MLX5_GET64(msecq_reg, out, local_clock_identity); + return 0; +} + +static int +mlx5_dpll_synce_status_get(struct mlx5_core_dev *mdev, + enum mlx5_msees_admin_status *admin_status, + enum mlx5_msees_oper_status *oper_status) +{ + u32 out[MLX5_ST_SZ_DW(msees_reg)] = {}; + u32 in[MLX5_ST_SZ_DW(msees_reg)] = {}; + int err; + + MLX5_SET(msees_reg, in, local_port, 1); + err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), + MLX5_REG_MSEES, 0, 0); + if (err) + return err; + if (admin_status) + *admin_status = MLX5_GET(msees_reg, out, admin_status); + if (oper_status) + *oper_status = MLX5_GET(msees_reg, out, oper_status); + return 0; +} + +static int +mlx5_dpll_synce_status_set(struct mlx5_core_dev *mdev, + enum mlx5_msees_admin_status admin_status) +{ + u32 out[MLX5_ST_SZ_DW(msees_reg)] = {}; + u32 in[MLX5_ST_SZ_DW(msees_reg)] = {}; + + MLX5_SET(msees_reg, in, local_port, 1); + MLX5_SET(msees_reg, in, field_select, + MLX5_MSEES_FIELD_SELECT_ENABLE | + MLX5_MSEES_FIELD_SELECT_ADMIN_STATUS); + MLX5_SET(msees_reg, in, admin_status, admin_status); + MLX5_SET(msees_reg, in, admin_freq_measure, + admin_status == MLX5_MSEES_ADMIN_STATUS_TRACK); + return mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), + MLX5_REG_MSEES, 0, 0); +} + +static enum dpll_lock_status +mlx5_dpll_lock_status_from_oper_status(enum mlx5_msees_oper_status oper_status) +{ + switch (oper_status) { + case MLX5_MSEES_OPER_STATUS_SELF_TRACK: + fallthrough; + case MLX5_MSEES_OPER_STATUS_OTHER_TRACK: + return DPLL_LOCK_STATUS_LOCKED; + case MLX5_MSEES_OPER_STATUS_HOLDOVER: + return DPLL_LOCK_STATUS_HOLDOVER; + default: + return DPLL_LOCK_STATUS_UNLOCKED; + } +} + +static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, + enum dpll_lock_status *status, + struct netlink_ext_ack *extack) +{ + struct mlx5_dpll *mdpll = dpll_priv(dpll); + enum mlx5_msees_oper_status oper_status; + int err; + + err = mlx5_dpll_synce_status_get(mdpll->mdev, NULL, &oper_status); + if (err) + return err; + + *status = mlx5_dpll_lock_status_from_oper_status(oper_status); + return 0; +} + +static int mlx5_dpll_device_mode_get(const struct dpll_device *dpll, + u32 *mode, struct netlink_ext_ack *extack) +{ + *mode = DPLL_MODE_MANUAL; + return 0; +} + +static bool mlx5_dpll_device_mode_supported(const struct dpll_device *dpll, + enum dpll_mode mode, + struct netlink_ext_ack *extack) +{ + return mode == DPLL_MODE_MANUAL; +} + +static const struct dpll_device_ops mlx5_dpll_device_ops = { + .lock_status_get = mlx5_dpll_device_lock_status_get, + .mode_get = mlx5_dpll_device_mode_get, + .mode_supported = mlx5_dpll_device_mode_supported, +}; + +static int mlx5_dpll_pin_direction_get(const struct dpll_pin *pin, + const struct dpll_device *dpll, + enum dpll_pin_direction *direction, + struct netlink_ext_ack *extack) +{ + *direction = DPLL_PIN_DIRECTION_SOURCE; + return 0; +} + +static enum dpll_pin_state +mlx5_dpll_pin_state_from_admin_status(enum mlx5_msees_admin_status admin_status) +{ + return admin_status == MLX5_MSEES_ADMIN_STATUS_TRACK ? + DPLL_PIN_STATE_CONNECTED : DPLL_PIN_STATE_DISCONNECTED; +} + +static int mlx5_dpll_state_on_dpll_get(const struct dpll_pin *pin, + const struct dpll_device *dpll, + enum dpll_pin_state *state, + struct netlink_ext_ack *extack) +{ + struct mlx5_dpll *mdpll = dpll_pin_on_dpll_priv(dpll, pin); + enum mlx5_msees_admin_status admin_status; + int err; + + err = mlx5_dpll_synce_status_get(mdpll->mdev, &admin_status, NULL); + if (err) + return err; + *state = mlx5_dpll_pin_state_from_admin_status(admin_status); + return 0; +} + +static int mlx5_dpll_state_on_dpll_set(const struct dpll_pin *pin, + const struct dpll_device *dpll, + enum dpll_pin_state state, + struct netlink_ext_ack *extack) +{ + struct mlx5_dpll *mdpll = dpll_pin_on_dpll_priv(dpll, pin); + + return mlx5_dpll_synce_status_set(mdpll->mdev, + state == DPLL_PIN_STATE_CONNECTED ? + MLX5_MSEES_ADMIN_STATUS_TRACK : + MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING); +} + +static const struct dpll_pin_ops mlx5_dpll_pins_ops = { + .direction_get = mlx5_dpll_pin_direction_get, + .state_on_dpll_get = mlx5_dpll_state_on_dpll_get, + .state_on_dpll_set = mlx5_dpll_state_on_dpll_set, +}; + +static const struct dpll_pin_properties mlx5_dpll_pin_properties = { + .description = "n/a", + .type = DPLL_PIN_TYPE_SYNCE_ETH_PORT, + .capabilities = DPLL_PIN_CAPS_STATE_CAN_CHANGE, +}; + +#define MLX5_DPLL_PERIODIC_WORK_INTERVAL 500 /* ms */ + +static void mlx5_dpll_periodic_work_queue(struct mlx5_dpll *mdpll) +{ + queue_delayed_work(mdpll->wq, &mdpll->work, + msecs_to_jiffies(MLX5_DPLL_PERIODIC_WORK_INTERVAL)); +} + +static void mlx5_dpll_periodic_work(struct work_struct *work) +{ + struct mlx5_dpll *mdpll = container_of(work, struct mlx5_dpll, + work.work); + enum mlx5_msees_admin_status admin_status; + enum mlx5_msees_oper_status oper_status; + enum dpll_lock_status lock_status; + enum dpll_pin_state pin_state, + + err = mlx5_dpll_synce_status_get(mdpll->mdev, &admin_status, + &oper_status); + if (err) + goto err_out; + lock_status = mlx5_dpll_lock_status_from_oper_status(oper_status); + pin_state = mlx5_dpll_pin_state_from_admin_status(admin_status); + + if (!mdpll->last.valid) + goto invalid_out; + + if (mdpll->last.lock_status != lock_status) + dpll_device_notify(mdpll->dpll, DPLL_A_LOCK_STATUS); + if (mdpll->last.pin_state != pin_state) + dpll_pin_notify(mdpll->dpll, mdpll->dpll_pin, DPLL_A_PIN_STATE); + +invalid_out: + mdpll->last.lock_status = lock_status; + mdpll->last.pin_state = pin_state; + mdpll->last.valid = true; +err_out: + mlx5_dpll_periodic_work_queue(mdpll); +} + +static void mlx5_dpll_netdev_dpll_pin_set(struct mlx5_dpll *mdpll, + struct net_device *netdev) +{ + if (mdpll->tracking_netdev) + return; + netdev_dpll_pin_set(netdev, mdpll->dpll_pin); + mdpll->tracking_netdev = netdev; +} + +static void mlx5_dpll_netdev_dpll_pin_clear(struct mlx5_dpll *mdpll) +{ + if (!mdpll->tracking_netdev) + return; + netdev_dpll_pin_clear(mdpll->tracking_netdev); + mdpll->tracking_netdev = NULL; +} + +static int mlx5_dpll_mdev_notifier_event(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct mlx5_dpll *mdpll = container_of(nb, struct mlx5_dpll, mdev_nb); + struct net_device *netdev = data; + + switch (event) { + case MLX5_DRIVER_EVENT_UPLINK_NETDEV: + if (netdev) + mlx5_dpll_netdev_dpll_pin_set(mdpll, netdev); + else + mlx5_dpll_netdev_dpll_pin_clear(mdpll); + break; + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static void mlx5_dpll_mdev_netdev_track(struct mlx5_dpll *mdpll, + struct mlx5_core_dev *mdev) +{ + mdpll->mdev_nb.notifier_call = mlx5_dpll_mdev_notifier_event; + mlx5_blocking_notifier_register(mdev, &mdpll->mdev_nb); + mlx5_core_uplink_netdev_event_replay(mdev); +} + +static void mlx5_dpll_mdev_netdev_untrack(struct mlx5_dpll *mdpll, + struct mlx5_core_dev *mdev) +{ + mlx5_blocking_notifier_unregister(mdev, &mdpll->mdev_nb); + mlx5_dpll_netdev_dpll_pin_clear(mdpll); +} + +static int mlx5_dpll_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev); + struct mlx5_core_dev *mdev = edev->mdev; + struct mlx5_dpll *mdpll; + u64 clock_id; + int err; + + err = mlx5_dpll_synce_status_set(mdev, + MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING); + if (err) + return err; + + err = mlx5_dpll_clock_id_get(mdev, &clock_id); + if (err) + return err; + + mdpll = kzalloc(sizeof(*mdpll), GFP_KERNEL); + if (!mdpll) + return -ENOMEM; + mdpll->mdev = mdev; + auxiliary_set_drvdata(adev, mdpll); + + /* Multiple mdev instances might share one DPLL device. */ + mdpll->dpll = dpll_device_get(clock_id, 0, DPLL_TYPE_EEC, THIS_MODULE); + if (IS_ERR(mdpll->dpll)) { + err = PTR_ERR(mdpll->dpll); + goto err_free_mdpll; + } + + err = dpll_device_register(mdpll->dpll, &mlx5_dpll_device_ops, + mdpll, &adev->dev); + if (err) + goto err_put_dpll_device; + + /* Multiple mdev instances might share one DPLL pin. */ + mdpll->dpll_pin = dpll_pin_get(clock_id, mlx5_get_dev_index(mdev), + THIS_MODULE, &mlx5_dpll_pin_properties); + if (IS_ERR(mdpll->dpll_pin)) { + err = PTR_ERR(mdpll->dpll_pin); + goto err_unregister_dpll_device; + } + + err = dpll_pin_register(mdpll->dpll, mdpll->dpll_pin, + &mlx5_dpll_pins_ops, mdpll, NULL); + if (err) + goto err_put_dpll_pin; + + mdpll->wq = create_singlethread_workqueue("mlx5_dpll"); + if (!mdpll->wq) { + err = -ENOMEM; + goto err_unregister_dpll_pin; + } + + mlx5_dpll_mdev_netdev_track(mdpll, mdev); + + INIT_DELAYED_WORK(&mdpll->work, &mlx5_dpll_periodic_work); + mlx5_dpll_periodic_work_queue(mdpll); + + return 0; + +err_unregister_dpll_pin: + dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin, + &mlx5_dpll_pins_ops, mdpll); +err_put_dpll_pin: + dpll_pin_put(mdpll->dpll_pin); +err_unregister_dpll_device: + dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll); +err_put_dpll_device: + dpll_device_put(mdpll->dpll); +err_free_mdpll: + kfree(mdpll); + return err; +} + +static void mlx5_dpll_remove(struct auxiliary_device *adev) +{ + struct mlx5_dpll *mdpll = auxiliary_get_drvdata(adev); + struct mlx5_core_dev *mdev = mdpll->mdev; + + cancel_delayed_work(&mdpll->work); + mlx5_dpll_mdev_netdev_untrack(mdpll, mdev); + destroy_workqueue(mdpll->wq); + dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin, + &mlx5_dpll_pins_ops, mdpll); + dpll_pin_put(mdpll->dpll_pin); + dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll); + dpll_device_put(mdpll->dpll); + kfree(mdpll); + + mlx5_dpll_synce_status_set(mdev, + MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING); +} + +static int mlx5_dpll_suspend(struct auxiliary_device *adev, pm_message_t state) +{ + return 0; +} + +static int mlx5_dpll_resume(struct auxiliary_device *adev) +{ + return 0; +} + +static const struct auxiliary_device_id mlx5_dpll_id_table[] = { + { .name = MLX5_ADEV_NAME ".dpll", }, + {}, +}; + +MODULE_DEVICE_TABLE(auxiliary, mlx5_dpll_id_table); + +static struct auxiliary_driver mlx5_dpll_driver = { + .name = "dpll", + .probe = mlx5_dpll_probe, + .remove = mlx5_dpll_remove, + .suspend = mlx5_dpll_suspend, + .resume = mlx5_dpll_resume, + .id_table = mlx5_dpll_id_table, +}; + +static int __init mlx5_dpll_init(void) +{ + return auxiliary_driver_register(&mlx5_dpll_driver); +} + +static void __exit mlx5_dpll_exit(void) +{ + auxiliary_driver_unregister(&mlx5_dpll_driver); +} + +module_init(mlx5_dpll_init); +module_exit(mlx5_dpll_exit); + +MODULE_AUTHOR("Jiri Pirko "); +MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) DPLL driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 7a898113b6b7..3cfa30b86878 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -154,6 +154,8 @@ enum { MLX5_REG_MCC = 0x9062, MLX5_REG_MCDA = 0x9063, MLX5_REG_MCAM = 0x907f, + MLX5_REG_MSECQ = 0x9155, + MLX5_REG_MSEES = 0x9156, MLX5_REG_MIRC = 0x9162, MLX5_REG_SBCAM = 0xB01F, MLX5_REG_RESOURCE_DUMP = 0xC000, diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index e47d6c58da35..6ce11b43bf39 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -10143,7 +10143,9 @@ struct mlx5_ifc_mcam_access_reg_bits2 { u8 mirc[0x1]; u8 regs_97_to_96[0x2]; - u8 regs_95_to_64[0x20]; + u8 regs_95_to_87[0x09]; + u8 synce_registers[0x2]; + u8 regs_84_to_64[0x15]; u8 regs_63_to_32[0x20]; @@ -12505,4 +12507,59 @@ struct mlx5_ifc_modify_page_track_obj_in_bits { struct mlx5_ifc_page_track_bits obj_context; }; +struct mlx5_ifc_msecq_reg_bits { + u8 reserved_at_0[0x20]; + + u8 reserved_at_20[0x12]; + u8 network_option[0x2]; + u8 local_ssm_code[0x4]; + u8 local_enhanced_ssm_code[0x8]; + + u8 local_clock_identity[0x40]; + + u8 reserved_at_80[0x180]; +}; + +enum { + MLX5_MSEES_FIELD_SELECT_ENABLE = BIT(0), + MLX5_MSEES_FIELD_SELECT_ADMIN_STATUS = BIT(1), + MLX5_MSEES_FIELD_SELECT_ADMIN_FREQ_MEASURE = BIT(2), +}; + +enum mlx5_msees_admin_status { + MLX5_MSEES_ADMIN_STATUS_FREE_RUNNING = 0x0, + MLX5_MSEES_ADMIN_STATUS_TRACK = 0x1, +}; + +enum mlx5_msees_oper_status { + MLX5_MSEES_OPER_STATUS_FREE_RUNNING = 0x0, + MLX5_MSEES_OPER_STATUS_SELF_TRACK = 0x1, + MLX5_MSEES_OPER_STATUS_OTHER_TRACK = 0x2, + MLX5_MSEES_OPER_STATUS_HOLDOVER = 0x3, + MLX5_MSEES_OPER_STATUS_FAIL_HOLDOVER = 0x4, + MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING = 0x5, +}; + +struct mlx5_ifc_msees_reg_bits { + u8 reserved_at_0[0x8]; + u8 local_port[0x8]; + u8 pnat[0x2]; + u8 lp_msb[0x2]; + u8 reserved_at_14[0xc]; + + u8 field_select[0x20]; + + u8 admin_status[0x4]; + u8 oper_status[0x4]; + u8 ho_acq[0x1]; + u8 reserved_at_49[0xc]; + u8 admin_freq_measure[0x1]; + u8 oper_freq_measure[0x1]; + u8 failure_reason[0x9]; + + u8 frequency_diff[0x20]; + + u8 reserved_at_80[0x180]; +}; + #endif /* MLX5_IFC_H */