From: Boris Brezillon <boris.brezillon@bootlin.com>
To: Wolfram Sang <wsa@the-dreams.de>,
linux-i2c@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
linux-doc@vger.kernel.org,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Arnd Bergmann <arnd@arndb.de>
Cc: Przemyslaw Sroka <psroka@cadence.com>,
Arkadiusz Golec <agolec@cadence.com>,
Alan Douglas <adouglas@cadence.com>,
Bartosz Folta <bfolta@cadence.com>, Damian Kos <dkos@cadence.com>,
Alicja Jurasik-Urbaniak <alicja@cadence.com>,
Cyprian Wronka <cwronka@cadence.com>,
Suresh Punnoose <sureshp@cadence.com>,
Rafal Ciepiela <rafalc@cadence.com>,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
Nishanth Menon <nm@ti.com>, Rob Herring <robh+dt@kernel.org>,
Pawel Moll <pawel.moll@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Ian Campbell <ijc+devicetree@hellion.org.uk>,
Kumar Gala <galak@codeaurora.org>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Vitor Soares <Vitor.Soares@synopsys.com>,
Geert Uytterhoeven <geert@linux-m68k.org>
Subject: [PATCH v3 01/11] i2c: Export of_i2c_get_board_info()
Date: Fri, 23 Mar 2018 12:00:10 +0100 [thread overview]
Message-ID: <20180323110020.19080-2-boris.brezillon@bootlin.com> (raw)
In-Reply-To: <20180323110020.19080-1-boris.brezillon@bootlin.com>
From: Boris Brezillon <boris.brezillon@free-electrons.com>
I3C busses have to know about all I2C devices connected on the I3C bus
to properly initialize the I3C master, and I2C frames can't be sent on
the bus until this initialization is done.
We can't let the I2C core parse the DT and instantiate I2C devices as
part of its i2c_add_adapter() procedure because, when done this way,
I2C devices are directly registered to the device-model and might be
attached to drivers which could in turn start sending frames on the bus,
which won't work since, as said above, the bus is not yet initialized.
Export of_i2c_register_device() in order to let the I3C core parse the
I2C device nodes by itself and initialize the bus.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
Changes in v2:
- fix memset() call
- rebase on v4.15-rc1
---
drivers/i2c/i2c-core-base.c | 2 +-
drivers/i2c/i2c-core-of.c | 66 ++++++++++++++++++++++++++-------------------
include/linux/i2c.h | 10 +++++++
3 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 5a00bf443d06..e57715f5064c 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -736,7 +736,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type;
- client->dev.of_node = info->of_node;
+ client->dev.of_node = of_node_get(info->of_node);
client->dev.fwnode = info->fwnode;
i2c_dev_set_name(adap, client, info);
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index 8d474bb1dc15..7470bc418a3b 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -22,56 +22,66 @@
#include "i2c-core.h"
-static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
- struct device_node *node)
+int of_i2c_get_board_info(struct device *dev, struct device_node *node,
+ struct i2c_board_info *info)
{
- struct i2c_client *result;
- struct i2c_board_info info = {};
- struct dev_archdata dev_ad = {};
- const __be32 *addr_be;
u32 addr;
- int len;
+ int ret;
- dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
+ memset(info, 0, sizeof(*info));
- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
- dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n",
- node);
- return ERR_PTR(-EINVAL);
+ if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) {
+ dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);
+ return -EINVAL;
}
- addr_be = of_get_property(node, "reg", &len);
- if (!addr_be || (len < sizeof(*addr_be))) {
- dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node);
- return ERR_PTR(-EINVAL);
+ ret = of_property_read_u32(node, "reg", &addr);
+ if (ret) {
+ dev_err(dev, "of_i2c: invalid reg on %pOF\n", node);
+ return ret;
}
- addr = be32_to_cpup(addr_be);
if (addr & I2C_TEN_BIT_ADDRESS) {
addr &= ~I2C_TEN_BIT_ADDRESS;
- info.flags |= I2C_CLIENT_TEN;
+ info->flags |= I2C_CLIENT_TEN;
}
if (addr & I2C_OWN_SLAVE_ADDRESS) {
addr &= ~I2C_OWN_SLAVE_ADDRESS;
- info.flags |= I2C_CLIENT_SLAVE;
+ info->flags |= I2C_CLIENT_SLAVE;
}
- if (i2c_check_addr_validity(addr, info.flags)) {
- dev_err(&adap->dev, "of_i2c: invalid addr=%x on %pOF\n",
- addr, node);
- return ERR_PTR(-EINVAL);
+ ret = i2c_check_addr_validity(addr, info->flags);
+ if (ret) {
+ dev_err(dev, "of_i2c: invalid addr=%x on %pOF\n", addr, node);
+ return ret;
}
- info.addr = addr;
- info.of_node = of_node_get(node);
- info.archdata = &dev_ad;
+ info->addr = addr;
+ info->of_node = node;
if (of_property_read_bool(node, "host-notify"))
- info.flags |= I2C_CLIENT_HOST_NOTIFY;
+ info->flags |= I2C_CLIENT_HOST_NOTIFY;
if (of_get_property(node, "wakeup-source", NULL))
- info.flags |= I2C_CLIENT_WAKE;
+ info->flags |= I2C_CLIENT_WAKE;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_i2c_get_board_info);
+
+static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
+ struct device_node *node)
+{
+ struct i2c_client *result;
+ struct i2c_board_info info;
+ int ret;
+
+ dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
+
+ ret = of_i2c_get_board_info(&adap->dev, node, &info);
+ if (ret)
+ return ERR_PTR(ret);
result = i2c_new_device(adap, &info);
if (result == NULL) {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 419a38e7c315..3e38c10748e3 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -873,6 +873,9 @@ extern const struct of_device_id
*i2c_of_match_device(const struct of_device_id *matches,
struct i2c_client *client);
+int of_i2c_get_board_info(struct device *dev, struct device_node *node,
+ struct i2c_board_info *info);
+
#else
static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
@@ -897,6 +900,13 @@ static inline const struct of_device_id
return NULL;
}
+static inline int of_i2c_get_board_info(struct device *dev,
+ struct device_node *node,
+ struct i2c_board_info *info)
+{
+ return -ENOTSUPP;
+}
+
#endif /* CONFIG_OF */
#if IS_ENABLED(CONFIG_ACPI)
--
2.14.1
next prev parent reply other threads:[~2018-03-23 11:00 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-23 11:00 [PATCH v3 00/11] Add the I3C subsystem Boris Brezillon
2018-03-23 11:00 ` Boris Brezillon [this message]
2018-03-24 22:35 ` [PATCH v3 01/11] i2c: Export of_i2c_get_board_info() Wolfram Sang
2018-03-24 22:38 ` Wolfram Sang
2018-03-25 10:21 ` Boris Brezillon
2018-03-25 10:19 ` Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 02/11] i3c: Add core I3C infrastructure Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 03/11] docs: driver-api: Add I3C documentation Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 04/11] i3c: Add sysfs ABI spec Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 05/11] dt-bindings: i3c: Document core bindings Boris Brezillon
2018-03-23 12:47 ` Peter Rosin
2018-03-23 13:58 ` Boris Brezillon
2018-03-26 10:22 ` Geert Uytterhoeven
2018-03-26 11:19 ` Boris Brezillon
2018-03-26 22:24 ` Rob Herring
2018-03-28 8:19 ` Boris Brezillon
2018-03-28 16:42 ` Rob Herring
2018-03-28 17:28 ` Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 06/11] dt-bindings: i3c: Add macros to help fill I3C/I2C device's reg property Boris Brezillon
2018-03-26 22:25 ` Rob Herring
2018-03-23 11:00 ` [PATCH v3 07/11] MAINTAINERS: Add myself as the I3C subsystem maintainer Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 08/11] i3c: master: Add driver for Cadence IP Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 09/11] dt-bindings: i3c: Document Cadence I3C master bindings Boris Brezillon
2018-03-23 11:10 ` Thomas Petazzoni
2018-03-23 13:59 ` Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 10/11] gpio: Add a driver for Cadence I3C GPIO expander Boris Brezillon
2018-03-23 11:00 ` [PATCH v3 11/11] dt-bindings: gpio: Add bindings for Cadence I3C gpio expander Boris Brezillon
2018-03-26 10:12 ` Geert Uytterhoeven
2018-03-26 11:25 ` Boris Brezillon
2018-03-26 11:35 ` Geert Uytterhoeven
2018-03-26 10:17 ` Geert Uytterhoeven
2018-03-26 11:21 ` Boris Brezillon
2018-03-26 22:25 ` Rob Herring
2018-03-23 11:03 ` [PATCH v3 00/11] Add the I3C subsystem Boris Brezillon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180323110020.19080-2-boris.brezillon@bootlin.com \
--to=boris.brezillon@bootlin.com \
--cc=Vitor.Soares@synopsys.com \
--cc=adouglas@cadence.com \
--cc=agolec@cadence.com \
--cc=alicja@cadence.com \
--cc=arnd@arndb.de \
--cc=bfolta@cadence.com \
--cc=corbet@lwn.net \
--cc=cwronka@cadence.com \
--cc=devicetree@vger.kernel.org \
--cc=dkos@cadence.com \
--cc=galak@codeaurora.org \
--cc=geert@linux-m68k.org \
--cc=gregkh@linuxfoundation.org \
--cc=ijc+devicetree@hellion.org.uk \
--cc=linux-doc@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=nm@ti.com \
--cc=pawel.moll@arm.com \
--cc=psroka@cadence.com \
--cc=rafalc@cadence.com \
--cc=robh+dt@kernel.org \
--cc=sureshp@cadence.com \
--cc=thomas.petazzoni@free-electrons.com \
--cc=wsa@the-dreams.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).