diff mbox series

[RFC] WIP: i2c: rcar: add HostNotify support

Message ID 20200701080904.11022-1-wsa+renesas@sang-engineering.com
State Superseded
Headers show
Series [RFC] WIP: i2c: rcar: add HostNotify support | expand

Commit Message

Wolfram Sang July 1, 2020, 8:09 a.m. UTC
The I2C core can now utilize a slave interface to handle SMBus
HostNotify events. Enable it in this driver.

Not-yet-Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---

Alain, this is the code needed to enable SMBus HostNotify for the
Renesas R-Car driver already using the binding we discussed yesterday.
I got it to work finally, so we have now two working cases. Good!

I do have some more review comments. I will send them out hopefully
later, but for sure somewhen today.

Thanks for working on it!

 drivers/i2c/busses/i2c-rcar.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

Comments

Wolfram Sang July 1, 2020, 9:27 a.m. UTC | #1
> Alain, this is the code needed to enable SMBus HostNotify for the
> Renesas R-Car driver already using the binding we discussed yesterday.
> I got it to work finally, so we have now two working cases. Good!

BTW I think the DTS additions don't look too bad? It is a grey area,
though...

 &i2c3  {
        pinctrl-0 = <&i2c3_pins>;
        pinctrl-names = "i2c-pwr";
+
+       enable-host-notify;
+
+       dummy@32 {
+               compatible = "dummy";
+               reg = <0x32>;
+               host-notify;
+       };
Wolfram Sang July 1, 2020, 12:16 p.m. UTC | #2
> BTW I think the DTS additions don't look too bad? It is a grey area,
> though...
> 
>  &i2c3  {
>         pinctrl-0 = <&i2c3_pins>;
>         pinctrl-names = "i2c-pwr";
> +
> +       enable-host-notify;

I got another idea. What about a boolean binding "smbus"?

This describes the bus as SMBus (and not I2C bus), so the additional
SMBus restrictions/requirements apply. HostNotify is required for SMBus,
so address 0x08 can't be used. Alert is optional, but still it uses a
reserved address. SMBus timeouts maybe can be handled through this as
well (there is the HWMON specific "smbus-timeout-disable" so far).

So, we have one simple binding for HostNotify and Alert which really
describes the HW.
Alain Volmat July 1, 2020, 12:32 p.m. UTC | #3
On Wed, Jul 01, 2020 at 02:16:33PM +0200, Wolfram Sang wrote:
> 
> > BTW I think the DTS additions don't look too bad? It is a grey area,
> > though...
> > 
> >  &i2c3  {
> >         pinctrl-0 = <&i2c3_pins>;
> >         pinctrl-names = "i2c-pwr";
> > +
> > +       enable-host-notify;
> 
> I got another idea. What about a boolean binding "smbus"?
> 
> This describes the bus as SMBus (and not I2C bus), so the additional
> SMBus restrictions/requirements apply. HostNotify is required for SMBus,
> so address 0x08 can't be used. Alert is optional, but still it uses a
> reserved address. SMBus timeouts maybe can be handled through this as
> well (there is the HWMON specific "smbus-timeout-disable" so far).
> 
> So, we have one simple binding for HostNotify and Alert which really
> describes the HW.

I much prefer this solution than the usage of the smbus_alert irq value
(in case of the i2c-stm32f7). In that case, I'd only set smbus boolean
to enable both SMBus Host-Notify & SMBus Alert.
In case of a device having a dedicated irq for SMBus Alert, smbus_alert
irq binding would still be needed.

Just my 2 cents about another aspect regarding SMBus Alert, since alert
is coming from another pin and not the usual SCL / SCK, when SMBus Alert
has to be used, there is a very good chance to have a pinctrl entry which
is different from not using SMBus Alert.
Indeed, even if we need SMBus, but don't need SMBus Alert, the SMBus Alert
input pin might be used for something else.
But this of course doesn't prevent to use the smbus boolean binding.

>
Wolfram Sang July 1, 2020, 1:21 p.m. UTC | #4
> > I got another idea. What about a boolean binding "smbus"?
...
> 
> I much prefer this solution than the usage of the smbus_alert irq value
> (in case of the i2c-stm32f7). In that case, I'd only set smbus boolean
> to enable both SMBus Host-Notify & SMBus Alert.

Correct.

> In case of a device having a dedicated irq for SMBus Alert, smbus_alert
> irq binding would still be needed.

Yes, that was my idea. Let's use "smbus".

> Just my 2 cents about another aspect regarding SMBus Alert, since alert
> is coming from another pin and not the usual SCL / SCK, when SMBus Alert
> has to be used, there is a very good chance to have a pinctrl entry which
> is different from not using SMBus Alert.
> Indeed, even if we need SMBus, but don't need SMBus Alert, the SMBus Alert
> input pin might be used for something else.
> But this of course doesn't prevent to use the smbus boolean binding.

I am not sure if I fully get this point. Either we have a dedicated line
(your case) or we need to use a GPIO as an interrupt line (my case). So,
either this is configured correctly in DT and added as a "smbus_alert"
irq. Or this irq is missing and then the driver will ignore SMBusAlert
and the GPIO can be freely used/muxed. Or?
Alain Volmat July 1, 2020, 1:46 p.m. UTC | #5
On Wed, Jul 01, 2020 at 03:21:45PM +0200, Wolfram Sang wrote:
> 
> > > I got another idea. What about a boolean binding "smbus"?
> ...
> > 
> > I much prefer this solution than the usage of the smbus_alert irq value
> > (in case of the i2c-stm32f7). In that case, I'd only set smbus boolean
> > to enable both SMBus Host-Notify & SMBus Alert.
> 
> Correct.
> 
> > In case of a device having a dedicated irq for SMBus Alert, smbus_alert
> > irq binding would still be needed.
> 
> Yes, that was my idea. Let's use "smbus".

Yes, good. I change the binding to this one then.

> 
> > Just my 2 cents about another aspect regarding SMBus Alert, since alert
> > is coming from another pin and not the usual SCL / SCK, when SMBus Alert
> > has to be used, there is a very good chance to have a pinctrl entry which
> > is different from not using SMBus Alert.
> > Indeed, even if we need SMBus, but don't need SMBus Alert, the SMBus Alert
> > input pin might be used for something else.
> > But this of course doesn't prevent to use the smbus boolean binding.
> 
> I am not sure if I fully get this point. Either we have a dedicated line
> (your case) or we need to use a GPIO as an interrupt line (my case). So,
> either this is configured correctly in DT and added as a "smbus_alert"
> irq. Or this irq is missing and then the driver will ignore SMBusAlert
> and the GPIO can be freely used/muxed. Or?

Well yes and no (for my case). I am NOT relying on GPIO for the SMBus Alert,
this is handled by the I2C controller itself via a dedicated input into the
controller. However, the pin itself can still be shared with other IPs,
depending on how the DT is configured. Just usual pinmux stuff. So I was
just mentioning that the pinctrl should also be correct to properly configure
the pinmuxing for that SMBus Alert input signal as well.
Sorry, this is just making the story more confusing for something which in
fact wasn't important in the first place probably. There is no real issue
here.

>
Wolfram Sang July 1, 2020, 2 p.m. UTC | #6
> Well yes and no (for my case). I am NOT relying on GPIO for the SMBus Alert,
> this is handled by the I2C controller itself via a dedicated input into the
> controller. However, the pin itself can still be shared with other IPs,

I see.

> depending on how the DT is configured. Just usual pinmux stuff. So I was
> just mentioning that the pinctrl should also be correct to properly configure
> the pinmuxing for that SMBus Alert input signal as well.

Well, yes, the DT needs to be correct :) Same for pinmuxing SCL and SDA,
right?

> Sorry, this is just making the story more confusing for something which in
> fact wasn't important in the first place probably. There is no real issue
> here.

No worries. It is better than to miss something.
Alain Volmat July 1, 2020, 2:37 p.m. UTC | #7
On Wed, Jul 01, 2020 at 03:21:45PM +0200, Wolfram Sang wrote:
> 
> > > I got another idea. What about a boolean binding "smbus"?
> ...
> > 
> > I much prefer this solution than the usage of the smbus_alert irq value
> > (in case of the i2c-stm32f7). In that case, I'd only set smbus boolean
> > to enable both SMBus Host-Notify & SMBus Alert.
> 
> Correct.
> 
> > In case of a device having a dedicated irq for SMBus Alert, smbus_alert
> > irq binding would still be needed.
> 
> Yes, that was my idea. Let's use "smbus".

Hum ... sorry ... I'm having some doubt about such a generic 'smbus' naming.
I mean, stating 'smbus' within the controller node kind of says
"I am working in SMBus mode", and not only "I am supporting Host-Notify & Alert".
In such case, NOT having 'smbus' would mean that the driver do not support
SMBUS and SMBus xfer and all smbus related stuff would get disabled ...
We for sure do not want to have everybody add a smbus property in their DT
if they support SMBus xfer for example.

This is probably too wide, don't you think ?

> 
> > Just my 2 cents about another aspect regarding SMBus Alert, since alert
> > is coming from another pin and not the usual SCL / SCK, when SMBus Alert
> > has to be used, there is a very good chance to have a pinctrl entry which
> > is different from not using SMBus Alert.
> > Indeed, even if we need SMBus, but don't need SMBus Alert, the SMBus Alert
> > input pin might be used for something else.
> > But this of course doesn't prevent to use the smbus boolean binding.
> 
> I am not sure if I fully get this point. Either we have a dedicated line
> (your case) or we need to use a GPIO as an interrupt line (my case). So,
> either this is configured correctly in DT and added as a "smbus_alert"
> irq. Or this irq is missing and then the driver will ignore SMBusAlert
> and the GPIO can be freely used/muxed. Or?
>
Wolfram Sang July 1, 2020, 2:57 p.m. UTC | #8
> Hum ... sorry ... I'm having some doubt about such a generic 'smbus' naming.
> I mean, stating 'smbus' within the controller node kind of says
> "I am working in SMBus mode", and not only "I am supporting Host-Notify & Alert".
> In such case, NOT having 'smbus' would mean that the driver do not support
> SMBUS and SMBus xfer and all smbus related stuff would get disabled ...
> We for sure do not want to have everybody add a smbus property in their DT
> if they support SMBus xfer for example.
> 
> This is probably too wide, don't you think ?

It would be, yet I don't think this is case.

The "smbus" property means that _additional_ SMBus restrictions apply to
that bus. Like additional timeout values, reserved addresses etc...

It does not mean that we can't use SMBus style communication on an I2C
bus. We can because we can easily emulate it. This is not an additional
restriction.

So it rather means "SMBus restrictions apply here". No such properties
means no such restrictions. But then you can't have HostNotify and Alert
because the addresses are not reserved.

We can update the binding to "smbus-restrictions" perhaps, although it
doesn't really sound nice to me. Maybe Rob also has an idea.

I'll send a patch later and then we will see what he says.

D'accord?
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 19e89ab73b6f..9bc23d72ccae 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -20,6 +20,7 @@ 
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/i2c-smbus.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -105,10 +106,11 @@ 
 #define ID_ARBLOST	(1 << 3)
 #define ID_NACK		(1 << 4)
 /* persistent flags */
+#define ID_P_HOST_NOTIFY	BIT(28)
 #define ID_P_REP_AFTER_RD	BIT(29)
 #define ID_P_NO_RXDMA		BIT(30) /* HW forbids RXDMA sometimes */
 #define ID_P_PM_BLOCKED		BIT(31)
-#define ID_P_MASK		GENMASK(31, 29)
+#define ID_P_MASK		GENMASK(31, 28)
 
 enum rcar_i2c_type {
 	I2C_RCAR_GEN1,
@@ -140,6 +142,8 @@  struct rcar_i2c_priv {
 
 	struct reset_control *rstc;
 	int irq;
+
+	struct i2c_client *host_client;
 };
 
 #define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
@@ -881,14 +885,21 @@  static int rcar_unreg_slave(struct i2c_client *slave)
 
 static u32 rcar_i2c_func(struct i2c_adapter *adap)
 {
+	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
+
 	/*
 	 * This HW can't do:
 	 * I2C_SMBUS_QUICK (setting FSB during START didn't work)
 	 * I2C_M_NOSTART (automatically sends address after START)
 	 * I2C_M_IGNORE_NAK (automatically sends STOP after NAK)
 	 */
-	return I2C_FUNC_I2C | I2C_FUNC_SLAVE |
-		(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+	u32 func = I2C_FUNC_I2C | I2C_FUNC_SLAVE |
+		   (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+
+	if (priv->flags & ID_P_HOST_NOTIFY)
+		func |= I2C_FUNC_SMBUS_HOST_NOTIFY;
+
+	return func;
 }
 
 static const struct i2c_algorithm rcar_i2c_algo = {
@@ -986,6 +997,8 @@  static int rcar_i2c_probe(struct platform_device *pdev)
 	else
 		pm_runtime_put(dev);
 
+	if (of_property_read_bool(dev->of_node, "enable-host-notify"))
+		priv->flags |= ID_P_HOST_NOTIFY;
 
 	priv->irq = platform_get_irq(pdev, 0);
 	ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0, dev_name(dev), priv);
@@ -1000,10 +1013,20 @@  static int rcar_i2c_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto out_pm_disable;
 
+	if (priv->flags & ID_P_HOST_NOTIFY) {
+		priv->host_client = i2c_new_smbus_host_notify_device(adap);
+		if (IS_ERR(priv->host_client)) {
+			ret = PTR_ERR(priv->host_client);
+			goto out_del_device;
+		}
+	}
+
 	dev_info(dev, "probed\n");
 
 	return 0;
 
+ out_del_device:
+	i2c_del_adapter(&priv->adap);
  out_pm_put:
 	pm_runtime_put(dev);
  out_pm_disable:
@@ -1017,6 +1040,8 @@  static int rcar_i2c_remove(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 
 	i2c_del_adapter(&priv->adap);
+	if (priv->host_client)
+		i2c_free_smbus_host_notify_device(priv->host_client);
 	rcar_i2c_release_dma(priv);
 	if (priv->flags & ID_P_PM_BLOCKED)
 		pm_runtime_put(dev);