From: Wolfram Sang <w.sang-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
To: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org,
swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org
Subject: Re: [PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
Date: Sat, 18 Aug 2012 14:47:03 +0200 [thread overview]
Message-ID: <20120818124703.GC12839@pengutronix.de> (raw)
In-Reply-To: <1345230155-4252-1-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 6057 bytes --]
On Sat, Aug 18, 2012 at 12:32:34AM +0530, Laxman Dewangan wrote:
> Tegra20 i2c controller does not support the continue transfer
> which implements the I2C_M_NOSTART functionality of i2c
> protocol mangling.
> Removing the I2C_M_NOSTART functionality for Tegra20.
>
> Signed-off-by: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> This is rebased on linux-next-20120816.
>
> drivers/i2c/busses/i2c-tegra.c | 73 +++++++++++++++++++++++++++++++--------
> 1 files changed, 58 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 7149625..554f713 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -27,6 +27,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-tegra.h>
> #include <linux/of_i2c.h>
> +#include <linux/of_device.h>
> #include <linux/module.h>
>
> #include <asm/unaligned.h>
> @@ -114,6 +115,15 @@ enum msg_end_type {
> };
>
> /**
> + * struct tegra_i2c_hw_feature : Different HW support on Tegra
> + * @has_continue_xfer_support: Continue transfer supports.
> + */
> +
> +struct tegra_i2c_hw_feature {
> + bool has_continue_xfer_support;
> +};
> +
> +/**
> * struct tegra_i2c_dev - per device i2c context
> * @dev: device reference for power management
> * @adapter: core i2c layer adapter information
> @@ -148,6 +158,7 @@ struct tegra_i2c_dev {
> int msg_read;
> unsigned long bus_clk_rate;
> bool is_suspended;
> + bool has_continue_xfer_support;
I wonder if it makes sense to carry a pointer here to the
tegra_i2c_hw_feature in use instead of copying all entries by hand,
since they might get more and more.
> };
>
> static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg)
> @@ -563,7 +574,17 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
> if (i2c_dev->is_suspended)
> return -EBUSY;
>
> - clk_prepare_enable(i2c_dev->div_clk);
> + /* Support I2C_M_NOSTART only if HW support continue xfer. */
> + for (i = 0; i < num - 1; i++) {
> + if ((msgs[i + 1].flags & I2C_M_NOSTART) &&
> + !i2c_dev->has_continue_xfer_support) {
> + dev_err(i2c_dev->dev,
> + "mesg %d have illegal flag\n", i + 1);
> + return -EINVAL;
> + }
> + }
Drivers are requested to explicitly check for features of the I2C bus
(like M_NOSTART) before using them, so I'd skip this extra check.
> +
> + clk_prepare_enable(i2c_dev->clk);
From a glimpse, this change looks unrelated at least. Even wrong, no?
> for (i = 0; i < num; i++) {
> enum msg_end_type end_type = MSG_END_STOP;
> if (i < (num - 1)) {
> @@ -582,8 +603,13 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
>
> static u32 tegra_i2c_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
> - I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
> + struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
> + u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
> + I2C_FUNC_PROTOCOL_MANGLING;
> +
> + if (i2c_dev->has_continue_xfer_support)
> + ret |= I2C_FUNC_NOSTART;
> + return ret;
> }
>
> static const struct i2c_algorithm tegra_i2c_algo = {
> @@ -591,6 +617,25 @@ static const struct i2c_algorithm tegra_i2c_algo = {
> .functionality = tegra_i2c_func,
> };
>
> +static struct tegra_i2c_hw_feature tegra20_i2c_hw = {
> + .has_continue_xfer_support = false,
> +};
> +
> +static struct tegra_i2c_hw_feature tegra30_i2c_hw = {
> + .has_continue_xfer_support = true,
> +};
> +
> +#if defined(CONFIG_OF)
> +/* Match table for of_platform binding */
> +static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
> + { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
> + { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
> + { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
> +#endif
> +
> static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> {
> struct tegra_i2c_dev *i2c_dev;
> @@ -600,6 +645,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> struct clk *fast_clk;
> const unsigned int *prop;
> void __iomem *base;
> + const struct tegra_i2c_hw_feature *hw = &tegra20_i2c_hw;
> int irq;
> int ret = 0;
>
> @@ -659,11 +705,18 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> i2c_dev->bus_clk_rate = be32_to_cpup(prop);
> }
>
> - if (pdev->dev.of_node)
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_device(of_match_ptr(tegra_i2c_of_match),
> + &pdev->dev);
> + hw = match->data;
> i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
> "nvidia,tegra20-i2c-dvc");
> - else if (pdev->id == 3)
> + } else if (pdev->id == 3) {
> i2c_dev->is_dvc = 1;
> + }
> +
> + i2c_dev->has_continue_xfer_support = hw->has_continue_xfer_support;
> init_completion(&i2c_dev->msg_complete);
>
> platform_set_drvdata(pdev, i2c_dev);
> @@ -751,16 +804,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, tegra_i2c_resume);
> #define TEGRA_I2C_PM NULL
> #endif
>
> -#if defined(CONFIG_OF)
> -/* Match table for of_platform binding */
> -static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
> - { .compatible = "nvidia,tegra20-i2c", },
> - { .compatible = "nvidia,tegra20-i2c-dvc", },
> - {},
> -};
> -MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
> -#endif
> -
> static struct platform_driver tegra_i2c_driver = {
> .probe = tegra_i2c_probe,
> .remove = __devexit_p(tegra_i2c_remove),
Thanks,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Wolfram Sang <w.sang@pengutronix.de>
To: Laxman Dewangan <ldewangan@nvidia.com>
Cc: khali@linux-fr.org, swarren@nvidia.com,
linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-tegra@vger.kernel.org, olof@lixom.net
Subject: Re: [PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
Date: Sat, 18 Aug 2012 14:47:03 +0200 [thread overview]
Message-ID: <20120818124703.GC12839@pengutronix.de> (raw)
In-Reply-To: <1345230155-4252-1-git-send-email-ldewangan@nvidia.com>
[-- Attachment #1: Type: text/plain, Size: 6028 bytes --]
On Sat, Aug 18, 2012 at 12:32:34AM +0530, Laxman Dewangan wrote:
> Tegra20 i2c controller does not support the continue transfer
> which implements the I2C_M_NOSTART functionality of i2c
> protocol mangling.
> Removing the I2C_M_NOSTART functionality for Tegra20.
>
> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
> ---
> This is rebased on linux-next-20120816.
>
> drivers/i2c/busses/i2c-tegra.c | 73 +++++++++++++++++++++++++++++++--------
> 1 files changed, 58 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 7149625..554f713 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -27,6 +27,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-tegra.h>
> #include <linux/of_i2c.h>
> +#include <linux/of_device.h>
> #include <linux/module.h>
>
> #include <asm/unaligned.h>
> @@ -114,6 +115,15 @@ enum msg_end_type {
> };
>
> /**
> + * struct tegra_i2c_hw_feature : Different HW support on Tegra
> + * @has_continue_xfer_support: Continue transfer supports.
> + */
> +
> +struct tegra_i2c_hw_feature {
> + bool has_continue_xfer_support;
> +};
> +
> +/**
> * struct tegra_i2c_dev - per device i2c context
> * @dev: device reference for power management
> * @adapter: core i2c layer adapter information
> @@ -148,6 +158,7 @@ struct tegra_i2c_dev {
> int msg_read;
> unsigned long bus_clk_rate;
> bool is_suspended;
> + bool has_continue_xfer_support;
I wonder if it makes sense to carry a pointer here to the
tegra_i2c_hw_feature in use instead of copying all entries by hand,
since they might get more and more.
> };
>
> static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg)
> @@ -563,7 +574,17 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
> if (i2c_dev->is_suspended)
> return -EBUSY;
>
> - clk_prepare_enable(i2c_dev->div_clk);
> + /* Support I2C_M_NOSTART only if HW support continue xfer. */
> + for (i = 0; i < num - 1; i++) {
> + if ((msgs[i + 1].flags & I2C_M_NOSTART) &&
> + !i2c_dev->has_continue_xfer_support) {
> + dev_err(i2c_dev->dev,
> + "mesg %d have illegal flag\n", i + 1);
> + return -EINVAL;
> + }
> + }
Drivers are requested to explicitly check for features of the I2C bus
(like M_NOSTART) before using them, so I'd skip this extra check.
> +
> + clk_prepare_enable(i2c_dev->clk);
From a glimpse, this change looks unrelated at least. Even wrong, no?
> for (i = 0; i < num; i++) {
> enum msg_end_type end_type = MSG_END_STOP;
> if (i < (num - 1)) {
> @@ -582,8 +603,13 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
>
> static u32 tegra_i2c_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
> - I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
> + struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
> + u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
> + I2C_FUNC_PROTOCOL_MANGLING;
> +
> + if (i2c_dev->has_continue_xfer_support)
> + ret |= I2C_FUNC_NOSTART;
> + return ret;
> }
>
> static const struct i2c_algorithm tegra_i2c_algo = {
> @@ -591,6 +617,25 @@ static const struct i2c_algorithm tegra_i2c_algo = {
> .functionality = tegra_i2c_func,
> };
>
> +static struct tegra_i2c_hw_feature tegra20_i2c_hw = {
> + .has_continue_xfer_support = false,
> +};
> +
> +static struct tegra_i2c_hw_feature tegra30_i2c_hw = {
> + .has_continue_xfer_support = true,
> +};
> +
> +#if defined(CONFIG_OF)
> +/* Match table for of_platform binding */
> +static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
> + { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
> + { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
> + { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
> +#endif
> +
> static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> {
> struct tegra_i2c_dev *i2c_dev;
> @@ -600,6 +645,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> struct clk *fast_clk;
> const unsigned int *prop;
> void __iomem *base;
> + const struct tegra_i2c_hw_feature *hw = &tegra20_i2c_hw;
> int irq;
> int ret = 0;
>
> @@ -659,11 +705,18 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
> i2c_dev->bus_clk_rate = be32_to_cpup(prop);
> }
>
> - if (pdev->dev.of_node)
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_device(of_match_ptr(tegra_i2c_of_match),
> + &pdev->dev);
> + hw = match->data;
> i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
> "nvidia,tegra20-i2c-dvc");
> - else if (pdev->id == 3)
> + } else if (pdev->id == 3) {
> i2c_dev->is_dvc = 1;
> + }
> +
> + i2c_dev->has_continue_xfer_support = hw->has_continue_xfer_support;
> init_completion(&i2c_dev->msg_complete);
>
> platform_set_drvdata(pdev, i2c_dev);
> @@ -751,16 +804,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, tegra_i2c_resume);
> #define TEGRA_I2C_PM NULL
> #endif
>
> -#if defined(CONFIG_OF)
> -/* Match table for of_platform binding */
> -static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
> - { .compatible = "nvidia,tegra20-i2c", },
> - { .compatible = "nvidia,tegra20-i2c-dvc", },
> - {},
> -};
> -MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
> -#endif
> -
> static struct platform_driver tegra_i2c_driver = {
> .probe = tegra_i2c_probe,
> .remove = __devexit_p(tegra_i2c_remove),
Thanks,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
next prev parent reply other threads:[~2012-08-18 12:47 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-17 19:02 [PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20 Laxman Dewangan
2012-08-17 19:02 ` Laxman Dewangan
[not found] ` <1345230155-4252-1-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-17 19:02 ` [PATCH REBASE 2/2] i2c: tegra: dynamically control fast clk Laxman Dewangan
2012-08-17 19:02 ` Laxman Dewangan
[not found] ` <1345230155-4252-2-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-18 18:52 ` Wolfram Sang
2012-08-18 18:52 ` Wolfram Sang
2012-08-17 21:35 ` [PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20 Stephen Warren
2012-08-17 21:35 ` Stephen Warren
2012-08-18 12:47 ` Wolfram Sang [this message]
2012-08-18 12:47 ` Wolfram Sang
[not found] ` <20120818124703.GC12839-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-08-18 12:50 ` Laxman Dewangan
2012-08-18 12:50 ` Laxman Dewangan
[not found] ` <502F8F83.5030902-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-18 18:29 ` Wolfram Sang
2012-08-18 18:29 ` Wolfram Sang
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=20120818124703.GC12839@pengutronix.de \
--to=w.sang-bicnvbalz9megne8c9+irq@public.gmane.org \
--cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
--cc=ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org \
--cc=swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.