Message ID | 1450291460-10514-4-git-send-email-wsa@the-dreams.de (mailing list archive) |
---|---|
State | RFC, archived |
Headers | show |
Hello. On 12/16/2015 09:44 PM, Wolfram Sang wrote: > From: Wolfram Sang <wsa+renesas@sang-engineering.com> > > In multi master mode, the IP core needs to be always active for > arbitration reasons. Get the config from DT and set up PM depending on > the config. > > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > --- > drivers/i2c/busses/i2c-rcar.c | 17 ++++++++++++++--- > 1 file changed, 14 insertions(+), 3 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c > index 79fd2aab8fa087..7c523dcaee3e48 100644 > --- a/drivers/i2c/busses/i2c-rcar.c > +++ b/drivers/i2c/busses/i2c-rcar.c [...] > @@ -630,7 +633,13 @@ static int rcar_i2c_probe(struct platform_device *pdev) > goto out_pm_put; > > rcar_i2c_init(priv); > - pm_runtime_put(dev); > + > + /* Don't suspend when multi-master to keep arbitration working */ > + if (of_get_property(dev->of_node, "multi-master", NULL)) of_property_read_bool(), perhaps? [...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 79fd2aab8fa087..7c523dcaee3e48 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -96,6 +96,9 @@ #define ID_DONE (1 << 2) #define ID_ARBLOST (1 << 3) #define ID_NACK (1 << 4) +/* persistent flags */ +#define ID_P_PM_BLOCKED (1 << 31) +#define ID_P_MASK ID_P_PM_BLOCKED enum rcar_i2c_type { I2C_RCAR_GEN1, @@ -277,7 +280,7 @@ static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) { priv->msg++; priv->msgs_left--; - priv->flags = 0; + priv->flags &= ID_P_MASK; rcar_i2c_prepare_msg(priv); } @@ -495,7 +498,7 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, /* init first message */ priv->msg = msgs; priv->msgs_left = num; - priv->flags = ID_FIRST_MSG; + priv->flags = (priv->flags & ID_P_MASK) | ID_FIRST_MSG; rcar_i2c_prepare_msg(priv); time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE, @@ -630,7 +633,13 @@ static int rcar_i2c_probe(struct platform_device *pdev) goto out_pm_put; rcar_i2c_init(priv); - pm_runtime_put(dev); + + /* Don't suspend when multi-master to keep arbitration working */ + if (of_get_property(dev->of_node, "multi-master", NULL)) + priv->flags |= ID_P_PM_BLOCKED; + else + pm_runtime_put(dev); + irq = platform_get_irq(pdev, 0); ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, dev_name(dev), priv); @@ -664,6 +673,8 @@ static int rcar_i2c_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; i2c_del_adapter(&priv->adap); + if (priv->flags & ID_P_PM_BLOCKED) + pm_runtime_put(dev); pm_runtime_disable(dev); return 0;