Message ID | 20221208104006.316606-2-tomi.valkeinen@ideasonboard.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp121647wrr; Thu, 8 Dec 2022 02:47:51 -0800 (PST) X-Google-Smtp-Source: AA0mqf5PR9a4PX/bKp2PF9SFybsWPNgpEJ1bJ2uILwJjkYmj/LHSe3YrttIKWsl+UGGWZrxmatTP X-Received: by 2002:a17:902:9897:b0:186:a98c:4ab8 with SMTP id s23-20020a170902989700b00186a98c4ab8mr78103818plp.118.1670496471206; Thu, 08 Dec 2022 02:47:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670496471; cv=none; d=google.com; s=arc-20160816; b=qyOFfxxogaZ0yUocHulcuHDjmNBrPstN+xunpaBXRm1diYGIrZdX2PkOk0/GiJc9mB jzU0QMSp7XEFl+0s6OwTLyqc9J6pP/c5hqDGNkVXk8PsdflH5wz08mSlGdpRCZauAmAy VZH3g6kLK4RuJ8hYeFufEZx8BgvLvsJfovfEX0f/OukRik74VFiAeIzGPYerCtHpabof 1mLr984Ciapja4wpI/LI7DeJPFkjIb2kDFTft3ycjJzF1US3xUGt6pLZ6sJl51yIGRA5 ROLHBAQX/9tps1h3v+ahkvMKSTyqRKpk26kS3MERVWA4/VpO8qBzxKSMw2Aa2iaFX3El hHEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=u2vkTmC0MUTy1TsDnElXxmMzsE3x/IEra0ctklTPu/s=; b=uBNKjuKjiel1YxS5MMeqnzWsyWQFWKaXp89MkKy8xymPzDg/Cz4dmsWkPT2PDThvpZ lv5Iv+yqcFAJEtaOqPAMyQyZgAn8D3mtLPaAmqq/vmul59sD6zFCFyrvE1XIBgKtST0T h+nDyOa7QdCchZK8qErdP0rzWsRaaV4LcPbKhaEp4bdeKjZyg4v9ZfJGknQ7LTMSwm1v PXhX+QEfclEJhmhj0EsA4ZKF9HGNfKKHluZ0CvKSF+3K9/sXQranXUj8E4QbJ1LXDYBK mYFpUlSjKS0Wyv0bKXhOnFYAP4HZt3Cycl8gHgUavXNoWCgBGZtzig+sUtlkO1YGwiqo o97w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b=CQkedEqP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m10-20020a17090a34ca00b00219648ff3a5si3693831pjf.171.2022.12.08.02.47.38; Thu, 08 Dec 2022 02:47:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b=CQkedEqP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230304AbiLHKnu (ORCPT <rfc822;foxyelen666@gmail.com> + 99 others); Thu, 8 Dec 2022 05:43:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230096AbiLHKnT (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 8 Dec 2022 05:43:19 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DD9BD4A; Thu, 8 Dec 2022 02:40:27 -0800 (PST) Received: from desky.lan (91-154-32-225.elisa-laajakaista.fi [91.154.32.225]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EE32B9D9; Thu, 8 Dec 2022 11:40:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1670496025; bh=qqlP9y4CxrbgrpwUUQtSV2m4Q9RgrkWSjW1olrXBJFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CQkedEqPUuFFPv87Gd/8wD85ZblpiG5JbFMhLP9siK7EJ62KJmi7fMpz1mdGnqrZz 2kAWJltrhhHX5saJ8Kssqb/hB7dO1dlU5qS0FObnh+StI6kxHYXQ/6XN3wP4JuBmft vf+lkBlx+mfWiMrqu0Y4nZq5pfeqIyfkI0SlrHE4= From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Wolfram Sang <wsa@kernel.org>, Luca Ceresoli <luca.ceresoli@bootlin.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Matti Vaittinen <Matti.Vaittinen@fi.rohmeurope.com> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>, Peter Rosin <peda@axentia.se>, Liam Girdwood <lgirdwood@gmail.com>, Mark Brown <broonie@kernel.org>, Sakari Ailus <sakari.ailus@linux.intel.com>, Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>, Michael Tretter <m.tretter@pengutronix.de>, Shawn Tu <shawnx.tu@intel.com>, Hans Verkuil <hverkuil@xs4all.nl>, Mike Pagano <mpagano@gentoo.org>, =?utf-8?q?Krzysztof_Ha=C5=82asa?= <khalasa@piap.pl>, Marek Vasut <marex@denx.de>, Luca Ceresoli <luca@lucaceresoli.net>, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Subject: [PATCH v5 1/8] i2c: core: let adapters be notified of client attach/detach Date: Thu, 8 Dec 2022 12:39:59 +0200 Message-Id: <20221208104006.316606-2-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221208104006.316606-1-tomi.valkeinen@ideasonboard.com> References: <20221208104006.316606-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751642507801671707?= X-GMAIL-MSGID: =?utf-8?q?1751642507801671707?= |
Series |
i2c-atr and FPDLink
|
|
Commit Message
Tomi Valkeinen
Dec. 8, 2022, 10:39 a.m. UTC
From: Luca Ceresoli <luca@lucaceresoli.net> An adapter might need to know when a new device is about to be added. This will soon bee needed to implement an "I2C address translator" (ATR for short), a device that propagates I2C transactions with a different slave address (an "alias" address). An ATR driver needs to know when a slave is being added to find a suitable alias and program the device translation map. Add an attach/detach callback pair to allow adapter drivers to be notified of clients being added and removed. Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> --- drivers/i2c/i2c-core-base.c | 18 +++++++++++++++++- include/linux/i2c.h | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
Comments
On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: > From: Luca Ceresoli <luca@lucaceresoli.net> > > An adapter might need to know when a new device is about to be > added. This will soon bee needed to implement an "I2C address > translator" (ATR for short), a device that propagates I2C transactions > with a different slave address (an "alias" address). An ATR driver > needs to know when a slave is being added to find a suitable alias and > program the device translation map. > > Add an attach/detach callback pair to allow adapter drivers to be > notified of clients being added and removed. ... > + if (adap->attach_ops && > + adap->attach_ops->attach_client && > + adap->attach_ops->attach_client(adap, info, client) != 0) > + goto out_remove_swnode; With a temporary variable it becomes better ... *ops = adap->attach_ops; if (ops && ops->attach_client && ops->attach_client(adap, info, client)) Also notice drop of unneeded ' != 0' part. > status = device_register(&client->dev); > if (status) > - goto out_remove_swnode; > + goto out_detach_client; > > dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", > client->name, dev_name(&client->dev)); > > return client; > > +out_detach_client: > + if (adap->attach_ops && adap->attach_ops->detach_client) > + adap->attach_ops->detach_client(adap, client); In the similar way. ... > + if (adap->attach_ops && > + adap->attach_ops->detach_client) > + adap->attach_ops->detach_client(adap, client); In the similar way.
On 08/12/2022 14:30, Andy Shevchenko wrote: > On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: >> From: Luca Ceresoli <luca@lucaceresoli.net> >> >> An adapter might need to know when a new device is about to be >> added. This will soon bee needed to implement an "I2C address >> translator" (ATR for short), a device that propagates I2C transactions >> with a different slave address (an "alias" address). An ATR driver >> needs to know when a slave is being added to find a suitable alias and >> program the device translation map. >> >> Add an attach/detach callback pair to allow adapter drivers to be >> notified of clients being added and removed. > > ... > >> + if (adap->attach_ops && >> + adap->attach_ops->attach_client && >> + adap->attach_ops->attach_client(adap, info, client) != 0) >> + goto out_remove_swnode; > > With a temporary variable it becomes better > Ok. Tomi
Hi Tomi and Luca, Thank you for the patch. On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: > From: Luca Ceresoli <luca@lucaceresoli.net> > > An adapter might need to know when a new device is about to be > added. This will soon bee needed to implement an "I2C address > translator" (ATR for short), a device that propagates I2C transactions > with a different slave address (an "alias" address). An ATR driver > needs to know when a slave is being added to find a suitable alias and > program the device translation map. > > Add an attach/detach callback pair to allow adapter drivers to be > notified of clients being added and removed. This may be a stupid question, but couldn't you instead use the BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE bus notifiers ? > Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> > --- > drivers/i2c/i2c-core-base.c | 18 +++++++++++++++++- > include/linux/i2c.h | 16 ++++++++++++++++ > 2 files changed, 33 insertions(+), 1 deletion(-) > > diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c > index b4edf10e8fd0..c8bc71b1db82 100644 > --- a/drivers/i2c/i2c-core-base.c > +++ b/drivers/i2c/i2c-core-base.c > @@ -966,15 +966,23 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf > } > } > > + if (adap->attach_ops && > + adap->attach_ops->attach_client && > + adap->attach_ops->attach_client(adap, info, client) != 0) > + goto out_remove_swnode; > + > status = device_register(&client->dev); > if (status) > - goto out_remove_swnode; > + goto out_detach_client; > > dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", > client->name, dev_name(&client->dev)); > > return client; > > +out_detach_client: > + if (adap->attach_ops && adap->attach_ops->detach_client) > + adap->attach_ops->detach_client(adap, client); > out_remove_swnode: > device_remove_software_node(&client->dev); > out_err_put_of_node: > @@ -996,9 +1004,17 @@ EXPORT_SYMBOL_GPL(i2c_new_client_device); > */ > void i2c_unregister_device(struct i2c_client *client) > { > + struct i2c_adapter *adap; > + > if (IS_ERR_OR_NULL(client)) > return; > > + adap = client->adapter; > + > + if (adap->attach_ops && > + adap->attach_ops->detach_client) > + adap->attach_ops->detach_client(adap, client); > + > if (client->dev.of_node) { > of_node_clear_flag(client->dev.of_node, OF_POPULATED); > of_node_put(client->dev.of_node); > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index f7c49bbdb8a1..9a385b6de388 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -584,6 +584,21 @@ struct i2c_lock_operations { > void (*unlock_bus)(struct i2c_adapter *adapter, unsigned int flags); > }; > > +/** > + * struct i2c_attach_operations - callbacks to notify client attach/detach > + * @attach_client: Notify of new client being attached > + * @detach_client: Notify of new client being detached > + * > + * Both ops are optional. > + */ > +struct i2c_attach_operations { > + int (*attach_client)(struct i2c_adapter *adapter, > + const struct i2c_board_info *info, > + const struct i2c_client *client); > + void (*detach_client)(struct i2c_adapter *adapter, > + const struct i2c_client *client); > +}; > + > /** > * struct i2c_timings - I2C timing information > * @bus_freq_hz: the bus frequency in Hz > @@ -726,6 +741,7 @@ struct i2c_adapter { > > /* data fields that are valid for all devices */ > const struct i2c_lock_operations *lock_ops; > + const struct i2c_attach_operations *attach_ops; > struct rt_mutex bus_lock; > struct rt_mutex mux_lock; >
Hello Laurent, thanks for the feedback and apologies for the delayed reply. On Sun, 11 Dec 2022 18:55:39 +0200 Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote: > Hi Tomi and Luca, > > Thank you for the patch. > > On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: > > From: Luca Ceresoli <luca@lucaceresoli.net> > > > > An adapter might need to know when a new device is about to be > > added. This will soon bee needed to implement an "I2C address > > translator" (ATR for short), a device that propagates I2C transactions > > with a different slave address (an "alias" address). An ATR driver > > needs to know when a slave is being added to find a suitable alias and > > program the device translation map. > > > > Add an attach/detach callback pair to allow adapter drivers to be > > notified of clients being added and removed. > > This may be a stupid question, but couldn't you instead use the > BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE bus notifiers ? I'm not sure they would be the correct tool for this task. Bus notifiers inform about new events on the 'struct bus_type, i.e. any event on the global i2c bus type. In the i2c world this means being notified about new _adapters_, which is exactly what drivers/i2c/i2c-dev.c does. Here, however, we need to be informed about new _clients_ being added under a specific adapter. I'm not sure whether the bus notifiers can inform about new clients in addition of new adapters, but they at least seem unable to provide per-adapter notification. Does that seem correct? Best regards,
On Mon, Dec 19, 2022 at 09:51:43AM +0100, Luca Ceresoli wrote: > On Sun, 11 Dec 2022 18:55:39 +0200 > Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote: > > On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: ... > > This may be a stupid question, but couldn't you instead use the > > BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE bus notifiers ? > > I'm not sure they would be the correct tool for this task. Bus > notifiers inform about new events on the 'struct bus_type, i.e. any > event on the global i2c bus type. In the i2c world this means being > notified about new _adapters_, which is exactly what > drivers/i2c/i2c-dev.c does. > > Here, however, we need to be informed about new _clients_ being added > under a specific adapter. This is for example exactly what ACPI integration in I2C framework does. But... > I'm not sure whether the bus notifiers can > inform about new clients in addition of new adapters, but they at least > seem unable to provide per-adapter notification. ...personally I don't like notifiers, they looks like overkill for this task. > Does that seem correct?
On Mon, Dec 19, 2022 at 11:48:51AM +0200, Andy Shevchenko wrote: > On Mon, Dec 19, 2022 at 09:51:43AM +0100, Luca Ceresoli wrote: > > On Sun, 11 Dec 2022 18:55:39 +0200 Laurent Pinchart wrote: > > > On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: > > ... > > > > This may be a stupid question, but couldn't you instead use the > > > BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE bus notifiers ? > > > > I'm not sure they would be the correct tool for this task. Bus > > notifiers inform about new events on the 'struct bus_type, i.e. any > > event on the global i2c bus type. In the i2c world this means being > > notified about new _adapters_, which is exactly what > > drivers/i2c/i2c-dev.c does. > > > > Here, however, we need to be informed about new _clients_ being added > > under a specific adapter. > > This is for example exactly what ACPI integration in I2C framework does. But... > > > I'm not sure whether the bus notifiers can > > inform about new clients in addition of new adapters, but they at least > > seem unable to provide per-adapter notification. > > ...personally I don't like notifiers, they looks like overkill for this task. But isn't this patch essentially implementing a custom notification system ? If we need notifiers, why would it be better to add an ad-hoc API for I2C instead of using bus notifiers ? > > Does that seem correct?
On Mon, Dec 26, 2022 at 06:54:37PM +0200, Laurent Pinchart wrote: > On Mon, Dec 19, 2022 at 11:48:51AM +0200, Andy Shevchenko wrote: > > On Mon, Dec 19, 2022 at 09:51:43AM +0100, Luca Ceresoli wrote: > > > On Sun, 11 Dec 2022 18:55:39 +0200 Laurent Pinchart wrote: > > > > On Thu, Dec 08, 2022 at 12:39:59PM +0200, Tomi Valkeinen wrote: ... > > > > This may be a stupid question, but couldn't you instead use the > > > > BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE bus notifiers ? > > > > > > I'm not sure they would be the correct tool for this task. Bus > > > notifiers inform about new events on the 'struct bus_type, i.e. any > > > event on the global i2c bus type. In the i2c world this means being > > > notified about new _adapters_, which is exactly what > > > drivers/i2c/i2c-dev.c does. > > > > > > Here, however, we need to be informed about new _clients_ being added > > > under a specific adapter. > > > > This is for example exactly what ACPI integration in I2C framework does. But... > > > > > I'm not sure whether the bus notifiers can > > > inform about new clients in addition of new adapters, but they at least > > > seem unable to provide per-adapter notification. > > > > ...personally I don't like notifiers, they looks like overkill for this task. > > But isn't this patch essentially implementing a custom notification > system ? If we need notifiers, why would it be better to add an ad-hoc > API for I2C instead of using bus notifiers ? Notifiers (as implemented in the Linux kernel) have some drawbacks IIUC. For example, it's not easy to pass the data over it. Another example is the context (you wouldn't know when the notifier be called and if it can hold some locks or not). That said, each case should be discussed individually despite the generic approach being present (i.o.w. do not consider notifiers as a silver bullet in _any_ notification scheme). > > > Does that seem correct?
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index b4edf10e8fd0..c8bc71b1db82 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -966,15 +966,23 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf } } + if (adap->attach_ops && + adap->attach_ops->attach_client && + adap->attach_ops->attach_client(adap, info, client) != 0) + goto out_remove_swnode; + status = device_register(&client->dev); if (status) - goto out_remove_swnode; + goto out_detach_client; dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", client->name, dev_name(&client->dev)); return client; +out_detach_client: + if (adap->attach_ops && adap->attach_ops->detach_client) + adap->attach_ops->detach_client(adap, client); out_remove_swnode: device_remove_software_node(&client->dev); out_err_put_of_node: @@ -996,9 +1004,17 @@ EXPORT_SYMBOL_GPL(i2c_new_client_device); */ void i2c_unregister_device(struct i2c_client *client) { + struct i2c_adapter *adap; + if (IS_ERR_OR_NULL(client)) return; + adap = client->adapter; + + if (adap->attach_ops && + adap->attach_ops->detach_client) + adap->attach_ops->detach_client(adap, client); + if (client->dev.of_node) { of_node_clear_flag(client->dev.of_node, OF_POPULATED); of_node_put(client->dev.of_node); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f7c49bbdb8a1..9a385b6de388 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -584,6 +584,21 @@ struct i2c_lock_operations { void (*unlock_bus)(struct i2c_adapter *adapter, unsigned int flags); }; +/** + * struct i2c_attach_operations - callbacks to notify client attach/detach + * @attach_client: Notify of new client being attached + * @detach_client: Notify of new client being detached + * + * Both ops are optional. + */ +struct i2c_attach_operations { + int (*attach_client)(struct i2c_adapter *adapter, + const struct i2c_board_info *info, + const struct i2c_client *client); + void (*detach_client)(struct i2c_adapter *adapter, + const struct i2c_client *client); +}; + /** * struct i2c_timings - I2C timing information * @bus_freq_hz: the bus frequency in Hz @@ -726,6 +741,7 @@ struct i2c_adapter { /* data fields that are valid for all devices */ const struct i2c_lock_operations *lock_ops; + const struct i2c_attach_operations *attach_ops; struct rt_mutex bus_lock; struct rt_mutex mux_lock;