* [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
[not found] ` <1369995191-20855-1-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
@ 2013-05-31 10:13 ` Hebbar Gururaja
2013-06-04 7:11 ` Linus Walleij
[not found] ` <1369995191-20855-10-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 10:13 ` [PATCH 11/11] i2c: omap: " Hebbar Gururaja
1 sibling, 2 replies; 16+ messages in thread
From: Hebbar Gururaja @ 2013-05-31 10:13 UTC (permalink / raw)
To: khilman-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
sudhakar.raj-l0cyMroinI0, linux-lFZ/pmaqli7XmaaqVzeoHQ,
Balaji T K, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, vaibhav.bedia-l0cyMroinI0,
gururaja.hebbar-l0cyMroinI0, linux-omap-u79uwXL29TY76Z2rM5mHXA,
Chris Ball, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Amend the hsmmc controller to optionally take a pin control handle and
set the state of the pins to:
- "default" on boot, resume and before performing a mmc transfer
- "idle" after initial default, after resume default, and after each
mmc/sd card access
- "sleep" on suspend()
By optionally putting the pins into sleep state in the suspend callback
we can accomplish two things.
- One is to minimize current leakage from pins and thus save power,
- second, we can prevent the IP from driving pins output in an
uncontrolled manner, which may happen if the power domain drops the
domain regulator.
If any of the above pin states are missing in dt, a warning message
about the missing state is displayed.
If certain pin-states are not available, to remove this warning message
pass respective state name with null phandler.
Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
Cc: Balaji T K <balajitk-l0cyMroinI0@public.gmane.org>
Cc: Chris Ball <cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org>
Cc: linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
:100644 100644 6e44025... a2d69aa... M drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/omap_hsmmc.c | 79 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 6e44025..a2d69aa 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -183,6 +183,12 @@ struct omap_hsmmc_host {
struct omap_hsmmc_next next_data;
struct omap_mmc_platform_data *pdata;
+
+ /* Three pin states - default, idle & sleep */
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default;
+ struct pinctrl_state *pins_idle;
+ struct pinctrl_state *pins_sleep;
};
static int omap_hsmmc_card_detect(struct device *dev, int slot)
@@ -1775,7 +1781,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
- struct pinctrl *pinctrl;
match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
if (match) {
@@ -1982,10 +1987,46 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
omap_hsmmc_disable_irq(host);
- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
- if (IS_ERR(pinctrl))
- dev_warn(&pdev->dev,
- "pins are not configured from the driver\n");
+ host->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!IS_ERR(host->pinctrl)) {
+ host->pins_default = pinctrl_lookup_state(host->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ if (IS_ERR(host->pins_default))
+ dev_dbg(&pdev->dev, "could not get default pinstate\n");
+ else
+ if (pinctrl_select_state(host->pinctrl,
+ host->pins_default))
+ dev_err(&pdev->dev,
+ "could not set default pinstate\n");
+
+ host->pins_idle = pinctrl_lookup_state(host->pinctrl,
+ PINCTRL_STATE_IDLE);
+ if (IS_ERR(host->pins_idle))
+ dev_dbg(&pdev->dev, "could not get idle pinstate\n");
+ else
+ /* If possible, let's idle until the first transfer */
+ if (pinctrl_select_state(host->pinctrl,
+ host->pins_idle))
+ dev_err(&pdev->dev,
+ "could not set idle pinstate\n");
+
+ host->pins_sleep = pinctrl_lookup_state(host->pinctrl,
+ PINCTRL_STATE_SLEEP);
+ if (IS_ERR(host->pins_sleep))
+ dev_dbg(&pdev->dev, "could not get sleep pinstate\n");
+ } else {
+ /*
+ * Since we continue even when pinctrl node is not found,
+ * Invalidate pins as not available. This is to make sure that
+ * IS_ERR(pins_xxx) results in failure when used.
+ */
+ host->pins_default = ERR_PTR(-ENODATA);
+ host->pins_idle = ERR_PTR(-ENODATA);
+ host->pins_sleep = ERR_PTR(-ENODATA);
+
+ dev_dbg(&pdev->dev, "did not get pins for mmc error: %li\n",
+ PTR_ERR(host->pinctrl));
+ }
omap_hsmmc_protect_card(host);
@@ -2135,6 +2176,12 @@ static int omap_hsmmc_suspend(struct device *dev)
clk_disable_unprepare(host->dbclk);
err:
pm_runtime_put_sync(host->dev);
+
+ /* Optionally let pins go into sleep states */
+ if (!IS_ERR(host->pins_sleep))
+ if (pinctrl_select_state(host->pinctrl, host->pins_sleep))
+ dev_err(dev, "could not set pins to sleep state\n");
+
return ret;
}
@@ -2152,6 +2199,16 @@ static int omap_hsmmc_resume(struct device *dev)
pm_runtime_get_sync(host->dev);
+ /* First go to the default state */
+ if (!IS_ERR(host->pins_default))
+ if (pinctrl_select_state(host->pinctrl, host->pins_default))
+ dev_err(host->dev, "could not set pins to default state\n");
+
+ /* Then let's idle the pins until the next transfer happens */
+ if (!IS_ERR(host->pins_idle))
+ if (pinctrl_select_state(host->pinctrl, host->pins_idle))
+ dev_err(host->dev, "couldn't set pins to idle state\n");
+
if (host->dbclk)
clk_prepare_enable(host->dbclk);
@@ -2185,6 +2242,12 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_save(host);
+
+ /* Optionally let pins go into sleep states */
+ if (!IS_ERR(host->pins_idle))
+ if (pinctrl_select_state(host->pinctrl, host->pins_idle))
+ dev_err(dev, "could not set pins to idle state\n");
+
dev_dbg(dev, "disabled\n");
return 0;
@@ -2195,6 +2258,12 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
struct omap_hsmmc_host *host;
host = platform_get_drvdata(to_platform_device(dev));
+
+ /* Optionaly enable pins to be muxed in and configured */
+ if (!IS_ERR(host->pins_default))
+ if (pinctrl_select_state(host->pinctrl, host->pins_default))
+ dev_err(host->dev, "could not set default pins\n");
+
omap_hsmmc_context_restore(host);
dev_dbg(dev, "enabled\n");
--
1.7.9.5
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <1369995191-20855-1-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 10:13 ` [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support Hebbar Gururaja
@ 2013-05-31 10:13 ` Hebbar Gururaja
[not found] ` <1369995191-20855-12-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 17:34 ` Kevin Hilman
1 sibling, 2 replies; 16+ messages in thread
From: Hebbar Gururaja @ 2013-05-31 10:13 UTC (permalink / raw)
To: khilman-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-lFZ/pmaqli7XmaaqVzeoHQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
vaibhav.bedia-l0cyMroinI0, sudhakar.raj-l0cyMroinI0,
gururaja.hebbar-l0cyMroinI0, Tony Lindgren, Wolfram Sang,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
Amend the I2C omap pin controller to optionally take a pin control
handle and set the state of the pins to:
- "default" on boot, resume and before performing an i2c transfer
- "idle" after initial default, after resume default, and after each
i2c xfer
- "sleep" on suspend()
By optionally putting the pins into sleep state in the suspend callback
we can accomplish two things.
- One is to minimize current leakage from pins and thus save power,
- second, we can prevent the IP from driving pins output in an
uncontrolled manner, which may happen if the power domain drops the
domain regulator.
Note:
A .suspend & .resume callback is added which simply puts the pins to sleep
state upon suspend & are moved to default & idle state upon resume.
If any of the above pin states are missing in dt, a warning message
about the missing state is displayed.
If certain pin-states are not available, to remove this warning message
pass respective state name with null phandler.
(Changes based on i2c-nomadik.c)
Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
:100644 100644 e02f9e3... 588ba28... M drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-omap.c | 112 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 105 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e02f9e3..588ba28 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -214,7 +214,11 @@ struct omap_i2c_dev {
u16 westate;
u16 errata;
- struct pinctrl *pins;
+ /* Three pin states - default, idle & sleep */
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default;
+ struct pinctrl_state *pins_idle;
+ struct pinctrl_state *pins_sleep;
};
static const u8 reg_map_ip_v1[] = {
@@ -641,6 +645,11 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (IS_ERR_VALUE(r))
goto out;
+ /* Optionaly enable pins to be muxed in and configured */
+ if (!IS_ERR(dev->pins_default))
+ if (pinctrl_select_state(dev->pinctrl, dev->pins_default))
+ dev_err(dev->dev, "could not set default pins\n");
+
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
goto out;
@@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
out:
pm_runtime_mark_last_busy(dev->dev);
+
pm_runtime_put_autosuspend(dev->dev);
+ /* Optionally let pins go into idle state */
+ if (!IS_ERR(dev->pins_idle))
+ if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
+ dev_err(dev->dev, "could not set pins to idle state\n");
+
return r;
}
@@ -1123,14 +1138,47 @@ omap_i2c_probe(struct platform_device *pdev)
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
}
- dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
- if (IS_ERR(dev->pins)) {
- if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
+ dev->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!IS_ERR(dev->pinctrl)) {
+ dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ if (IS_ERR(dev->pins_default))
+ dev_dbg(&pdev->dev, "could not get default pinstate\n");
+ else
+ if (pinctrl_select_state(dev->pinctrl,
+ dev->pins_default))
+ dev_err(&pdev->dev,
+ "could not set default pinstate\n");
+
+ dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
+ PINCTRL_STATE_IDLE);
+ if (IS_ERR(dev->pins_idle))
+ dev_dbg(&pdev->dev, "could not get idle pinstate\n");
+ else
+ /* If possible, let's idle until the first transfer */
+ if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
+ dev_err(&pdev->dev,
+ "could not set idle pinstate\n");
+
+ dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
+ PINCTRL_STATE_SLEEP);
+ if (IS_ERR(dev->pins_sleep))
+ dev_dbg(&pdev->dev, "could not get sleep pinstate\n");
+ } else {
+ if (PTR_ERR(dev->pinctrl) == -EPROBE_DEFER)
return -EPROBE_DEFER;
- dev_warn(&pdev->dev, "did not get pins for i2c error: %li\n",
- PTR_ERR(dev->pins));
- dev->pins = NULL;
+ /*
+ * Since we continue even when pinctrl node is not found,
+ * Invalidate pins as not available. This is to make sure that
+ * IS_ERR(pins_xxx) results in failure when used.
+ */
+ dev->pins_default = ERR_PTR(-ENODATA);
+ dev->pins_idle = ERR_PTR(-ENODATA);
+ dev->pins_sleep = ERR_PTR(-ENODATA);
+
+ dev_dbg(&pdev->dev, "did not get pins for i2c error: %li\n",
+ PTR_ERR(dev->pinctrl));
}
dev->dev = &pdev->dev;
@@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
}
+ if (!IS_ERR(_dev->pins_idle))
+ if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
+ dev_err(dev, "could not set pins to idle state\n");
+
return 0;
}
@@ -1311,13 +1363,59 @@ static int omap_i2c_runtime_resume(struct device *dev)
if (!_dev->regs)
return 0;
+ /* Optionally place the pins to the default state */
+ if (!IS_ERR(_dev->pins_default))
+ if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
+ dev_err(dev, "could not set pins to default state\n");
+
__omap_i2c_init(_dev);
return 0;
}
#endif /* CONFIG_PM_RUNTIME */
+#ifdef CONFIG_PM_SLEEP
+static int omap_i2c_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+
+ pm_runtime_get_sync(dev);
+ if (omap_i2c_wait_for_bb(_dev) < 0) {
+ pm_runtime_put_sync(dev);
+ return -EBUSY;
+ }
+ pm_runtime_put_sync(dev);
+
+ if (!IS_ERR(_dev->pins_sleep))
+ if (pinctrl_select_state(_dev->pinctrl, _dev->pins_sleep))
+ dev_err(dev, "could not set pins to sleep state\n");
+
+ return 0;
+}
+
+static int omap_i2c_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+
+ /* First go to the default state */
+ if (!IS_ERR(_dev->pins_default))
+ if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
+ dev_err(dev, "could not set pins to default state\n");
+
+ /* Then let's idle the pins until the next transfer happens */
+ if (!IS_ERR(_dev->pins_idle))
+ if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
+ dev_err(dev, "could not set pins to idle state\n");
+
+ return 0;
+}
+#endif
+
+
static struct dev_pm_ops omap_i2c_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
omap_i2c_runtime_resume, NULL)
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <1369995191-20855-12-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
@ 2013-05-31 14:55 ` Grygorii Strashko
[not found] ` <51A8B9EA.6030604-l0cyMroinI0@public.gmane.org>
2013-05-31 18:07 ` Kevin Hilman
1 sibling, 1 reply; 16+ messages in thread
From: Grygorii Strashko @ 2013-05-31 14:55 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: khilman-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-lFZ/pmaqli7XmaaqVzeoHQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
vaibhav.bedia-l0cyMroinI0, sudhakar.raj-l0cyMroinI0,
Tony Lindgren, Wolfram Sang, linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
On 05/31/2013 01:13 PM, Hebbar Gururaja wrote:
> Amend the I2C omap pin controller to optionally take a pin control
> handle and set the state of the pins to:
>
> - "default" on boot, resume and before performing an i2c transfer
> - "idle" after initial default, after resume default, and after each
> i2c xfer
> - "sleep" on suspend()
>
> By optionally putting the pins into sleep state in the suspend callback
> we can accomplish two things.
> - One is to minimize current leakage from pins and thus save power,
> - second, we can prevent the IP from driving pins output in an
> uncontrolled manner, which may happen if the power domain drops the
> domain regulator.
>
> Note:
> A .suspend & .resume callback is added which simply puts the pins to sleep
> state upon suspend & are moved to default & idle state upon resume.
>
> If any of the above pin states are missing in dt, a warning message
> about the missing state is displayed.
> If certain pin-states are not available, to remove this warning message
> pass respective state name with null phandler.
>
> (Changes based on i2c-nomadik.c)
>
> Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
> Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
> :100644 100644 e02f9e3... 588ba28... M drivers/i2c/busses/i2c-omap.c
> drivers/i2c/busses/i2c-omap.c | 112 ++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 105 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index e02f9e3..588ba28 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -214,7 +214,11 @@ struct omap_i2c_dev {
> u16 westate;
> u16 errata;
>
> - struct pinctrl *pins;
> + /* Three pin states - default, idle & sleep */
> + struct pinctrl *pinctrl;
> + struct pinctrl_state *pins_default;
> + struct pinctrl_state *pins_idle;
> + struct pinctrl_state *pins_sleep;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -641,6 +645,11 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> if (IS_ERR_VALUE(r))
> goto out;
>
The current HWMOD framework configures PINs to enable state before
enabling the device and
switch PINs to idle state after disabling the device. Why here its done
in different order?
> + /* Optionaly enable pins to be muxed in and configured */
> + if (!IS_ERR(dev->pins_default))
> + if (pinctrl_select_state(dev->pinctrl, dev->pins_default))
> + dev_err(dev->dev, "could not set default pins\n");
> +
> r = omap_i2c_wait_for_bb(dev);
> if (r < 0)
> goto out;
> @@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>
> out:
> pm_runtime_mark_last_busy(dev->dev);
> +
> pm_runtime_put_autosuspend(dev->dev);
> + /* Optionally let pins go into idle state */
> + if (!IS_ERR(dev->pins_idle))
> + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> + dev_err(dev->dev, "could not set pins to idle state\n");
> +
> return r;
> }
>
> @@ -1123,14 +1138,47 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> }
>
> - dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
> - if (IS_ERR(dev->pins)) {
> - if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
> + dev->pinctrl = devm_pinctrl_get(&pdev->dev);
May be struct device ->pins->p can be used instead of dev->pinctrl?
> + if (!IS_ERR(dev->pinctrl)) {
> + dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
> + PINCTRL_STATE_DEFAULT);
> + if (IS_ERR(dev->pins_default))
> + dev_dbg(&pdev->dev, "could not get default pinstate\n");
> + else
> + if (pinctrl_select_state(dev->pinctrl,
> + dev->pins_default))
> + dev_err(&pdev->dev,
> + "could not set default pinstate\n");
Don't need to set Default pin state
Default pins state is applied by DD framework automatically before
device probing
and stored in struct device ->pins->default_state
> +
> + dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
> + PINCTRL_STATE_IDLE);
> + if (IS_ERR(dev->pins_idle))
> + dev_dbg(&pdev->dev, "could not get idle pinstate\n");
> + else
> + /* If possible, let's idle until the first transfer */
> + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> + dev_err(&pdev->dev,
> + "could not set idle pinstate\n");
> +
> + dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
> + PINCTRL_STATE_SLEEP);
> + if (IS_ERR(dev->pins_sleep))
> + dev_dbg(&pdev->dev, "could not get sleep pinstate\n");
> + } else {
> + if (PTR_ERR(dev->pinctrl) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
>
> - dev_warn(&pdev->dev, "did not get pins for i2c error: %li\n",
> - PTR_ERR(dev->pins));
> - dev->pins = NULL;
> + /*
> + * Since we continue even when pinctrl node is not found,
> + * Invalidate pins as not available. This is to make sure that
> + * IS_ERR(pins_xxx) results in failure when used.
> + */
> + dev->pins_default = ERR_PTR(-ENODATA);
> + dev->pins_idle = ERR_PTR(-ENODATA);
> + dev->pins_sleep = ERR_PTR(-ENODATA);
> +
> + dev_dbg(&pdev->dev, "did not get pins for i2c error: %li\n",
> + PTR_ERR(dev->pinctrl));
> }
>
> dev->dev = &pdev->dev;
> @@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
> omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
> }
>
> + if (!IS_ERR(_dev->pins_idle))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> + dev_err(dev, "could not set pins to idle state\n");
> +
It's done in omap_i2c_xfer
> return 0;
> }
>
> @@ -1311,13 +1363,59 @@ static int omap_i2c_runtime_resume(struct device *dev)
> if (!_dev->regs)
> return 0;
>
> + /* Optionally place the pins to the default state */
> + if (!IS_ERR(_dev->pins_default))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
> + dev_err(dev, "could not set pins to default state\n");
> +
It's done in omap_i2c_xfer
> __omap_i2c_init(_dev);
>
> return 0;
> }
> #endif /* CONFIG_PM_RUNTIME */
>
> +#ifdef CONFIG_PM_SLEEP
> +static int omap_i2c_suspend(struct device *dev)
Please, use .suspend_noirq() - it's possible that I2C will be used
even after "device suspend" stage especially on SMP platforms((( ),
but its prohibited to use it after "suspend_noirq" stage (
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> +
> + pm_runtime_get_sync(dev);
Here is the better way to detect late I2C activities during suspending:
i2c_lock_adapter(&_dev->adapter);
/* Check for active I2C transaction */
if (atomic_read(&dev->power.usage_count) > 1) {
dev_info(dev,
"active I2C transaction detected - suspend aborted\n");
return -EBUSY;
}
i2c_unlock_adapter(&_dev->adapter);
> + if (omap_i2c_wait_for_bb(_dev) < 0) {
> + pm_runtime_put_sync(dev);
> + return -EBUSY;
> + }
> + pm_runtime_put_sync(dev);
> +
> + if (!IS_ERR(_dev->pins_sleep))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_sleep))
> + dev_err(dev, "could not set pins to sleep state\n");
> +
> + return 0;
> +}
Not sure it's right - Lest assume suspend_noirq() is used here.
Then, at this point, OMAP device framework will disable device
(_od_suspend_noirq()).
But PINs will be switched to IDLE state before that. Is it ok?
Possibly Kevin could clarify this point?
> +
> +static int omap_i2c_resume(struct device *dev)
Please, use .resume_noirq()
> +{
The same is here - OMAP device framework will enable device
(_od_suspend_noirq()) here.
But PINs are still in IDLE state???
> + struct platform_device *pdev = to_platform_device(dev);
> + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> +
> + /* First go to the default state */
> + if (!IS_ERR(_dev->pins_default))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
> + dev_err(dev, "could not set pins to default state\n");
> +
> + /* Then let's idle the pins until the next transfer happens */
> + if (!IS_ERR(_dev->pins_idle))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> + dev_err(dev, "could not set pins to idle state\n");
> +
This is wrong - at this moment I2C device can be as in Enabled state
as in Disabled
> + return 0;
> +}
> +#endif
> +
> +
> static struct dev_pm_ops omap_i2c_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
> SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
> omap_i2c_runtime_resume, NULL)
> };
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 11/11] i2c: omap: enhance pinctrl support
2013-05-31 10:13 ` [PATCH 11/11] i2c: omap: " Hebbar Gururaja
[not found] ` <1369995191-20855-12-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
@ 2013-05-31 17:34 ` Kevin Hilman
[not found] ` <87k3mf2gu4.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
1 sibling, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2013-05-31 17:34 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: grant.likely, linus.walleij, rob.herring,
davinci-linux-open-source, devicetree-discuss, linux-arm-kernel,
linux, linux-kernel, vaibhav.bedia, sudhakar.raj, Tony Lindgren,
Wolfram Sang, linux-omap, linux-i2c
Hebbar Gururaja <gururaja.hebbar@ti.com> writes:
> Amend the I2C omap pin controller to optionally take a pin control
> handle and set the state of the pins to:
>
> - "default" on boot, resume and before performing an i2c transfer
> - "idle" after initial default, after resume default, and after each
> i2c xfer
> - "sleep" on suspend()
>
> By optionally putting the pins into sleep state in the suspend callback
> we can accomplish two things.
> - One is to minimize current leakage from pins and thus save power,
> - second, we can prevent the IP from driving pins output in an
> uncontrolled manner, which may happen if the power domain drops the
> domain regulator.
>
> Note:
> A .suspend & .resume callback is added which simply puts the pins to sleep
> state upon suspend & are moved to default & idle state upon resume.
>
> If any of the above pin states are missing in dt, a warning message
> about the missing state is displayed.
> If certain pin-states are not available, to remove this warning message
> pass respective state name with null phandler.
>
> (Changes based on i2c-nomadik.c)
>
> Signed-off-by: Hebbar Gururaja <gururaja.hebbar@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: linux-omap@vger.kernel.org
> Cc: linux-i2c@vger.kernel.org
[...]
> @@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>
> out:
> pm_runtime_mark_last_busy(dev->dev);
> +
> pm_runtime_put_autosuspend(dev->dev);
> + /* Optionally let pins go into idle state */
> + if (!IS_ERR(dev->pins_idle))
> + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> + dev_err(dev->dev, "could not set pins to idle state\n");
This is wrong. You're changing the muxing before the device actually
goes idle. Anything you want to happen when the device actually idles
for real has to be in runtime PM callbacks.
Looking below, I see it's already in the callbacks, so why is it here also?
[...]
> @@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
> omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
> }
>
> + if (!IS_ERR(_dev->pins_idle))
> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> + dev_err(dev, "could not set pins to idle state\n");
> +
> return 0;
> }
>
Kevin
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <1369995191-20855-12-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 14:55 ` Grygorii Strashko
@ 2013-05-31 18:07 ` Kevin Hilman
2013-06-04 7:23 ` Linus Walleij
[not found] ` <87bo7r10s9.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
1 sibling, 2 replies; 16+ messages in thread
From: Kevin Hilman @ 2013-05-31 18:07 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-lFZ/pmaqli7XmaaqVzeoHQ, Wolfram Sang, Tony Lindgren,
Linus Walleij, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
+Linus Walleij (pinctrl maintainer)
Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org> writes:
> Amend the I2C omap pin controller to optionally take a pin control
> handle and set the state of the pins to:
>
> - "default" on boot, resume and before performing an i2c transfer
> - "idle" after initial default, after resume default, and after each
> i2c xfer
> - "sleep" on suspend()
>
> By optionally putting the pins into sleep state in the suspend callback
> we can accomplish two things.
> - One is to minimize current leakage from pins and thus save power,
> - second, we can prevent the IP from driving pins output in an
> uncontrolled manner, which may happen if the power domain drops the
> domain regulator.
>
> Note:
> A .suspend & .resume callback is added which simply puts the pins to sleep
> state upon suspend & are moved to default & idle state upon resume.
>
> If any of the above pin states are missing in dt, a warning message
> about the missing state is displayed.
> If certain pin-states are not available, to remove this warning message
> pass respective state name with null phandler.
>
> (Changes based on i2c-nomadik.c)
>
> Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
> Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
[...]
> @@ -1123,14 +1138,47 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> }
>
> - dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
> - if (IS_ERR(dev->pins)) {
> - if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
> + dev->pinctrl = devm_pinctrl_get(&pdev->dev);
> + if (!IS_ERR(dev->pinctrl)) {
> + dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
> + PINCTRL_STATE_DEFAULT);
This part is already done by probe in driver core, why does it need to
be done again. dev->pins->default_state should already have this.
(c.f. pinctrl_bind_pins() in drivers/base/pinctrl.c)
But that brings up a bigger question about whether or not we should be
doing the rest of this (idle/sleep) pin management in the drivers or in
the driver core as well. I would much prefer it be handled by the
driver core.
In fact, since these are all PM related events, it should probably be
handled by the PM core and seems pretty straight forward to do so.
Kevin
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
2013-05-31 10:13 ` [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support Hebbar Gururaja
@ 2013-06-04 7:11 ` Linus Walleij
2013-06-04 7:19 ` Linus Walleij
[not found] ` <1369995191-20855-10-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
1 sibling, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2013-06-04 7:11 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: Kevin Hilman, Grant Likely, Rob Herring,
davinci-linux-open-source@linux.davincidsp.com,
devicetree-discuss@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org, Russell King - ARM Linux,
linux-kernel@vger.kernel.org, Vaibhav Bedia, sudhakar.raj,
Balaji T K, Chris Ball, linux-mmc@vger.kernel.org, Linux-OMAP
On Fri, May 31, 2013 at 12:13 PM, Hebbar Gururaja
<gururaja.hebbar@ti.com> wrote:
> Amend the hsmmc controller to optionally take a pin control handle and
> set the state of the pins to:
>
> - "default" on boot, resume and before performing a mmc transfer
> - "idle" after initial default, after resume default, and after each
> mmc/sd card access
> - "sleep" on suspend()
>
> By optionally putting the pins into sleep state in the suspend callback
> we can accomplish two things.
> - One is to minimize current leakage from pins and thus save power,
> - second, we can prevent the IP from driving pins output in an
> uncontrolled manner, which may happen if the power domain drops the
> domain regulator.
>
> If any of the above pin states are missing in dt, a warning message
> about the missing state is displayed.
> If certain pin-states are not available, to remove this warning message
> pass respective state name with null phandler.
>
> Signed-off-by: Hebbar Gururaja <gururaja.hebbar@ti.com>
> Cc: Balaji T K <balajitk@ti.com>
> Cc: Chris Ball <cjb@laptop.org>
> Cc: linux-mmc@vger.kernel.org
> Cc: linux-omap@vger.kernel.org
This is perfectly correct.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
As the PM code seems to be similar across platforms I have had
loose plans to move this to the device core as well, but right now
I'm too busy with other things, and it can surely be refactored later.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
2013-06-04 7:11 ` Linus Walleij
@ 2013-06-04 7:19 ` Linus Walleij
[not found] ` <CACRpkdYeh6UXnbUXiiZLPP+FUz11HKaD-FrHHaqUGX8AmA_p6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2013-06-04 7:19 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: Kevin Hilman, Grant Likely, Rob Herring,
davinci-linux-open-source@linux.davincidsp.com,
devicetree-discuss@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org, Russell King - ARM Linux,
linux-kernel@vger.kernel.org, Vaibhav Bedia, sudhakar.raj,
Balaji T K, Chris Ball, linux-mmc@vger.kernel.org, Linux-OMAP
On Tue, Jun 4, 2013 at 9:11 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Fri, May 31, 2013 at 12:13 PM, Hebbar Gururaja
> <gururaja.hebbar@ti.com> wrote:
>
>> Amend the hsmmc controller to optionally take a pin control handle and
>> set the state of the pins to:
>>
>> - "default" on boot, resume and before performing a mmc transfer
>> - "idle" after initial default, after resume default, and after each
>> mmc/sd card access
>> - "sleep" on suspend()
>>
>> By optionally putting the pins into sleep state in the suspend callback
>> we can accomplish two things.
>> - One is to minimize current leakage from pins and thus save power,
>> - second, we can prevent the IP from driving pins output in an
>> uncontrolled manner, which may happen if the power domain drops the
>> domain regulator.
>>
>> If any of the above pin states are missing in dt, a warning message
>> about the missing state is displayed.
>> If certain pin-states are not available, to remove this warning message
>> pass respective state name with null phandler.
>>
>> Signed-off-by: Hebbar Gururaja <gururaja.hebbar@ti.com>
>> Cc: Balaji T K <balajitk@ti.com>
>> Cc: Chris Ball <cjb@laptop.org>
>> Cc: linux-mmc@vger.kernel.org
>> Cc: linux-omap@vger.kernel.org
>
> This is perfectly correct.
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
So please consider my other option given in patch 2 instead.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 11/11] i2c: omap: enhance pinctrl support
2013-05-31 18:07 ` Kevin Hilman
@ 2013-06-04 7:23 ` Linus Walleij
[not found] ` <87bo7r10s9.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
1 sibling, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2013-06-04 7:23 UTC (permalink / raw)
To: Kevin Hilman
Cc: Hebbar Gururaja, Grant Likely, Rob Herring,
davinci-linux-open-source@linux.davincidsp.com,
devicetree-discuss@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org, Russell King - ARM Linux,
linux-kernel@vger.kernel.org, Vaibhav Bedia, sudhakar.raj,
Tony Lindgren, Wolfram Sang, Linux-OMAP,
linux-i2c@vger.kernel.org
On Fri, May 31, 2013 at 8:07 PM, Kevin Hilman <khilman@linaro.org> wrote:
> But that brings up a bigger question about whether or not we should be
> doing the rest of this (idle/sleep) pin management in the drivers or in
> the driver core as well. I would much prefer it be handled by the
> driver core.
Yes. See my suggestion in 2/11.
> In fact, since these are all PM related events, it should probably be
> handled by the PM core and seems pretty straight forward to do so.
I can see a clean interface with three simple functions toward
<pinctrl/consumer.h> for switching between the default, idle and
sleep states, but you may see even further...
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <87bo7r10s9.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2013-06-04 9:50 ` Hebbar, Gururaja
0 siblings, 0 replies; 16+ messages in thread
From: Hebbar, Gururaja @ 2013-06-04 9:50 UTC (permalink / raw)
To: Kevin Hilman
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org, Wolfram Sang,
Tony Lindgren, Linus Walleij,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
On Fri, May 31, 2013 at 23:37:02, Kevin Hilman wrote:
> +Linus Walleij (pinctrl maintainer)
>
> Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org> writes:
>
> > Amend the I2C omap pin controller to optionally take a pin control
> > handle and set the state of the pins to:
> >
> > - "default" on boot, resume and before performing an i2c transfer
> > - "idle" after initial default, after resume default, and after each
> > i2c xfer
> > - "sleep" on suspend()
> >
> > By optionally putting the pins into sleep state in the suspend callback
> > we can accomplish two things.
> > - One is to minimize current leakage from pins and thus save power,
> > - second, we can prevent the IP from driving pins output in an
> > uncontrolled manner, which may happen if the power domain drops the
> > domain regulator.
> >
> > Note:
> > A .suspend & .resume callback is added which simply puts the pins to sleep
> > state upon suspend & are moved to default & idle state upon resume.
> >
> > If any of the above pin states are missing in dt, a warning message
> > about the missing state is displayed.
> > If certain pin-states are not available, to remove this warning message
> > pass respective state name with null phandler.
> >
> > (Changes based on i2c-nomadik.c)
> >
> > Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> > Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> > Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
> > Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> [...]
>
> > @@ -1123,14 +1138,47 @@ omap_i2c_probe(struct platform_device *pdev)
> > dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> > }
> >
> > - dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
> > - if (IS_ERR(dev->pins)) {
> > - if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
> > + dev->pinctrl = devm_pinctrl_get(&pdev->dev);
> > + if (!IS_ERR(dev->pinctrl)) {
> > + dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
> > + PINCTRL_STATE_DEFAULT);
>
> This part is already done by probe in driver core, why does it need to
> be done again. dev->pins->default_state should already have this.
> (c.f. pinctrl_bind_pins() in drivers/base/pinctrl.c)
>
> But that brings up a bigger question about whether or not we should be
> doing the rest of this (idle/sleep) pin management in the drivers or in
> the driver core as well. I would much prefer it be handled by the
> driver core.
>
> In fact, since these are all PM related events, it should probably be
> handled by the PM core and seems pretty straight forward to do so.
Let me pull out some info about these and come back
>
> Kevin
>
Regards,
Gururaja
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
[not found] ` <CACRpkdYeh6UXnbUXiiZLPP+FUz11HKaD-FrHHaqUGX8AmA_p6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-06-04 9:52 ` Hebbar, Gururaja
0 siblings, 0 replies; 16+ messages in thread
From: Hebbar, Gururaja @ 2013-06-04 9:52 UTC (permalink / raw)
To: Linus Walleij
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
Russell King - ARM Linux, Krishnamoorthy, Balaji T,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Linux-OMAP, Grant Likely, Chris Ball,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Tue, Jun 04, 2013 at 12:49:57, Linus Walleij wrote:
> On Tue, Jun 4, 2013 at 9:11 AM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> > On Fri, May 31, 2013 at 12:13 PM, Hebbar Gururaja
> > <gururaja.hebbar-l0cyMroinI0@public.gmane.org> wrote:
> >
> >> Amend the hsmmc controller to optionally take a pin control handle and
> >> set the state of the pins to:
> >>
> >> - "default" on boot, resume and before performing a mmc transfer
> >> - "idle" after initial default, after resume default, and after each
> >> mmc/sd card access
> >> - "sleep" on suspend()
> >>
> >> By optionally putting the pins into sleep state in the suspend callback
> >> we can accomplish two things.
> >> - One is to minimize current leakage from pins and thus save power,
> >> - second, we can prevent the IP from driving pins output in an
> >> uncontrolled manner, which may happen if the power domain drops the
> >> domain regulator.
> >>
> >> If any of the above pin states are missing in dt, a warning message
> >> about the missing state is displayed.
> >> If certain pin-states are not available, to remove this warning message
> >> pass respective state name with null phandler.
> >>
> >> Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> >> Cc: Balaji T K <balajitk-l0cyMroinI0@public.gmane.org>
> >> Cc: Chris Ball <cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org>
> >> Cc: linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >> Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >
> > This is perfectly correct.
> > Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> So please consider my other option given in patch 2 instead.
I will check how I can be a part of this implementation
>
> Yours,
> Linus Walleij
>
Regards,
Gururaja
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <87k3mf2gu4.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2013-06-04 11:39 ` Grygorii Strashko
2013-06-05 9:05 ` Hebbar, Gururaja
1 sibling, 0 replies; 16+ messages in thread
From: Grygorii Strashko @ 2013-06-04 11:39 UTC (permalink / raw)
To: Kevin Hilman
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
linux-lFZ/pmaqli7XmaaqVzeoHQ, Wolfram Sang, Tony Lindgren,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA
Hi Kevin, Gururaja
On 05/31/2013 08:34 PM, Kevin Hilman wrote:
> Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org> writes:
>
>> Amend the I2C omap pin controller to optionally take a pin control
>> handle and set the state of the pins to:
>>
>> - "default" on boot, resume and before performing an i2c transfer
>> - "idle" after initial default, after resume default, and after each
>> i2c xfer
>> - "sleep" on suspend()
>>
>> By optionally putting the pins into sleep state in the suspend callback
>> we can accomplish two things.
>> - One is to minimize current leakage from pins and thus save power,
>> - second, we can prevent the IP from driving pins output in an
>> uncontrolled manner, which may happen if the power domain drops the
>> domain regulator.
>>
>> Note:
>> A .suspend & .resume callback is added which simply puts the pins to sleep
>> state upon suspend & are moved to default & idle state upon resume.
>>
>> If any of the above pin states are missing in dt, a warning message
>> about the missing state is displayed.
>> If certain pin-states are not available, to remove this warning message
>> pass respective state name with null phandler.
>>
>> (Changes based on i2c-nomadik.c)
>>
>> Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
>> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>> Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
>> Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> [...]
>
>> @@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>>
>> out:
>> pm_runtime_mark_last_busy(dev->dev);
>> +
>> pm_runtime_put_autosuspend(dev->dev);
>> + /* Optionally let pins go into idle state */
>> + if (!IS_ERR(dev->pins_idle))
>> + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
>> + dev_err(dev->dev, "could not set pins to idle state\n");
> This is wrong. You're changing the muxing before the device actually
> goes idle. Anything you want to happen when the device actually idles
> for real has to be in runtime PM callbacks.
>
> Looking below, I see it's already in the callbacks, so why is it here also?
I have two questions regarding this patch & the whole series:
1) PM runtime suspend/resume
Current sequence:
- resume
|- omap_hwmod_enable()
|- _enable()
|- omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED)
|- enable module (sysc&clocks)
|- omap_i2c_runtime_resume()
- suspend
|- omap_i2c_runtime_suspend()
|- omap_hwmod_idle()
|- _idle()
|- disbale module (sysc&clocks)
|- omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
The new order will change this sequence - *Is it safe?*:
- resume
|- omap_hwmod_enable()
|- _enable()
|- enable module (sysc&clocks) <---- Is it valid to enable
module before PINs?
|- omap_i2c_runtime_resume()
|- PINs state set to DEFAULT
- suspend
|- omap_i2c_runtime_suspend()
|- PINs state set to IDLE
|- omap_hwmod_idle()
|- _idle()
|- disbale module (sysc&clocks) <---- Is it valid to disable
module after PINs?
2) System suspend (OFF-mode) with assumption that "noirq" stage will be
used for PINs cfg
Current implementation: handled in the same way as PM runtime
The new implementation: -- total mess is here((:
- suspend_noirq - I2C device can be still active because of PM auto-suspend
|-_od_suspend_noirq
|- omap_i2c_suspend_noirq
|- PINs state set to SLEEP
|- pm_generic_runtime_suspend
|- omap_i2c_runtime_suspend()
|- PINs state set to IDLE <--- *oops* PINs state is IDLE and
not SLEEP
|- omap_device_idle()
|- omap_hwmod_idle()
|- _idle()
|- disbale module (sysc&clocks)
- resume_noirq - I2C was active before suspend
|-_od_resume_noirq
|- omap_hwmod_enable()
|- _enable()
|- enable module (sysc&clocks)
|- pm_generic_runtime_resume
|- omap_i2c_runtime_resume()
|- PINs state set to DEFAULT <--- !!!!
|- omap_i2c_resume_noirq
|- PINs state set to DEFAULT
|- PINs state set to IDLE <--- *big oops* we have active
module and its
PINs state is IDLE
All mentioned above, applicable for most of all patches in series.
And It seems, that this functionality can't be implemented in such way (
- OMAP device FW and Driver core might handle PINs states changing and
drivers (DT) should provide set of available states only.
Am I wrong?
Regards,
-grygorii
>
> [...]
>
>> @@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
>> omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
>> }
>>
>> + if (!IS_ERR(_dev->pins_idle))
>> + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
>> + dev_err(dev, "could not set pins to idle state\n");
>> +
>> return 0;
>> }
>>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
[not found] ` <1369995191-20855-10-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
@ 2013-06-04 14:46 ` Tony Lindgren
2013-06-07 13:36 ` Balaji T K
0 siblings, 1 reply; 16+ messages in thread
From: Tony Lindgren @ 2013-06-04 14:46 UTC (permalink / raw)
To: Hebbar Gururaja
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khilman-QSEj5FYQhm4dnm+yROfE0A, linux-lFZ/pmaqli7XmaaqVzeoHQ,
Balaji T K, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, Chris Ball,
sudhakar.raj-l0cyMroinI0, vaibhav.bedia-l0cyMroinI0,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
* Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org> [130531 03:19]:
> Amend the hsmmc controller to optionally take a pin control handle and
> set the state of the pins to:
>
> - "default" on boot, resume and before performing a mmc transfer
> - "idle" after initial default, after resume default, and after each
> mmc/sd card access
> - "sleep" on suspend()
>
> By optionally putting the pins into sleep state in the suspend callback
> we can accomplish two things.
> - One is to minimize current leakage from pins and thus save power,
> - second, we can prevent the IP from driving pins output in an
> uncontrolled manner, which may happen if the power domain drops the
> domain regulator.
>
> If any of the above pin states are missing in dt, a warning message
> about the missing state is displayed.
> If certain pin-states are not available, to remove this warning message
> pass respective state name with null phandler.
There's a similar patch in the "[RESEND PATCH v2 1/3] mmc: omap_hsmmc:
Enable SDIO IRQ using a GPIO in idle mode" thread. It also makes the
SDIO interrupts to work, so we need to consider that too.
We can merge the dynamic pinmuxing parts separately, but they should
be in a separate function like I posted later on in the thread above.
Regards,
Tony
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <51A8B9EA.6030604-l0cyMroinI0@public.gmane.org>
@ 2013-06-05 9:04 ` Hebbar, Gururaja
0 siblings, 0 replies; 16+ messages in thread
From: Hebbar, Gururaja @ 2013-06-05 9:04 UTC (permalink / raw)
To: Strashko, Grygorii
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org, Wolfram Sang,
Tony Lindgren,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
On Fri, May 31, 2013 at 20:25:38, Strashko, Grygorii wrote:
> On 05/31/2013 01:13 PM, Hebbar Gururaja wrote:
> > Amend the I2C omap pin controller to optionally take a pin control
> > handle and set the state of the pins to:
> >
> > - "default" on boot, resume and before performing an i2c transfer
> > - "idle" after initial default, after resume default, and after each
> > i2c xfer
> > - "sleep" on suspend()
> >
> > By optionally putting the pins into sleep state in the suspend callback
> > we can accomplish two things.
> > - One is to minimize current leakage from pins and thus save power,
> > - second, we can prevent the IP from driving pins output in an
> > uncontrolled manner, which may happen if the power domain drops the
> > domain regulator.
> >
> > Note:
> > A .suspend & .resume callback is added which simply puts the pins to sleep
> > state upon suspend & are moved to default & idle state upon resume.
> >
> > If any of the above pin states are missing in dt, a warning message
> > about the missing state is displayed.
> > If certain pin-states are not available, to remove this warning message
> > pass respective state name with null phandler.
> >
> > (Changes based on i2c-nomadik.c)
> >
> > Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> > Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> > Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
> > Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > ---
> > :100644 100644 e02f9e3... 588ba28... M drivers/i2c/busses/i2c-omap.c
> > drivers/i2c/busses/i2c-omap.c | 112 ++++++++++++++++++++++++++++++++++++++---
> > 1 file changed, 105 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> > index e02f9e3..588ba28 100644
> > --- a/drivers/i2c/busses/i2c-omap.c
> > +++ b/drivers/i2c/busses/i2c-omap.c
> > @@ -214,7 +214,11 @@ struct omap_i2c_dev {
> > u16 westate;
> > u16 errata;
> >
> > - struct pinctrl *pins;
> > + /* Three pin states - default, idle & sleep */
> > + struct pinctrl *pinctrl;
> > + struct pinctrl_state *pins_default;
> > + struct pinctrl_state *pins_idle;
> > + struct pinctrl_state *pins_sleep;
> > };
> >
> > static const u8 reg_map_ip_v1[] = {
> > @@ -641,6 +645,11 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> > if (IS_ERR_VALUE(r))
> > goto out;
> >
> The current HWMOD framework configures PINs to enable state before
> enabling the device and
> switch PINs to idle state after disabling the device. Why here its done
> in different order?
AFAIK, in case of DT boot, "oh->mux" will be NULL. So hwmod will not change
Any pins.
> > + /* Optionaly enable pins to be muxed in and configured */
> > + if (!IS_ERR(dev->pins_default))
> > + if (pinctrl_select_state(dev->pinctrl, dev->pins_default))
> > + dev_err(dev->dev, "could not set default pins\n");
> > +
> > r = omap_i2c_wait_for_bb(dev);
> > if (r < 0)
> > goto out;
> > @@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> >
> > out:
> > pm_runtime_mark_last_busy(dev->dev);
> > +
> > pm_runtime_put_autosuspend(dev->dev);
> > + /* Optionally let pins go into idle state */
> > + if (!IS_ERR(dev->pins_idle))
> > + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> > + dev_err(dev->dev, "could not set pins to idle state\n");
> > +
> > return r;
> > }
> >
> > @@ -1123,14 +1138,47 @@ omap_i2c_probe(struct platform_device *pdev)
> > dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> > }
> >
> > - dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
> > - if (IS_ERR(dev->pins)) {
> > - if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
> > + dev->pinctrl = devm_pinctrl_get(&pdev->dev);
> May be struct device ->pins->p can be used instead of dev->pinctrl?
> > + if (!IS_ERR(dev->pinctrl)) {
> > + dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
> > + PINCTRL_STATE_DEFAULT);
> > + if (IS_ERR(dev->pins_default))
> > + dev_dbg(&pdev->dev, "could not get default pinstate\n");
> > + else
> > + if (pinctrl_select_state(dev->pinctrl,
> > + dev->pins_default))
> > + dev_err(&pdev->dev,
> > + "could not set default pinstate\n");
> Don't need to set Default pin state
> Default pins state is applied by DD framework automatically before
> device probing
> and stored in struct device ->pins->default_state
Correct.
> > +
> > + dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
> > + PINCTRL_STATE_IDLE);
> > + if (IS_ERR(dev->pins_idle))
> > + dev_dbg(&pdev->dev, "could not get idle pinstate\n");
> > + else
> > + /* If possible, let's idle until the first transfer */
> > + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> > + dev_err(&pdev->dev,
> > + "could not set idle pinstate\n");
> > +
> > + dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
> > + PINCTRL_STATE_SLEEP);
> > + if (IS_ERR(dev->pins_sleep))
> > + dev_dbg(&pdev->dev, "could not get sleep pinstate\n");
> > + } else {
> > + if (PTR_ERR(dev->pinctrl) == -EPROBE_DEFER)
> > return -EPROBE_DEFER;
> >
> > - dev_warn(&pdev->dev, "did not get pins for i2c error: %li\n",
> > - PTR_ERR(dev->pins));
> > - dev->pins = NULL;
> > + /*
> > + * Since we continue even when pinctrl node is not found,
> > + * Invalidate pins as not available. This is to make sure that
> > + * IS_ERR(pins_xxx) results in failure when used.
> > + */
> > + dev->pins_default = ERR_PTR(-ENODATA);
> > + dev->pins_idle = ERR_PTR(-ENODATA);
> > + dev->pins_sleep = ERR_PTR(-ENODATA);
> > +
> > + dev_dbg(&pdev->dev, "did not get pins for i2c error: %li\n",
> > + PTR_ERR(dev->pinctrl));
> > }
> >
> > dev->dev = &pdev->dev;
> > @@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
> > omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
> > }
> >
> > + if (!IS_ERR(_dev->pins_idle))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> > + dev_err(dev, "could not set pins to idle state\n");
> > +
> It's done in omap_i2c_xfer
Correct.
> > return 0;
> > }
> >
> > @@ -1311,13 +1363,59 @@ static int omap_i2c_runtime_resume(struct device *dev)
> > if (!_dev->regs)
> > return 0;
> >
> > + /* Optionally place the pins to the default state */
> > + if (!IS_ERR(_dev->pins_default))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
> > + dev_err(dev, "could not set pins to default state\n");
> > +
> It's done in omap_i2c_xfer
Hmmm. What is not a single transaction has taken place. In that case
omap_i2c_xfer() would have not been called.
> > __omap_i2c_init(_dev);
> >
> > return 0;
> > }
> > #endif /* CONFIG_PM_RUNTIME */
> >
> > +#ifdef CONFIG_PM_SLEEP
> > +static int omap_i2c_suspend(struct device *dev)
> Please, use .suspend_noirq() - it's possible that I2C will be used
> even after "device suspend" stage especially on SMP platforms((( ),
> but its prohibited to use it after "suspend_noirq" stage (
Ok will check about those implementation.
> > +{
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> > +
> > + pm_runtime_get_sync(dev);
> Here is the better way to detect late I2C activities during suspending:
> i2c_lock_adapter(&_dev->adapter);
>
> /* Check for active I2C transaction */
> if (atomic_read(&dev->power.usage_count) > 1) {
> dev_info(dev,
> "active I2C transaction detected - suspend aborted\n");
> return -EBUSY;
> }
>
> i2c_unlock_adapter(&_dev->adapter);
Hmm. Correct.
> > + if (omap_i2c_wait_for_bb(_dev) < 0) {
> > + pm_runtime_put_sync(dev);
> > + return -EBUSY;
> > + }
> > + pm_runtime_put_sync(dev);
> > +
> > + if (!IS_ERR(_dev->pins_sleep))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_sleep))
> > + dev_err(dev, "could not set pins to sleep state\n");
> > +
> > + return 0;
> > +}
> Not sure it's right - Lest assume suspend_noirq() is used here.
> Then, at this point, OMAP device framework will disable device
> (_od_suspend_noirq()).
> But PINs will be switched to IDLE state before that. Is it ok?
> Possibly Kevin could clarify this point?
Seems he has a entirely different approach for this implementation.
> > +
> > +static int omap_i2c_resume(struct device *dev)
> Please, use .resume_noirq()
Ok.
> > +{
> The same is here - OMAP device framework will enable device
> (_od_suspend_noirq()) here.
> But PINs are still in IDLE state???
Needs to re-check. I will see how I can overcome this issue.
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> > +
> > + /* First go to the default state */
> > + if (!IS_ERR(_dev->pins_default))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_default))
> > + dev_err(dev, "could not set pins to default state\n");
> > +
> > + /* Then let's idle the pins until the next transfer happens */
> > + if (!IS_ERR(_dev->pins_idle))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> > + dev_err(dev, "could not set pins to idle state\n");
> > +
> This is wrong - at this moment I2C device can be as in Enabled state
> as in Disabled
As above. Needs to re-check. I will see how I can overcome this issue.
> > + return 0;
> > +}
> > +#endif
> > +
> > +
> > static struct dev_pm_ops omap_i2c_pm_ops = {
> > + SET_SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
> > SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
> > omap_i2c_runtime_resume, NULL)
> > };
>
>
Thanks for the thorough review.
Regards,
Gururaja
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH 11/11] i2c: omap: enhance pinctrl support
[not found] ` <87k3mf2gu4.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-06-04 11:39 ` Grygorii Strashko
@ 2013-06-05 9:05 ` Hebbar, Gururaja
1 sibling, 0 replies; 16+ messages in thread
From: Hebbar, Gururaja @ 2013-06-05 9:05 UTC (permalink / raw)
To: Kevin Hilman
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org, Wolfram Sang,
Tony Lindgren,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
On Fri, May 31, 2013 at 23:04:59, Kevin Hilman wrote:
> Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org> writes:
>
> > Amend the I2C omap pin controller to optionally take a pin control
> > handle and set the state of the pins to:
> >
> > - "default" on boot, resume and before performing an i2c transfer
> > - "idle" after initial default, after resume default, and after each
> > i2c xfer
> > - "sleep" on suspend()
> >
> > By optionally putting the pins into sleep state in the suspend callback
> > we can accomplish two things.
> > - One is to minimize current leakage from pins and thus save power,
> > - second, we can prevent the IP from driving pins output in an
> > uncontrolled manner, which may happen if the power domain drops the
> > domain regulator.
> >
> > Note:
> > A .suspend & .resume callback is added which simply puts the pins to sleep
> > state upon suspend & are moved to default & idle state upon resume.
> >
> > If any of the above pin states are missing in dt, a warning message
> > about the missing state is displayed.
> > If certain pin-states are not available, to remove this warning message
> > pass respective state name with null phandler.
> >
> > (Changes based on i2c-nomadik.c)
> >
> > Signed-off-by: Hebbar Gururaja <gururaja.hebbar-l0cyMroinI0@public.gmane.org>
> > Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> > Cc: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
> > Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> [...]
>
> > @@ -664,7 +673,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> >
> > out:
> > pm_runtime_mark_last_busy(dev->dev);
> > +
> > pm_runtime_put_autosuspend(dev->dev);
> > + /* Optionally let pins go into idle state */
> > + if (!IS_ERR(dev->pins_idle))
> > + if (pinctrl_select_state(dev->pinctrl, dev->pins_idle))
> > + dev_err(dev->dev, "could not set pins to idle state\n");
>
> This is wrong. You're changing the muxing before the device actually
> goes idle. Anything you want to happen when the device actually idles
> for real has to be in runtime PM callbacks.
>
> Looking below, I see it's already in the callbacks, so why is it here also?
Just to be double sure. Seems it is unwanted.
>
> [...]
>
> > @@ -1300,6 +1348,10 @@ static int omap_i2c_runtime_suspend(struct device *dev)
> > omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
> > }
> >
> > + if (!IS_ERR(_dev->pins_idle))
> > + if (pinctrl_select_state(_dev->pinctrl, _dev->pins_idle))
> > + dev_err(dev, "could not set pins to idle state\n");
> > +
> > return 0;
> > }
> >
>
> Kevin
>
Regards,
Gururaja
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
2013-06-04 14:46 ` Tony Lindgren
@ 2013-06-07 13:36 ` Balaji T K
2013-06-07 21:01 ` Tony Lindgren
0 siblings, 1 reply; 16+ messages in thread
From: Balaji T K @ 2013-06-07 13:36 UTC (permalink / raw)
To: Tony Lindgren
Cc: Hebbar Gururaja, khilman, linus.walleij, sudhakar.raj, linux-mmc,
linux-kernel, vaibhav.bedia, linux-omap, Chris Ball,
linux-arm-kernel
On Tuesday 04 June 2013 08:16 PM, Tony Lindgren wrote:
> * Hebbar Gururaja <gururaja.hebbar@ti.com> [130531 03:19]:
>> Amend the hsmmc controller to optionally take a pin control handle and
>> set the state of the pins to:
>>
>> - "default" on boot, resume and before performing a mmc transfer
>> - "idle" after initial default, after resume default, and after each
>> mmc/sd card access
>> - "sleep" on suspend()
>>
>> By optionally putting the pins into sleep state in the suspend callback
>> we can accomplish two things.
>> - One is to minimize current leakage from pins and thus save power,
>> - second, we can prevent the IP from driving pins output in an
>> uncontrolled manner, which may happen if the power domain drops the
>> domain regulator.
>>
>> If any of the above pin states are missing in dt, a warning message
>> about the missing state is displayed.
>> If certain pin-states are not available, to remove this warning message
>> pass respective state name with null phandler.
>
> There's a similar patch in the "[RESEND PATCH v2 1/3] mmc: omap_hsmmc:
> Enable SDIO IRQ using a GPIO in idle mode" thread. It also makes the
> SDIO interrupts to work, so we need to consider that too.
>
Hi Tony,
I will try to combine both of these and make use of
pinctrl_pm_select_[*]_state helper functions.
> We can merge the dynamic pinmuxing parts separately, but they should
> be in a separate function like I posted later on in the thread above.
>
> Regards,
>
> Tony
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support
2013-06-07 13:36 ` Balaji T K
@ 2013-06-07 21:01 ` Tony Lindgren
0 siblings, 0 replies; 16+ messages in thread
From: Tony Lindgren @ 2013-06-07 21:01 UTC (permalink / raw)
To: Balaji T K
Cc: Hebbar Gururaja, khilman, linus.walleij, sudhakar.raj, linux-mmc,
linux-kernel, vaibhav.bedia, linux-omap, Chris Ball,
linux-arm-kernel
* Balaji T K <balajitk@ti.com> [130607 06:42]:
> On Tuesday 04 June 2013 08:16 PM, Tony Lindgren wrote:
> >* Hebbar Gururaja <gururaja.hebbar@ti.com> [130531 03:19]:
> >>Amend the hsmmc controller to optionally take a pin control handle and
> >>set the state of the pins to:
> >>
> >>- "default" on boot, resume and before performing a mmc transfer
> >>- "idle" after initial default, after resume default, and after each
> >>mmc/sd card access
> >>- "sleep" on suspend()
> >>
> >>By optionally putting the pins into sleep state in the suspend callback
> >>we can accomplish two things.
> >>- One is to minimize current leakage from pins and thus save power,
> >>- second, we can prevent the IP from driving pins output in an
> >>uncontrolled manner, which may happen if the power domain drops the
> >>domain regulator.
> >>
> >>If any of the above pin states are missing in dt, a warning message
> >>about the missing state is displayed.
> >>If certain pin-states are not available, to remove this warning message
> >>pass respective state name with null phandler.
> >
> >There's a similar patch in the "[RESEND PATCH v2 1/3] mmc: omap_hsmmc:
> >Enable SDIO IRQ using a GPIO in idle mode" thread. It also makes the
> >SDIO interrupts to work, so we need to consider that too.
> >
>
> Hi Tony,
>
> I will try to combine both of these and make use of
> pinctrl_pm_select_[*]_state helper functions.
OK thanks, I'll separate out the pinctrl parts from Andreas' patch
and repost.
Regards,
Tony
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-06-07 21:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1369995191-20855-1-git-send-email-gururaja.hebbar@ti.com>
[not found] ` <1369995191-20855-1-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 10:13 ` [PATCH 09/11] mmc: omap_hsmmc: enhance pinctrl support Hebbar Gururaja
2013-06-04 7:11 ` Linus Walleij
2013-06-04 7:19 ` Linus Walleij
[not found] ` <CACRpkdYeh6UXnbUXiiZLPP+FUz11HKaD-FrHHaqUGX8AmA_p6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-06-04 9:52 ` Hebbar, Gururaja
[not found] ` <1369995191-20855-10-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-06-04 14:46 ` Tony Lindgren
2013-06-07 13:36 ` Balaji T K
2013-06-07 21:01 ` Tony Lindgren
2013-05-31 10:13 ` [PATCH 11/11] i2c: omap: " Hebbar Gururaja
[not found] ` <1369995191-20855-12-git-send-email-gururaja.hebbar-l0cyMroinI0@public.gmane.org>
2013-05-31 14:55 ` Grygorii Strashko
[not found] ` <51A8B9EA.6030604-l0cyMroinI0@public.gmane.org>
2013-06-05 9:04 ` Hebbar, Gururaja
2013-05-31 18:07 ` Kevin Hilman
2013-06-04 7:23 ` Linus Walleij
[not found] ` <87bo7r10s9.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-06-04 9:50 ` Hebbar, Gururaja
2013-05-31 17:34 ` Kevin Hilman
[not found] ` <87k3mf2gu4.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-06-04 11:39 ` Grygorii Strashko
2013-06-05 9:05 ` Hebbar, Gururaja
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).