All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] net: can: Use syscon regmap for TI specific RAMINIT register
@ 2014-11-04 10:20 ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

Hi,

Some hardware (TI am43xx) has a buggy RAMINIT DONE mechanism and it might
not always set the DONE bit. This will result in a lockup in c_can_hw_raminit_wait_ti(),
so patch 1 adds a timeout mechanism there.

There is a non compliancy within TI platforms with respect to the
layout of the RAMINIT register. The patches 2 and 3 address this issue
and make a flexible but standard way of defining the RAMINIT hardware register
layout in the device tree. The RAMINIT register is accessed using the syscon
regmap framework.

Patches available at
git@github.com:rogerq/linux.git	[for-v3.19/can]

Patches are tested on am335x-evm, am437x-gp-evm and dra7-evm.
Board support files to allow CAN testing on these boards are available at
git@github.com:rogerq/linux.git	[for-v3.19/omap-dts-dcan]

Changelog:

v3:
- allow driver data to be more than just CAN_ID
- RAMINIT register data moved to driver data instead of device tree file.

v2:
- added "ti" vendor prefix to TI specific raminit properties.
- split DTS changes into a separate series

cheers,
-roger
---

Roger Quadros (8):
  net: can: c_can: Add timeout to c_can_hw_raminit_ti()
  net: can: c_can: Introduce c_can_driver_data structure
  net: can: c_can: Add RAMINIT register information to driver data
  net: can: c_can: Add syscon/regmap RAMINIT mechanism
  net: can: c_can: Add support for START pulse in RAMINIT sequence
  net: can: c_can: Disable pins when CAN interface is down
  net: can: c_can: Add support for TI DRA7 DCAN
  net: can: c_can: Add support for TI am3352 DCAN

 .../devicetree/bindings/net/can/c_can.txt          |   5 +
 drivers/net/can/c_can/c_can.c                      |  20 ++
 drivers/net/can/c_can/c_can.h                      |  20 +-
 drivers/net/can/c_can/c_can_platform.c             | 207 +++++++++++++++------
 4 files changed, 191 insertions(+), 61 deletions(-)

-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v3 0/8] net: can: Use syscon regmap for TI specific RAMINIT register
@ 2014-11-04 10:20 ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

Hi,

Some hardware (TI am43xx) has a buggy RAMINIT DONE mechanism and it might
not always set the DONE bit. This will result in a lockup in c_can_hw_raminit_wait_ti(),
so patch 1 adds a timeout mechanism there.

There is a non compliancy within TI platforms with respect to the
layout of the RAMINIT register. The patches 2 and 3 address this issue
and make a flexible but standard way of defining the RAMINIT hardware register
layout in the device tree. The RAMINIT register is accessed using the syscon
regmap framework.

Patches available at
git@github.com:rogerq/linux.git	[for-v3.19/can]

Patches are tested on am335x-evm, am437x-gp-evm and dra7-evm.
Board support files to allow CAN testing on these boards are available at
git@github.com:rogerq/linux.git	[for-v3.19/omap-dts-dcan]

Changelog:

v3:
- allow driver data to be more than just CAN_ID
- RAMINIT register data moved to driver data instead of device tree file.

v2:
- added "ti" vendor prefix to TI specific raminit properties.
- split DTS changes into a separate series

cheers,
-roger
---

Roger Quadros (8):
  net: can: c_can: Add timeout to c_can_hw_raminit_ti()
  net: can: c_can: Introduce c_can_driver_data structure
  net: can: c_can: Add RAMINIT register information to driver data
  net: can: c_can: Add syscon/regmap RAMINIT mechanism
  net: can: c_can: Add support for START pulse in RAMINIT sequence
  net: can: c_can: Disable pins when CAN interface is down
  net: can: c_can: Add support for TI DRA7 DCAN
  net: can: c_can: Add support for TI am3352 DCAN

 .../devicetree/bindings/net/can/c_can.txt          |   5 +
 drivers/net/can/c_can/c_can.c                      |  20 ++
 drivers/net/can/c_can/c_can.h                      |  20 +-
 drivers/net/can/c_can/c_can_platform.c             | 207 +++++++++++++++------
 4 files changed, 191 insertions(+), 61 deletions(-)

-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v3 1/8] net: can: c_can: Add timeout to c_can_hw_raminit_ti()
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

TI's RAMINIT DONE mechanism is buggy on AM43xx SoC and may not always
be set after the START bit is set. Although it seems to work fine even
in that case. So add a timeout mechanism to c_can_hw_raminit_wait_ti().
Don't bail out in that failure case but just print an error message.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can_platform.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index fb279d6..b144e71 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -75,10 +75,18 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
 static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
 				  u32 val)
 {
+	int timeout = 0;
 	/* We look only at the bits of our instance. */
 	val &= mask;
-	while ((readl(priv->raminit_ctrlreg) & mask) != val)
+	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
 		udelay(1);
+		timeout++;
+
+		if (timeout == 1000) {
+			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
+			break;
+		}
+	}
 }
 
 static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 1/8] net: can: c_can: Add timeout to c_can_hw_raminit_ti()
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

TI's RAMINIT DONE mechanism is buggy on AM43xx SoC and may not always
be set after the START bit is set. Although it seems to work fine even
in that case. So add a timeout mechanism to c_can_hw_raminit_wait_ti().
Don't bail out in that failure case but just print an error message.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can_platform.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index fb279d6..b144e71 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -75,10 +75,18 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
 static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
 				  u32 val)
 {
+	int timeout = 0;
 	/* We look only at the bits of our instance. */
 	val &= mask;
-	while ((readl(priv->raminit_ctrlreg) & mask) != val)
+	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
 		udelay(1);
+		timeout++;
+
+		if (timeout == 1000) {
+			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
+			break;
+		}
+	}
 }
 
 static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 2/8] net: can: c_can: Introduce c_can_driver_data structure
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

We want to have more data than just can_dev_id to be present
in the driver data e.g. TI platforms need RAMINIT register
description. Introduce the c_can_driver_data structure and move
the can_dev_id into it.

Tidy up the way it is used on probe().

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.h          |  4 +++
 drivers/net/can/c_can/c_can_platform.c | 52 +++++++++++++++++++---------------
 2 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 99ad1aa..26c975d 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -169,6 +169,10 @@ enum c_can_dev_id {
 	BOSCH_D_CAN,
 };
 
+struct c_can_driver_data {
+	enum c_can_dev_id id;
+};
+
 /* c_can private data structure */
 struct c_can_priv {
 	struct can_priv can;	/* must be the first member */
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index b144e71..1546c2b 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -167,26 +167,34 @@ static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
 	}
 }
 
+static struct c_can_driver_data c_can_drvdata = {
+	.id = BOSCH_C_CAN,
+};
+
+static struct c_can_driver_data d_can_drvdata = {
+	.id = BOSCH_D_CAN,
+};
+
 static struct platform_device_id c_can_id_table[] = {
-	[BOSCH_C_CAN_PLATFORM] = {
+	{
 		.name = KBUILD_MODNAME,
-		.driver_data = BOSCH_C_CAN,
+		.driver_data = (kernel_ulong_t)&c_can_drvdata,
 	},
-	[BOSCH_C_CAN] = {
+	{
 		.name = "c_can",
-		.driver_data = BOSCH_C_CAN,
+		.driver_data = (kernel_ulong_t)&c_can_drvdata,
 	},
-	[BOSCH_D_CAN] = {
+	{
 		.name = "d_can",
-		.driver_data = BOSCH_D_CAN,
-	}, {
-	}
+		.driver_data = (kernel_ulong_t)&d_can_drvdata,
+	},
+	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(platform, c_can_id_table);
 
 static const struct of_device_id c_can_of_table[] = {
-	{ .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] },
-	{ .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] },
+	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
+	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
@@ -198,21 +206,19 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct c_can_priv *priv;
 	const struct of_device_id *match;
-	const struct platform_device_id *id;
 	struct resource *mem, *res;
 	int irq;
 	struct clk *clk;
-
-	if (pdev->dev.of_node) {
-		match = of_match_device(c_can_of_table, &pdev->dev);
-		if (!match) {
-			dev_err(&pdev->dev, "Failed to find matching dt id\n");
-			ret = -EINVAL;
-			goto exit;
-		}
-		id = match->data;
+	const struct c_can_driver_data *drvdata;
+
+	match = of_match_device(c_can_of_table, &pdev->dev);
+	if (match) {
+		drvdata = match->data;
+	} else if (pdev->id_entry->driver_data) {
+		drvdata = (struct c_can_driver_data *)
+			   pdev->id_entry->driver_data;
 	} else {
-		id = platform_get_device_id(pdev);
+		return -ENODEV;
 	}
 
 	/* get the appropriate clk */
@@ -244,7 +250,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	}
 
 	priv = netdev_priv(dev);
-	switch (id->driver_data) {
+	switch (drvdata->id) {
 	case BOSCH_C_CAN:
 		priv->regs = reg_map_c_can;
 		switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
@@ -303,7 +309,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	priv->device = &pdev->dev;
 	priv->can.clock.freq = clk_get_rate(clk);
 	priv->priv = clk;
-	priv->type = id->driver_data;
+	priv->type = drvdata->id;
 
 	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 2/8] net: can: c_can: Introduce c_can_driver_data structure
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

We want to have more data than just can_dev_id to be present
in the driver data e.g. TI platforms need RAMINIT register
description. Introduce the c_can_driver_data structure and move
the can_dev_id into it.

Tidy up the way it is used on probe().

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.h          |  4 +++
 drivers/net/can/c_can/c_can_platform.c | 52 +++++++++++++++++++---------------
 2 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 99ad1aa..26c975d 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -169,6 +169,10 @@ enum c_can_dev_id {
 	BOSCH_D_CAN,
 };
 
+struct c_can_driver_data {
+	enum c_can_dev_id id;
+};
+
 /* c_can private data structure */
 struct c_can_priv {
 	struct can_priv can;	/* must be the first member */
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index b144e71..1546c2b 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -167,26 +167,34 @@ static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
 	}
 }
 
+static struct c_can_driver_data c_can_drvdata = {
+	.id = BOSCH_C_CAN,
+};
+
+static struct c_can_driver_data d_can_drvdata = {
+	.id = BOSCH_D_CAN,
+};
+
 static struct platform_device_id c_can_id_table[] = {
-	[BOSCH_C_CAN_PLATFORM] = {
+	{
 		.name = KBUILD_MODNAME,
-		.driver_data = BOSCH_C_CAN,
+		.driver_data = (kernel_ulong_t)&c_can_drvdata,
 	},
-	[BOSCH_C_CAN] = {
+	{
 		.name = "c_can",
-		.driver_data = BOSCH_C_CAN,
+		.driver_data = (kernel_ulong_t)&c_can_drvdata,
 	},
-	[BOSCH_D_CAN] = {
+	{
 		.name = "d_can",
-		.driver_data = BOSCH_D_CAN,
-	}, {
-	}
+		.driver_data = (kernel_ulong_t)&d_can_drvdata,
+	},
+	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(platform, c_can_id_table);
 
 static const struct of_device_id c_can_of_table[] = {
-	{ .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] },
-	{ .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] },
+	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
+	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
@@ -198,21 +206,19 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct c_can_priv *priv;
 	const struct of_device_id *match;
-	const struct platform_device_id *id;
 	struct resource *mem, *res;
 	int irq;
 	struct clk *clk;
-
-	if (pdev->dev.of_node) {
-		match = of_match_device(c_can_of_table, &pdev->dev);
-		if (!match) {
-			dev_err(&pdev->dev, "Failed to find matching dt id\n");
-			ret = -EINVAL;
-			goto exit;
-		}
-		id = match->data;
+	const struct c_can_driver_data *drvdata;
+
+	match = of_match_device(c_can_of_table, &pdev->dev);
+	if (match) {
+		drvdata = match->data;
+	} else if (pdev->id_entry->driver_data) {
+		drvdata = (struct c_can_driver_data *)
+			   pdev->id_entry->driver_data;
 	} else {
-		id = platform_get_device_id(pdev);
+		return -ENODEV;
 	}
 
 	/* get the appropriate clk */
@@ -244,7 +250,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	}
 
 	priv = netdev_priv(dev);
-	switch (id->driver_data) {
+	switch (drvdata->id) {
 	case BOSCH_C_CAN:
 		priv->regs = reg_map_c_can;
 		switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
@@ -303,7 +309,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	priv->device = &pdev->dev;
 	priv->can.clock.freq = clk_get_rate(clk);
 	priv->priv = clk;
-	priv->type = id->driver_data;
+	priv->type = drvdata->id;
 
 	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 3/8] net: can: c_can: Add RAMINIT register information to driver data
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

Some platforms (e.g. TI) need special RAMINIT register handling.
Provide a way to store RAMINIT register description in driver data.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.h          | 6 ++++++
 drivers/net/can/c_can/c_can_platform.c | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 26c975d..c3b2108 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -171,6 +171,11 @@ enum c_can_dev_id {
 
 struct c_can_driver_data {
 	enum c_can_dev_id id;
+
+	/* RAMINIT register description. Optional. */
+	u8 raminit_start_bit;	/* START bit position in RAMINIT reg. */
+	u8 raminit_done_bit;	/* DONE bit position in RAMINIT reg. */
+	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
 };
 
 /* c_can private data structure */
@@ -196,6 +201,7 @@ struct c_can_priv {
 	u32 comm_rcv_high;
 	u32 rxmasked;
 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
+	const struct c_can_driver_data *drvdata;
 };
 
 struct net_device *alloc_c_can_dev(void);
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 1546c2b..11946e8 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -250,6 +250,8 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	}
 
 	priv = netdev_priv(dev);
+	priv->drvdata = drvdata;
+
 	switch (drvdata->id) {
 	case BOSCH_C_CAN:
 		priv->regs = reg_map_c_can;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 3/8] net: can: c_can: Add RAMINIT register information to driver data
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

Some platforms (e.g. TI) need special RAMINIT register handling.
Provide a way to store RAMINIT register description in driver data.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.h          | 6 ++++++
 drivers/net/can/c_can/c_can_platform.c | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 26c975d..c3b2108 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -171,6 +171,11 @@ enum c_can_dev_id {
 
 struct c_can_driver_data {
 	enum c_can_dev_id id;
+
+	/* RAMINIT register description. Optional. */
+	u8 raminit_start_bit;	/* START bit position in RAMINIT reg. */
+	u8 raminit_done_bit;	/* DONE bit position in RAMINIT reg. */
+	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
 };
 
 /* c_can private data structure */
@@ -196,6 +201,7 @@ struct c_can_priv {
 	u32 comm_rcv_high;
 	u32 rxmasked;
 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
+	const struct c_can_driver_data *drvdata;
 };
 
 struct net_device *alloc_c_can_dev(void);
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 1546c2b..11946e8 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -250,6 +250,8 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	}
 
 	priv = netdev_priv(dev);
+	priv->drvdata = drvdata;
+
 	switch (drvdata->id) {
 	case BOSCH_C_CAN:
 		priv->regs = reg_map_c_can;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

Some TI SoCs like DRA7 have a RAMINIT register specification
different from the other AMxx SoCs and as expected by the
existing driver.

To add more insanity, this register is shared with other
IPs like DSS, PCIe and PWM.

Provides a more generic mechanism to specify the RAMINIT
register location and START/DONE bit position and use the
syscon/regmap framework to access the register.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 .../devicetree/bindings/net/can/c_can.txt          |  3 +
 drivers/net/can/c_can/c_can.h                      |  9 ++-
 drivers/net/can/c_can/c_can_platform.c             | 93 +++++++++++++---------
 3 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 8f1ae81..917ac0e 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -12,6 +12,9 @@ Required properties:
 Optional properties:
 - ti,hwmods		: Must be "d_can<n>" or "c_can<n>", n being the
 			  instance number
+- syscon-raminit	: Handle to system control region that contains the
+			  RAMINIT register and register offset to the RAMINIT
+			  register.
 
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index c3b2108..b5067bd 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -178,6 +178,12 @@ struct c_can_driver_data {
 	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
 };
 
+/* Out of band RAMINIT register access via syscon regmap */
+struct c_can_raminit {
+	struct regmap *syscon;	/* for raminit ctrl. reg. access */
+	unsigned int reg;	/* register index within syscon */
+};
+
 /* c_can private data structure */
 struct c_can_priv {
 	struct can_priv can;	/* must be the first member */
@@ -195,8 +201,7 @@ struct c_can_priv {
 	const u16 *regs;
 	void *priv;		/* for board-specific data */
 	enum c_can_dev_id type;
-	u32 __iomem *raminit_ctrlreg;
-	int instance;
+	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
 	void (*raminit) (const struct c_can_priv *priv, bool enable);
 	u32 comm_rcv_high;
 	u32 rxmasked;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 11946e8..d0ce439 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -32,14 +32,13 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <linux/can/dev.h>
 
 #include "c_can.h"
 
-#define CAN_RAMINIT_START_MASK(i)	(0x001 << (i))
-#define CAN_RAMINIT_DONE_MASK(i)	(0x100 << (i))
-#define CAN_RAMINIT_ALL_MASK(i)		(0x101 << (i))
 #define DCAN_RAM_INIT_BIT		(1 << 3)
 static DEFINE_SPINLOCK(raminit_lock);
 /*
@@ -72,47 +71,61 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
 	writew(val, priv->base + 2 * priv->regs[index]);
 }
 
-static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
-				  u32 val)
+static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
+					 u32 mask, u32 val)
 {
 	int timeout = 0;
+	const struct c_can_raminit *raminit = &priv->raminit_sys;
+	u32 ctrl;
+
 	/* We look only at the bits of our instance. */
 	val &= mask;
-	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
+	do {
 		udelay(1);
 		timeout++;
 
+		regmap_read(raminit->syscon, raminit->reg, &ctrl);
 		if (timeout == 1000) {
 			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
 			break;
 		}
-	}
+	} while ((ctrl & mask) != val);
 }
 
-static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
+static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
 {
-	u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
+	u32 mask;
 	u32 ctrl;
+	const struct c_can_raminit *raminit = &priv->raminit_sys;
+	u8 start_bit, done_bit;
+
+	start_bit = priv->drvdata->raminit_start_bit;
+	done_bit = priv->drvdata->raminit_done_bit;
 
 	spin_lock(&raminit_lock);
 
-	ctrl = readl(priv->raminit_ctrlreg);
+	mask = 1 << start_bit | 1 << done_bit;
+	regmap_read(raminit->syscon, raminit->reg, &ctrl);
+
 	/* We clear the done and start bit first. The start bit is
 	 * looking at the 0 -> transition, but is not self clearing;
 	 * And we clear the init done bit as well.
+	 * NOTE: DONE must be written with 1 to clear it.
 	 */
-	ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
-	ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
-	writel(ctrl, priv->raminit_ctrlreg);
-	ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
-	c_can_hw_raminit_wait_ti(priv, mask, ctrl);
+	ctrl &= ~(1 << start_bit);
+	ctrl |= 1 << done_bit;
+	regmap_write(raminit->syscon, raminit->reg, ctrl);
+
+	ctrl &= ~(1 << done_bit);
+	c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 
 	if (enable) {
 		/* Set start bit and wait for the done bit. */
-		ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
-		writel(ctrl, priv->raminit_ctrlreg);
-		ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
-		c_can_hw_raminit_wait_ti(priv, mask, ctrl);
+		ctrl |= 1 << start_bit;
+		regmap_write(raminit->syscon, raminit->reg, ctrl);
+
+		ctrl |= 1 << done_bit;
+		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 	}
 	spin_unlock(&raminit_lock);
 }
@@ -206,10 +219,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct c_can_priv *priv;
 	const struct of_device_id *match;
-	struct resource *mem, *res;
+	struct resource *mem;
 	int irq;
 	struct clk *clk;
 	const struct c_can_driver_data *drvdata;
+	struct device_node *np = pdev->dev.of_node;
 
 	match = of_match_device(c_can_of_table, &pdev->dev);
 	if (match) {
@@ -279,27 +293,30 @@ static int c_can_plat_probe(struct platform_device *pdev)
 		priv->read_reg32 = d_can_plat_read_reg32;
 		priv->write_reg32 = d_can_plat_write_reg32;
 
-		if (pdev->dev.of_node)
-			priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
-		else
-			priv->instance = pdev->id;
-
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		/* Not all D_CAN modules have a separate register for the D_CAN
-		 * RAM initialization. Use default RAM init bit in D_CAN module
-		 * if not specified in DT.
+		/* Check if we need custom RAMINIT via syscon. Mostly for TI
+		 * platforms. Only supported with DT boot.
 		 */
-		if (!res) {
+		if (np && of_property_read_bool(np, "syscon-raminit")) {
+			ret = -EINVAL;
+			priv->raminit_sys.syscon = syscon_regmap_lookup_by_phandle(np,
+					"syscon-raminit");
+			if (IS_ERR(priv->raminit_sys.syscon)) {
+				dev_err(&pdev->dev,
+					"couldn't get syscon regmap for RAMINIT reg.\n");
+				goto exit_free_device;
+			}
+
+			if (of_property_read_u32_index(np, "syscon-raminit", 1,
+						       &priv->raminit_sys.reg)) {
+				dev_err(&pdev->dev,
+					"couldn't get the RAMINIT reg. offset!\n");
+				goto exit_free_device;
+			}
+
+			priv->raminit = c_can_hw_raminit_syscon;
+		} else {
 			priv->raminit = c_can_hw_raminit;
-			break;
 		}
-
-		priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
-						     resource_size(res));
-		if (!priv->raminit_ctrlreg || priv->instance < 0)
-			dev_info(&pdev->dev, "control memory is not used for raminit\n");
-		else
-			priv->raminit = c_can_hw_raminit_ti;
 		break;
 	default:
 		ret = -EINVAL;
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

Some TI SoCs like DRA7 have a RAMINIT register specification
different from the other AMxx SoCs and as expected by the
existing driver.

To add more insanity, this register is shared with other
IPs like DSS, PCIe and PWM.

Provides a more generic mechanism to specify the RAMINIT
register location and START/DONE bit position and use the
syscon/regmap framework to access the register.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 .../devicetree/bindings/net/can/c_can.txt          |  3 +
 drivers/net/can/c_can/c_can.h                      |  9 ++-
 drivers/net/can/c_can/c_can_platform.c             | 93 +++++++++++++---------
 3 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 8f1ae81..917ac0e 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -12,6 +12,9 @@ Required properties:
 Optional properties:
 - ti,hwmods		: Must be "d_can<n>" or "c_can<n>", n being the
 			  instance number
+- syscon-raminit	: Handle to system control region that contains the
+			  RAMINIT register and register offset to the RAMINIT
+			  register.
 
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index c3b2108..b5067bd 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -178,6 +178,12 @@ struct c_can_driver_data {
 	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
 };
 
+/* Out of band RAMINIT register access via syscon regmap */
+struct c_can_raminit {
+	struct regmap *syscon;	/* for raminit ctrl. reg. access */
+	unsigned int reg;	/* register index within syscon */
+};
+
 /* c_can private data structure */
 struct c_can_priv {
 	struct can_priv can;	/* must be the first member */
@@ -195,8 +201,7 @@ struct c_can_priv {
 	const u16 *regs;
 	void *priv;		/* for board-specific data */
 	enum c_can_dev_id type;
-	u32 __iomem *raminit_ctrlreg;
-	int instance;
+	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
 	void (*raminit) (const struct c_can_priv *priv, bool enable);
 	u32 comm_rcv_high;
 	u32 rxmasked;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 11946e8..d0ce439 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -32,14 +32,13 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <linux/can/dev.h>
 
 #include "c_can.h"
 
-#define CAN_RAMINIT_START_MASK(i)	(0x001 << (i))
-#define CAN_RAMINIT_DONE_MASK(i)	(0x100 << (i))
-#define CAN_RAMINIT_ALL_MASK(i)		(0x101 << (i))
 #define DCAN_RAM_INIT_BIT		(1 << 3)
 static DEFINE_SPINLOCK(raminit_lock);
 /*
@@ -72,47 +71,61 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
 	writew(val, priv->base + 2 * priv->regs[index]);
 }
 
-static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
-				  u32 val)
+static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
+					 u32 mask, u32 val)
 {
 	int timeout = 0;
+	const struct c_can_raminit *raminit = &priv->raminit_sys;
+	u32 ctrl;
+
 	/* We look only at the bits of our instance. */
 	val &= mask;
-	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
+	do {
 		udelay(1);
 		timeout++;
 
+		regmap_read(raminit->syscon, raminit->reg, &ctrl);
 		if (timeout == 1000) {
 			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
 			break;
 		}
-	}
+	} while ((ctrl & mask) != val);
 }
 
-static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
+static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
 {
-	u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
+	u32 mask;
 	u32 ctrl;
+	const struct c_can_raminit *raminit = &priv->raminit_sys;
+	u8 start_bit, done_bit;
+
+	start_bit = priv->drvdata->raminit_start_bit;
+	done_bit = priv->drvdata->raminit_done_bit;
 
 	spin_lock(&raminit_lock);
 
-	ctrl = readl(priv->raminit_ctrlreg);
+	mask = 1 << start_bit | 1 << done_bit;
+	regmap_read(raminit->syscon, raminit->reg, &ctrl);
+
 	/* We clear the done and start bit first. The start bit is
 	 * looking at the 0 -> transition, but is not self clearing;
 	 * And we clear the init done bit as well.
+	 * NOTE: DONE must be written with 1 to clear it.
 	 */
-	ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
-	ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
-	writel(ctrl, priv->raminit_ctrlreg);
-	ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
-	c_can_hw_raminit_wait_ti(priv, mask, ctrl);
+	ctrl &= ~(1 << start_bit);
+	ctrl |= 1 << done_bit;
+	regmap_write(raminit->syscon, raminit->reg, ctrl);
+
+	ctrl &= ~(1 << done_bit);
+	c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 
 	if (enable) {
 		/* Set start bit and wait for the done bit. */
-		ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
-		writel(ctrl, priv->raminit_ctrlreg);
-		ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
-		c_can_hw_raminit_wait_ti(priv, mask, ctrl);
+		ctrl |= 1 << start_bit;
+		regmap_write(raminit->syscon, raminit->reg, ctrl);
+
+		ctrl |= 1 << done_bit;
+		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 	}
 	spin_unlock(&raminit_lock);
 }
@@ -206,10 +219,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct c_can_priv *priv;
 	const struct of_device_id *match;
-	struct resource *mem, *res;
+	struct resource *mem;
 	int irq;
 	struct clk *clk;
 	const struct c_can_driver_data *drvdata;
+	struct device_node *np = pdev->dev.of_node;
 
 	match = of_match_device(c_can_of_table, &pdev->dev);
 	if (match) {
@@ -279,27 +293,30 @@ static int c_can_plat_probe(struct platform_device *pdev)
 		priv->read_reg32 = d_can_plat_read_reg32;
 		priv->write_reg32 = d_can_plat_write_reg32;
 
-		if (pdev->dev.of_node)
-			priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
-		else
-			priv->instance = pdev->id;
-
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		/* Not all D_CAN modules have a separate register for the D_CAN
-		 * RAM initialization. Use default RAM init bit in D_CAN module
-		 * if not specified in DT.
+		/* Check if we need custom RAMINIT via syscon. Mostly for TI
+		 * platforms. Only supported with DT boot.
 		 */
-		if (!res) {
+		if (np && of_property_read_bool(np, "syscon-raminit")) {
+			ret = -EINVAL;
+			priv->raminit_sys.syscon = syscon_regmap_lookup_by_phandle(np,
+					"syscon-raminit");
+			if (IS_ERR(priv->raminit_sys.syscon)) {
+				dev_err(&pdev->dev,
+					"couldn't get syscon regmap for RAMINIT reg.\n");
+				goto exit_free_device;
+			}
+
+			if (of_property_read_u32_index(np, "syscon-raminit", 1,
+						       &priv->raminit_sys.reg)) {
+				dev_err(&pdev->dev,
+					"couldn't get the RAMINIT reg. offset!\n");
+				goto exit_free_device;
+			}
+
+			priv->raminit = c_can_hw_raminit_syscon;
+		} else {
 			priv->raminit = c_can_hw_raminit;
-			break;
 		}
-
-		priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
-						     resource_size(res));
-		if (!priv->raminit_ctrlreg || priv->instance < 0)
-			dev_info(&pdev->dev, "control memory is not used for raminit\n");
-		else
-			priv->raminit = c_can_hw_raminit_ti;
 		break;
 	default:
 		ret = -EINVAL;
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 5/8] net: can: c_can: Add support for START pulse in RAMINIT sequence
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

Some SoCs e.g. (TI DRA7xx) need a START pulse to start the
RAMINIT sequence i.e. START bit must be set and cleared before
checking for the DONE bit status.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can_platform.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index d0ce439..ef1f5ce 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -124,6 +124,12 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
 		ctrl |= 1 << start_bit;
 		regmap_write(raminit->syscon, raminit->reg, ctrl);
 
+		/* clear START bit if start pulse is needed */
+		if (priv->drvdata->raminit_pulse) {
+			ctrl &= ~(1 << start_bit);
+			regmap_write(raminit->syscon, raminit->reg, ctrl);
+		}
+
 		ctrl |= 1 << done_bit;
 		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 	}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 5/8] net: can: c_can: Add support for START pulse in RAMINIT sequence
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

Some SoCs e.g. (TI DRA7xx) need a START pulse to start the
RAMINIT sequence i.e. START bit must be set and cleared before
checking for the DONE bit status.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can_platform.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index d0ce439..ef1f5ce 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -124,6 +124,12 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
 		ctrl |= 1 << start_bit;
 		regmap_write(raminit->syscon, raminit->reg, ctrl);
 
+		/* clear START bit if start pulse is needed */
+		if (priv->drvdata->raminit_pulse) {
+			ctrl &= ~(1 << start_bit);
+			regmap_write(raminit->syscon, raminit->reg, ctrl);
+		}
+
 		ctrl |= 1 << done_bit;
 		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
 	}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:20   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

DRA7 CAN IP suffers from a problem which causes it to be prevented
from fully turning OFF (i.e. stuck in transition) if the module was
disabled while there was traffic on the CAN_RX line.

To work around this issue we select the SLEEP pin state by default
on probe and use the DEFAULT pin state on CAN up and back to the
SLEEP pin state on CAN down.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
 drivers/net/can/c_can/c_can.h          |  1 +
 drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 8e78bb4..4dfc3ce 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
+	/* activate pins */
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	}
+
 	return 0;
 }
 
@@ -611,6 +621,16 @@ static void c_can_stop(struct net_device *dev)
 	struct c_can_priv *priv = netdev_priv(dev);
 
 	c_can_irq_control(priv, false);
+
+	/* deactivate pins */
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_SLEEP);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	}
+
 	priv->can.state = CAN_STATE_STOPPED;
 }
 
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index b5067bd..6b4ed1f 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -207,6 +207,7 @@ struct c_can_priv {
 	u32 rxmasked;
 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
 	const struct c_can_driver_data *drvdata;
+	struct pinctrl *pinctrl;
 };
 
 struct net_device *alloc_c_can_dev(void);
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index ef1f5ce..d058820 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -34,6 +34,7 @@
 #include <linux/of_device.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/can/dev.h>
 
@@ -230,6 +231,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct clk *clk;
 	const struct c_can_driver_data *drvdata;
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 
 	match = of_match_device(c_can_of_table, &pdev->dev);
 	if (match) {
@@ -241,6 +243,23 @@ static int c_can_plat_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	pinctrl = devm_pinctrl_get(&pdev->dev);
+	if (!IS_ERR(pinctrl)) {
+		struct pinctrl_state *s;
+
+		/* Deactivate pins to prevent DRA7 DCAN IP from being
+		 * stuck in transition when module is disabled.
+		 * Pins are activated in c_can_start() and deactivated
+		 * in c_can_stop()
+		 */
+		s = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_SLEEP);
+		if (!IS_ERR(s))
+			pinctrl_select_state(pinctrl, s);
+	} else {
+		dev_warn(&pdev->dev,
+			 "failed to get pinctrl\n");
+	}
+
 	/* get the appropriate clk */
 	clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -271,6 +290,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(dev);
 	priv->drvdata = drvdata;
+	priv->pinctrl = pinctrl;
 
 	switch (drvdata->id) {
 	case BOSCH_C_CAN:
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
@ 2014-11-04 10:20   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:20 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

DRA7 CAN IP suffers from a problem which causes it to be prevented
from fully turning OFF (i.e. stuck in transition) if the module was
disabled while there was traffic on the CAN_RX line.

To work around this issue we select the SLEEP pin state by default
on probe and use the DEFAULT pin state on CAN up and back to the
SLEEP pin state on CAN down.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
 drivers/net/can/c_can/c_can.h          |  1 +
 drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 8e78bb4..4dfc3ce 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
+	/* activate pins */
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	}
+
 	return 0;
 }
 
@@ -611,6 +621,16 @@ static void c_can_stop(struct net_device *dev)
 	struct c_can_priv *priv = netdev_priv(dev);
 
 	c_can_irq_control(priv, false);
+
+	/* deactivate pins */
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_SLEEP);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	}
+
 	priv->can.state = CAN_STATE_STOPPED;
 }
 
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index b5067bd..6b4ed1f 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -207,6 +207,7 @@ struct c_can_priv {
 	u32 rxmasked;
 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
 	const struct c_can_driver_data *drvdata;
+	struct pinctrl *pinctrl;
 };
 
 struct net_device *alloc_c_can_dev(void);
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index ef1f5ce..d058820 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -34,6 +34,7 @@
 #include <linux/of_device.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/can/dev.h>
 
@@ -230,6 +231,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 	struct clk *clk;
 	const struct c_can_driver_data *drvdata;
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 
 	match = of_match_device(c_can_of_table, &pdev->dev);
 	if (match) {
@@ -241,6 +243,23 @@ static int c_can_plat_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	pinctrl = devm_pinctrl_get(&pdev->dev);
+	if (!IS_ERR(pinctrl)) {
+		struct pinctrl_state *s;
+
+		/* Deactivate pins to prevent DRA7 DCAN IP from being
+		 * stuck in transition when module is disabled.
+		 * Pins are activated in c_can_start() and deactivated
+		 * in c_can_stop()
+		 */
+		s = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_SLEEP);
+		if (!IS_ERR(s))
+			pinctrl_select_state(pinctrl, s);
+	} else {
+		dev_warn(&pdev->dev,
+			 "failed to get pinctrl\n");
+	}
+
 	/* get the appropriate clk */
 	clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -271,6 +290,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(dev);
 	priv->drvdata = drvdata;
+	priv->pinctrl = pinctrl;
 
 	switch (drvdata->id) {
 	case BOSCH_C_CAN:
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:21   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:21 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
register data for both.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
 drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 917ac0e..746cc07 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
 Required properties:
 - compatible		: Should be "bosch,c_can" for C_CAN controllers and
 			  "bosch,d_can" for D_CAN controllers.
+			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
 - reg			: physical base address and size of the C_CAN/D_CAN
 			  registers map
 - interrupts		: property with a value describing the interrupt
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index d058820..dc618ce 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
 	.id = BOSCH_D_CAN,
 };
 
+static struct c_can_driver_data dra7_dcan1_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 3,
+	.raminit_done_bit = 1,
+	.raminit_pulse = true,
+};
+
+static struct c_can_driver_data dra7_dcan2_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 5,
+	.raminit_done_bit = 2,
+	.raminit_pulse = true,
+};
+
 static struct platform_device_id c_can_id_table[] = {
 	{
 		.name = KBUILD_MODNAME,
@@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
 static const struct of_device_id c_can_of_table[] = {
 	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
 	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
+	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
+	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
@ 2014-11-04 10:21   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:21 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
register data for both.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
 drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 917ac0e..746cc07 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
 Required properties:
 - compatible		: Should be "bosch,c_can" for C_CAN controllers and
 			  "bosch,d_can" for D_CAN controllers.
+			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
 - reg			: physical base address and size of the C_CAN/D_CAN
 			  registers map
 - interrupts		: property with a value describing the interrupt
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index d058820..dc618ce 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
 	.id = BOSCH_D_CAN,
 };
 
+static struct c_can_driver_data dra7_dcan1_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 3,
+	.raminit_done_bit = 1,
+	.raminit_pulse = true,
+};
+
+static struct c_can_driver_data dra7_dcan2_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 5,
+	.raminit_done_bit = 2,
+	.raminit_pulse = true,
+};
+
 static struct platform_device_id c_can_id_table[] = {
 	{
 		.name = KBUILD_MODNAME,
@@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
 static const struct of_device_id c_can_of_table[] = {
 	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
 	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
+	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
+	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 8/8] net: can: c_can: Add support for TI am3352 DCAN
  2014-11-04 10:20 ` Roger Quadros
@ 2014-11-04 10:21   ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:21 UTC (permalink / raw)
  To: wg, mkl; +Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

AM3352 SoC has 2 DCAN modules. Add compatible id and
raminit driver data for am3352 DCAN.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 Documentation/devicetree/bindings/net/can/c_can.txt |  3 ++-
 drivers/net/can/c_can/c_can_platform.c              | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 746cc07..27205d9 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -4,7 +4,8 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
 Required properties:
 - compatible		: Should be "bosch,c_can" for C_CAN controllers and
 			  "bosch,d_can" for D_CAN controllers.
-			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
+			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2" or
+			  "ti,am3352-d_can0" or "ti,am3352-d_can1".
 - reg			: physical base address and size of the C_CAN/D_CAN
 			  registers map
 - interrupts		: property with a value describing the interrupt
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index dc618ce..7dcdcde 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -209,6 +209,18 @@ static struct c_can_driver_data dra7_dcan2_drvdata = {
 	.raminit_pulse = true,
 };
 
+static struct c_can_driver_data am3352_dcan0_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 0,
+	.raminit_done_bit = 8,
+};
+
+static struct c_can_driver_data am3352_dcan1_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 1,
+	.raminit_done_bit = 9,
+};
+
 static struct platform_device_id c_can_id_table[] = {
 	{
 		.name = KBUILD_MODNAME,
@@ -231,6 +243,8 @@ static const struct of_device_id c_can_of_table[] = {
 	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
 	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
 	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
+	{ .compatible = "ti,am3352-d_can0", .data = &am3352_dcan0_drvdata },
+	{ .compatible = "ti,am3352-d_can1", .data = &am3352_dcan1_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 8/8] net: can: c_can: Add support for TI am3352 DCAN
@ 2014-11-04 10:21   ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-04 10:21 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev,
	Roger Quadros

AM3352 SoC has 2 DCAN modules. Add compatible id and
raminit driver data for am3352 DCAN.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 Documentation/devicetree/bindings/net/can/c_can.txt |  3 ++-
 drivers/net/can/c_can/c_can_platform.c              | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 746cc07..27205d9 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -4,7 +4,8 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
 Required properties:
 - compatible		: Should be "bosch,c_can" for C_CAN controllers and
 			  "bosch,d_can" for D_CAN controllers.
-			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
+			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2" or
+			  "ti,am3352-d_can0" or "ti,am3352-d_can1".
 - reg			: physical base address and size of the C_CAN/D_CAN
 			  registers map
 - interrupts		: property with a value describing the interrupt
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index dc618ce..7dcdcde 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -209,6 +209,18 @@ static struct c_can_driver_data dra7_dcan2_drvdata = {
 	.raminit_pulse = true,
 };
 
+static struct c_can_driver_data am3352_dcan0_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 0,
+	.raminit_done_bit = 8,
+};
+
+static struct c_can_driver_data am3352_dcan1_drvdata = {
+	.id = BOSCH_D_CAN,
+	.raminit_start_bit = 1,
+	.raminit_done_bit = 9,
+};
+
 static struct platform_device_id c_can_id_table[] = {
 	{
 		.name = KBUILD_MODNAME,
@@ -231,6 +243,8 @@ static const struct of_device_id c_can_of_table[] = {
 	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
 	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
 	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
+	{ .compatible = "ti,am3352-d_can0", .data = &am3352_dcan0_drvdata },
+	{ .compatible = "ti,am3352-d_can1", .data = &am3352_dcan1_drvdata },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, c_can_of_table);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
  2014-11-04 10:20   ` Roger Quadros
@ 2014-11-05 11:37     ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 11:37 UTC (permalink / raw)
  To: wg, mkl, Tomi Valkeinen
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

On 11/04/2014 12:20 PM, Roger Quadros wrote:
> Some TI SoCs like DRA7 have a RAMINIT register specification
> different from the other AMxx SoCs and as expected by the
> existing driver.
> 
> To add more insanity, this register is shared with other
> IPs like DSS, PCIe and PWM.
> 
> Provides a more generic mechanism to specify the RAMINIT
> register location and START/DONE bit position and use the
> syscon/regmap framework to access the register.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  .../devicetree/bindings/net/can/c_can.txt          |  3 +
>  drivers/net/can/c_can/c_can.h                      |  9 ++-
>  drivers/net/can/c_can/c_can_platform.c             | 93 +++++++++++++---------
>  3 files changed, 65 insertions(+), 40 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
> index 8f1ae81..917ac0e 100644
> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
> @@ -12,6 +12,9 @@ Required properties:
>  Optional properties:
>  - ti,hwmods		: Must be "d_can<n>" or "c_can<n>", n being the
>  			  instance number
> +- syscon-raminit	: Handle to system control region that contains the
> +			  RAMINIT register and register offset to the RAMINIT
> +			  register.
>  
>  Note: "ti,hwmods" field is used to fetch the base address and irq
>  resources from TI, omap hwmod data base during device registration.
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index c3b2108..b5067bd 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -178,6 +178,12 @@ struct c_can_driver_data {
>  	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
>  };
>  
> +/* Out of band RAMINIT register access via syscon regmap */
> +struct c_can_raminit {
> +	struct regmap *syscon;	/* for raminit ctrl. reg. access */
> +	unsigned int reg;	/* register index within syscon */
> +};
> +
>  /* c_can private data structure */
>  struct c_can_priv {
>  	struct can_priv can;	/* must be the first member */
> @@ -195,8 +201,7 @@ struct c_can_priv {
>  	const u16 *regs;
>  	void *priv;		/* for board-specific data */
>  	enum c_can_dev_id type;
> -	u32 __iomem *raminit_ctrlreg;
> -	int instance;
> +	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
>  	void (*raminit) (const struct c_can_priv *priv, bool enable);
>  	u32 comm_rcv_high;
>  	u32 rxmasked;
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index 11946e8..d0ce439 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -32,14 +32,13 @@
>  #include <linux/clk.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>  
>  #include <linux/can/dev.h>
>  
>  #include "c_can.h"
>  
> -#define CAN_RAMINIT_START_MASK(i)	(0x001 << (i))
> -#define CAN_RAMINIT_DONE_MASK(i)	(0x100 << (i))
> -#define CAN_RAMINIT_ALL_MASK(i)		(0x101 << (i))
>  #define DCAN_RAM_INIT_BIT		(1 << 3)
>  static DEFINE_SPINLOCK(raminit_lock);
>  /*
> @@ -72,47 +71,61 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
>  	writew(val, priv->base + 2 * priv->regs[index]);
>  }
>  
> -static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
> -				  u32 val)
> +static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
> +					 u32 mask, u32 val)
>  {
>  	int timeout = 0;
> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
> +	u32 ctrl;
> +
>  	/* We look only at the bits of our instance. */
>  	val &= mask;
> -	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
> +	do {
>  		udelay(1);
>  		timeout++;
>  
> +		regmap_read(raminit->syscon, raminit->reg, &ctrl);
>  		if (timeout == 1000) {
>  			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
>  			break;
>  		}
> -	}
> +	} while ((ctrl & mask) != val);
>  }
>  
> -static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
> +static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
>  {
> -	u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
> +	u32 mask;
>  	u32 ctrl;
> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
> +	u8 start_bit, done_bit;
> +
> +	start_bit = priv->drvdata->raminit_start_bit;
> +	done_bit = priv->drvdata->raminit_done_bit;
>  
>  	spin_lock(&raminit_lock);
>  
> -	ctrl = readl(priv->raminit_ctrlreg);
> +	mask = 1 << start_bit | 1 << done_bit;
> +	regmap_read(raminit->syscon, raminit->reg, &ctrl);
> +
>  	/* We clear the done and start bit first. The start bit is
>  	 * looking at the 0 -> transition, but is not self clearing;
>  	 * And we clear the init done bit as well.
> +	 * NOTE: DONE must be written with 1 to clear it.
>  	 */
> -	ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
> -	ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
> -	writel(ctrl, priv->raminit_ctrlreg);
> -	ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
> -	c_can_hw_raminit_wait_ti(priv, mask, ctrl);
> +	ctrl &= ~(1 << start_bit);
> +	ctrl |= 1 << done_bit;
> +	regmap_write(raminit->syscon, raminit->reg, ctrl);

Thanks to Tomi for pointing out.

I need to use regmap_update_bits() instead of regmap_write() for atomic modification,
as this register needs to be shared between multiple drivers in case of DRA7 SoC.

cheers,
-roger

> +
> +	ctrl &= ~(1 << done_bit);
> +	c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>  
>  	if (enable) {
>  		/* Set start bit and wait for the done bit. */
> -		ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
> -		writel(ctrl, priv->raminit_ctrlreg);
> -		ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
> -		c_can_hw_raminit_wait_ti(priv, mask, ctrl);
> +		ctrl |= 1 << start_bit;
> +		regmap_write(raminit->syscon, raminit->reg, ctrl);
> +
> +		ctrl |= 1 << done_bit;
> +		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>  	}
>  	spin_unlock(&raminit_lock);
>  }
> @@ -206,10 +219,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	struct net_device *dev;
>  	struct c_can_priv *priv;
>  	const struct of_device_id *match;
> -	struct resource *mem, *res;
> +	struct resource *mem;
>  	int irq;
>  	struct clk *clk;
>  	const struct c_can_driver_data *drvdata;
> +	struct device_node *np = pdev->dev.of_node;
>  
>  	match = of_match_device(c_can_of_table, &pdev->dev);
>  	if (match) {
> @@ -279,27 +293,30 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  		priv->read_reg32 = d_can_plat_read_reg32;
>  		priv->write_reg32 = d_can_plat_write_reg32;
>  
> -		if (pdev->dev.of_node)
> -			priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
> -		else
> -			priv->instance = pdev->id;
> -
> -		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> -		/* Not all D_CAN modules have a separate register for the D_CAN
> -		 * RAM initialization. Use default RAM init bit in D_CAN module
> -		 * if not specified in DT.
> +		/* Check if we need custom RAMINIT via syscon. Mostly for TI
> +		 * platforms. Only supported with DT boot.
>  		 */
> -		if (!res) {
> +		if (np && of_property_read_bool(np, "syscon-raminit")) {
> +			ret = -EINVAL;
> +			priv->raminit_sys.syscon = syscon_regmap_lookup_by_phandle(np,
> +					"syscon-raminit");
> +			if (IS_ERR(priv->raminit_sys.syscon)) {
> +				dev_err(&pdev->dev,
> +					"couldn't get syscon regmap for RAMINIT reg.\n");
> +				goto exit_free_device;
> +			}
> +
> +			if (of_property_read_u32_index(np, "syscon-raminit", 1,
> +						       &priv->raminit_sys.reg)) {
> +				dev_err(&pdev->dev,
> +					"couldn't get the RAMINIT reg. offset!\n");
> +				goto exit_free_device;
> +			}
> +
> +			priv->raminit = c_can_hw_raminit_syscon;
> +		} else {
>  			priv->raminit = c_can_hw_raminit;
> -			break;
>  		}
> -
> -		priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
> -						     resource_size(res));
> -		if (!priv->raminit_ctrlreg || priv->instance < 0)
> -			dev_info(&pdev->dev, "control memory is not used for raminit\n");
> -		else
> -			priv->raminit = c_can_hw_raminit_ti;
>  		break;
>  	default:
>  		ret = -EINVAL;
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
@ 2014-11-05 11:37     ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 11:37 UTC (permalink / raw)
  To: wg, mkl, Tomi Valkeinen
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

On 11/04/2014 12:20 PM, Roger Quadros wrote:
> Some TI SoCs like DRA7 have a RAMINIT register specification
> different from the other AMxx SoCs and as expected by the
> existing driver.
> 
> To add more insanity, this register is shared with other
> IPs like DSS, PCIe and PWM.
> 
> Provides a more generic mechanism to specify the RAMINIT
> register location and START/DONE bit position and use the
> syscon/regmap framework to access the register.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  .../devicetree/bindings/net/can/c_can.txt          |  3 +
>  drivers/net/can/c_can/c_can.h                      |  9 ++-
>  drivers/net/can/c_can/c_can_platform.c             | 93 +++++++++++++---------
>  3 files changed, 65 insertions(+), 40 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
> index 8f1ae81..917ac0e 100644
> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
> @@ -12,6 +12,9 @@ Required properties:
>  Optional properties:
>  - ti,hwmods		: Must be "d_can<n>" or "c_can<n>", n being the
>  			  instance number
> +- syscon-raminit	: Handle to system control region that contains the
> +			  RAMINIT register and register offset to the RAMINIT
> +			  register.
>  
>  Note: "ti,hwmods" field is used to fetch the base address and irq
>  resources from TI, omap hwmod data base during device registration.
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index c3b2108..b5067bd 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -178,6 +178,12 @@ struct c_can_driver_data {
>  	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
>  };
>  
> +/* Out of band RAMINIT register access via syscon regmap */
> +struct c_can_raminit {
> +	struct regmap *syscon;	/* for raminit ctrl. reg. access */
> +	unsigned int reg;	/* register index within syscon */
> +};
> +
>  /* c_can private data structure */
>  struct c_can_priv {
>  	struct can_priv can;	/* must be the first member */
> @@ -195,8 +201,7 @@ struct c_can_priv {
>  	const u16 *regs;
>  	void *priv;		/* for board-specific data */
>  	enum c_can_dev_id type;
> -	u32 __iomem *raminit_ctrlreg;
> -	int instance;
> +	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
>  	void (*raminit) (const struct c_can_priv *priv, bool enable);
>  	u32 comm_rcv_high;
>  	u32 rxmasked;
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index 11946e8..d0ce439 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -32,14 +32,13 @@
>  #include <linux/clk.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>  
>  #include <linux/can/dev.h>
>  
>  #include "c_can.h"
>  
> -#define CAN_RAMINIT_START_MASK(i)	(0x001 << (i))
> -#define CAN_RAMINIT_DONE_MASK(i)	(0x100 << (i))
> -#define CAN_RAMINIT_ALL_MASK(i)		(0x101 << (i))
>  #define DCAN_RAM_INIT_BIT		(1 << 3)
>  static DEFINE_SPINLOCK(raminit_lock);
>  /*
> @@ -72,47 +71,61 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
>  	writew(val, priv->base + 2 * priv->regs[index]);
>  }
>  
> -static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
> -				  u32 val)
> +static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
> +					 u32 mask, u32 val)
>  {
>  	int timeout = 0;
> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
> +	u32 ctrl;
> +
>  	/* We look only at the bits of our instance. */
>  	val &= mask;
> -	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
> +	do {
>  		udelay(1);
>  		timeout++;
>  
> +		regmap_read(raminit->syscon, raminit->reg, &ctrl);
>  		if (timeout == 1000) {
>  			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
>  			break;
>  		}
> -	}
> +	} while ((ctrl & mask) != val);
>  }
>  
> -static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
> +static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
>  {
> -	u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
> +	u32 mask;
>  	u32 ctrl;
> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
> +	u8 start_bit, done_bit;
> +
> +	start_bit = priv->drvdata->raminit_start_bit;
> +	done_bit = priv->drvdata->raminit_done_bit;
>  
>  	spin_lock(&raminit_lock);
>  
> -	ctrl = readl(priv->raminit_ctrlreg);
> +	mask = 1 << start_bit | 1 << done_bit;
> +	regmap_read(raminit->syscon, raminit->reg, &ctrl);
> +
>  	/* We clear the done and start bit first. The start bit is
>  	 * looking at the 0 -> transition, but is not self clearing;
>  	 * And we clear the init done bit as well.
> +	 * NOTE: DONE must be written with 1 to clear it.
>  	 */
> -	ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
> -	ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
> -	writel(ctrl, priv->raminit_ctrlreg);
> -	ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
> -	c_can_hw_raminit_wait_ti(priv, mask, ctrl);
> +	ctrl &= ~(1 << start_bit);
> +	ctrl |= 1 << done_bit;
> +	regmap_write(raminit->syscon, raminit->reg, ctrl);

Thanks to Tomi for pointing out.

I need to use regmap_update_bits() instead of regmap_write() for atomic modification,
as this register needs to be shared between multiple drivers in case of DRA7 SoC.

cheers,
-roger

> +
> +	ctrl &= ~(1 << done_bit);
> +	c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>  
>  	if (enable) {
>  		/* Set start bit and wait for the done bit. */
> -		ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
> -		writel(ctrl, priv->raminit_ctrlreg);
> -		ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
> -		c_can_hw_raminit_wait_ti(priv, mask, ctrl);
> +		ctrl |= 1 << start_bit;
> +		regmap_write(raminit->syscon, raminit->reg, ctrl);
> +
> +		ctrl |= 1 << done_bit;
> +		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>  	}
>  	spin_unlock(&raminit_lock);
>  }
> @@ -206,10 +219,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	struct net_device *dev;
>  	struct c_can_priv *priv;
>  	const struct of_device_id *match;
> -	struct resource *mem, *res;
> +	struct resource *mem;
>  	int irq;
>  	struct clk *clk;
>  	const struct c_can_driver_data *drvdata;
> +	struct device_node *np = pdev->dev.of_node;
>  
>  	match = of_match_device(c_can_of_table, &pdev->dev);
>  	if (match) {
> @@ -279,27 +293,30 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  		priv->read_reg32 = d_can_plat_read_reg32;
>  		priv->write_reg32 = d_can_plat_write_reg32;
>  
> -		if (pdev->dev.of_node)
> -			priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
> -		else
> -			priv->instance = pdev->id;
> -
> -		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> -		/* Not all D_CAN modules have a separate register for the D_CAN
> -		 * RAM initialization. Use default RAM init bit in D_CAN module
> -		 * if not specified in DT.
> +		/* Check if we need custom RAMINIT via syscon. Mostly for TI
> +		 * platforms. Only supported with DT boot.
>  		 */
> -		if (!res) {
> +		if (np && of_property_read_bool(np, "syscon-raminit")) {
> +			ret = -EINVAL;
> +			priv->raminit_sys.syscon = syscon_regmap_lookup_by_phandle(np,
> +					"syscon-raminit");
> +			if (IS_ERR(priv->raminit_sys.syscon)) {
> +				dev_err(&pdev->dev,
> +					"couldn't get syscon regmap for RAMINIT reg.\n");
> +				goto exit_free_device;
> +			}
> +
> +			if (of_property_read_u32_index(np, "syscon-raminit", 1,
> +						       &priv->raminit_sys.reg)) {
> +				dev_err(&pdev->dev,
> +					"couldn't get the RAMINIT reg. offset!\n");
> +				goto exit_free_device;
> +			}
> +
> +			priv->raminit = c_can_hw_raminit_syscon;
> +		} else {
>  			priv->raminit = c_can_hw_raminit;
> -			break;
>  		}
> -
> -		priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
> -						     resource_size(res));
> -		if (!priv->raminit_ctrlreg || priv->instance < 0)
> -			dev_info(&pdev->dev, "control memory is not used for raminit\n");
> -		else
> -			priv->raminit = c_can_hw_raminit_ti;
>  		break;
>  	default:
>  		ret = -EINVAL;
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
  2014-11-04 10:20   ` Roger Quadros
@ 2014-11-05 13:24     ` Marc Kleine-Budde
  -1 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:24 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]

On 11/04/2014 11:20 AM, Roger Quadros wrote:
> DRA7 CAN IP suffers from a problem which causes it to be prevented
> from fully turning OFF (i.e. stuck in transition) if the module was
> disabled while there was traffic on the CAN_RX line.
> 
> To work around this issue we select the SLEEP pin state by default
> on probe and use the DEFAULT pin state on CAN up and back to the
> SLEEP pin state on CAN down.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
>  drivers/net/can/c_can/c_can.h          |  1 +
>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>  3 files changed, 41 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 8e78bb4..4dfc3ce 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -35,6 +35,7 @@
>  #include <linux/list.h>
>  #include <linux/io.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
> +	/* activate pins */
> +	if (!IS_ERR(priv->pinctrl)) {
> +		struct pinctrl_state *s;
> +
> +		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(priv->pinctrl, s);
> +	}

Can you factor this into a common function? Which is used like this:

c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)

Otherwise looks god.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
@ 2014-11-05 13:24     ` Marc Kleine-Budde
  0 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:24 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]

On 11/04/2014 11:20 AM, Roger Quadros wrote:
> DRA7 CAN IP suffers from a problem which causes it to be prevented
> from fully turning OFF (i.e. stuck in transition) if the module was
> disabled while there was traffic on the CAN_RX line.
> 
> To work around this issue we select the SLEEP pin state by default
> on probe and use the DEFAULT pin state on CAN up and back to the
> SLEEP pin state on CAN down.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
>  drivers/net/can/c_can/c_can.h          |  1 +
>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>  3 files changed, 41 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 8e78bb4..4dfc3ce 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -35,6 +35,7 @@
>  #include <linux/list.h>
>  #include <linux/io.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
> +	/* activate pins */
> +	if (!IS_ERR(priv->pinctrl)) {
> +		struct pinctrl_state *s;
> +
> +		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(priv->pinctrl, s);
> +	}

Can you factor this into a common function? Which is used like this:

c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)

Otherwise looks god.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
  2014-11-04 10:21   ` Roger Quadros
@ 2014-11-05 13:30     ` Marc Kleine-Budde
  -1 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:30 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

[-- Attachment #1: Type: text/plain, Size: 3090 bytes --]

On 11/04/2014 11:21 AM, Roger Quadros wrote:
> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
> register data for both.

My understanding of the discussion with Wolfram was:
- We should put the number of the Interface into to DT as a regmap
  parameter.
- We put the method how to find the correct bits into the DT, via the
  compatible.

So for both CAN instances on the DRA7 we have a single compatible
"ti,dra7-d_can" and in the driver a mechanism that translates the number
of the instance into the needed bit offsets, e.g. via two arrays.

Same comments for patch 8/8.

Marc

> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
>  drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
> index 917ac0e..746cc07 100644
> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
>  Required properties:
>  - compatible		: Should be "bosch,c_can" for C_CAN controllers and
>  			  "bosch,d_can" for D_CAN controllers.
> +			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
>  - reg			: physical base address and size of the C_CAN/D_CAN
>  			  registers map
>  - interrupts		: property with a value describing the interrupt
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index d058820..dc618ce 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
>  	.id = BOSCH_D_CAN,
>  };
>  
> +static struct c_can_driver_data dra7_dcan1_drvdata = {
> +	.id = BOSCH_D_CAN,
> +	.raminit_start_bit = 3,
> +	.raminit_done_bit = 1,
> +	.raminit_pulse = true,
> +};
> +
> +static struct c_can_driver_data dra7_dcan2_drvdata = {
> +	.id = BOSCH_D_CAN,
> +	.raminit_start_bit = 5,
> +	.raminit_done_bit = 2,
> +	.raminit_pulse = true,
> +};
> +
>  static struct platform_device_id c_can_id_table[] = {
>  	{
>  		.name = KBUILD_MODNAME,
> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
>  static const struct of_device_id c_can_of_table[] = {
>  	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
>  	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
> +	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
> +	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, c_can_of_table);
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
@ 2014-11-05 13:30     ` Marc Kleine-Budde
  0 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:30 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

[-- Attachment #1: Type: text/plain, Size: 3090 bytes --]

On 11/04/2014 11:21 AM, Roger Quadros wrote:
> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
> register data for both.

My understanding of the discussion with Wolfram was:
- We should put the number of the Interface into to DT as a regmap
  parameter.
- We put the method how to find the correct bits into the DT, via the
  compatible.

So for both CAN instances on the DRA7 we have a single compatible
"ti,dra7-d_can" and in the driver a mechanism that translates the number
of the instance into the needed bit offsets, e.g. via two arrays.

Same comments for patch 8/8.

Marc

> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
>  drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
> index 917ac0e..746cc07 100644
> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
>  Required properties:
>  - compatible		: Should be "bosch,c_can" for C_CAN controllers and
>  			  "bosch,d_can" for D_CAN controllers.
> +			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
>  - reg			: physical base address and size of the C_CAN/D_CAN
>  			  registers map
>  - interrupts		: property with a value describing the interrupt
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index d058820..dc618ce 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
>  	.id = BOSCH_D_CAN,
>  };
>  
> +static struct c_can_driver_data dra7_dcan1_drvdata = {
> +	.id = BOSCH_D_CAN,
> +	.raminit_start_bit = 3,
> +	.raminit_done_bit = 1,
> +	.raminit_pulse = true,
> +};
> +
> +static struct c_can_driver_data dra7_dcan2_drvdata = {
> +	.id = BOSCH_D_CAN,
> +	.raminit_start_bit = 5,
> +	.raminit_done_bit = 2,
> +	.raminit_pulse = true,
> +};
> +
>  static struct platform_device_id c_can_id_table[] = {
>  	{
>  		.name = KBUILD_MODNAME,
> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
>  static const struct of_device_id c_can_of_table[] = {
>  	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
>  	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
> +	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
> +	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, c_can_of_table);
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
  2014-11-05 13:24     ` Marc Kleine-Budde
@ 2014-11-05 13:33       ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 13:33 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

On 11/05/2014 03:24 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:20 AM, Roger Quadros wrote:
>> DRA7 CAN IP suffers from a problem which causes it to be prevented
>> from fully turning OFF (i.e. stuck in transition) if the module was
>> disabled while there was traffic on the CAN_RX line.
>>
>> To work around this issue we select the SLEEP pin state by default
>> on probe and use the DEFAULT pin state on CAN up and back to the
>> SLEEP pin state on CAN down.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
>>  drivers/net/can/c_can/c_can.h          |  1 +
>>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>>  3 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>> index 8e78bb4..4dfc3ce 100644
>> --- a/drivers/net/can/c_can/c_can.c
>> +++ b/drivers/net/can/c_can/c_can.c
>> @@ -35,6 +35,7 @@
>>  #include <linux/list.h>
>>  #include <linux/io.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/pinctrl/consumer.h>
>>  
>>  #include <linux/can.h>
>>  #include <linux/can/dev.h>
>> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>>  
>>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>  
>> +	/* activate pins */
>> +	if (!IS_ERR(priv->pinctrl)) {
>> +		struct pinctrl_state *s;
>> +
>> +		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
>> +		if (!IS_ERR(s))
>> +			pinctrl_select_state(priv->pinctrl, s);
>> +	}
> 
> Can you factor this into a common function? Which is used like this:
> 
> c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)
> 
> Otherwise looks god.

OK.

cheers,
-roger

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
@ 2014-11-05 13:33       ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 13:33 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

On 11/05/2014 03:24 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:20 AM, Roger Quadros wrote:
>> DRA7 CAN IP suffers from a problem which causes it to be prevented
>> from fully turning OFF (i.e. stuck in transition) if the module was
>> disabled while there was traffic on the CAN_RX line.
>>
>> To work around this issue we select the SLEEP pin state by default
>> on probe and use the DEFAULT pin state on CAN up and back to the
>> SLEEP pin state on CAN down.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/net/can/c_can/c_can.c          | 20 ++++++++++++++++++++
>>  drivers/net/can/c_can/c_can.h          |  1 +
>>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>>  3 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>> index 8e78bb4..4dfc3ce 100644
>> --- a/drivers/net/can/c_can/c_can.c
>> +++ b/drivers/net/can/c_can/c_can.c
>> @@ -35,6 +35,7 @@
>>  #include <linux/list.h>
>>  #include <linux/io.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/pinctrl/consumer.h>
>>  
>>  #include <linux/can.h>
>>  #include <linux/can/dev.h>
>> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>>  
>>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>  
>> +	/* activate pins */
>> +	if (!IS_ERR(priv->pinctrl)) {
>> +		struct pinctrl_state *s;
>> +
>> +		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
>> +		if (!IS_ERR(s))
>> +			pinctrl_select_state(priv->pinctrl, s);
>> +	}
> 
> Can you factor this into a common function? Which is used like this:
> 
> c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)
> 
> Otherwise looks god.

OK.

cheers,
-roger

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
  2014-11-05 13:30     ` Marc Kleine-Budde
@ 2014-11-05 13:36       ` Roger Quadros
  -1 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 13:36 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

On 11/05/2014 03:30 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:21 AM, Roger Quadros wrote:
>> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
>> register data for both.
> 
> My understanding of the discussion with Wolfram was:
> - We should put the number of the Interface into to DT as a regmap
>   parameter.
> - We put the method how to find the correct bits into the DT, via the
>   compatible.
> 
> So for both CAN instances on the DRA7 we have a single compatible
> "ti,dra7-d_can" and in the driver a mechanism that translates the number
> of the instance into the needed bit offsets, e.g. via two arrays.
> 

OK. I'll revise this series.

The new syscon-raminit property will be like
syscon-raminit = <syscon_phandle raminit-reg-offset dcan-interface-number>;

cheers,
-roger

> Same comments for patch 8/8.
> 
> Marc
> 
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
>>  drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
>>  2 files changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
>> index 917ac0e..746cc07 100644
>> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
>> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
>> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
>>  Required properties:
>>  - compatible		: Should be "bosch,c_can" for C_CAN controllers and
>>  			  "bosch,d_can" for D_CAN controllers.
>> +			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
>>  - reg			: physical base address and size of the C_CAN/D_CAN
>>  			  registers map
>>  - interrupts		: property with a value describing the interrupt
>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>> index d058820..dc618ce 100644
>> --- a/drivers/net/can/c_can/c_can_platform.c
>> +++ b/drivers/net/can/c_can/c_can_platform.c
>> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
>>  	.id = BOSCH_D_CAN,
>>  };
>>  
>> +static struct c_can_driver_data dra7_dcan1_drvdata = {
>> +	.id = BOSCH_D_CAN,
>> +	.raminit_start_bit = 3,
>> +	.raminit_done_bit = 1,
>> +	.raminit_pulse = true,
>> +};
>> +
>> +static struct c_can_driver_data dra7_dcan2_drvdata = {
>> +	.id = BOSCH_D_CAN,
>> +	.raminit_start_bit = 5,
>> +	.raminit_done_bit = 2,
>> +	.raminit_pulse = true,
>> +};
>> +
>>  static struct platform_device_id c_can_id_table[] = {
>>  	{
>>  		.name = KBUILD_MODNAME,
>> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
>>  static const struct of_device_id c_can_of_table[] = {
>>  	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
>>  	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
>> +	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
>> +	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
>>  	{ /* sentinel */ },
>>  };
>>  MODULE_DEVICE_TABLE(of, c_can_of_table);
>>
> 
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
@ 2014-11-05 13:36       ` Roger Quadros
  0 siblings, 0 replies; 30+ messages in thread
From: Roger Quadros @ 2014-11-05 13:36 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

On 11/05/2014 03:30 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:21 AM, Roger Quadros wrote:
>> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
>> register data for both.
> 
> My understanding of the discussion with Wolfram was:
> - We should put the number of the Interface into to DT as a regmap
>   parameter.
> - We put the method how to find the correct bits into the DT, via the
>   compatible.
> 
> So for both CAN instances on the DRA7 we have a single compatible
> "ti,dra7-d_can" and in the driver a mechanism that translates the number
> of the instance into the needed bit offsets, e.g. via two arrays.
> 

OK. I'll revise this series.

The new syscon-raminit property will be like
syscon-raminit = <syscon_phandle raminit-reg-offset dcan-interface-number>;

cheers,
-roger

> Same comments for patch 8/8.
> 
> Marc
> 
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  Documentation/devicetree/bindings/net/can/c_can.txt |  1 +
>>  drivers/net/can/c_can/c_can_platform.c              | 16 ++++++++++++++++
>>  2 files changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
>> index 917ac0e..746cc07 100644
>> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
>> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
>> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
>>  Required properties:
>>  - compatible		: Should be "bosch,c_can" for C_CAN controllers and
>>  			  "bosch,d_can" for D_CAN controllers.
>> +			  Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
>>  - reg			: physical base address and size of the C_CAN/D_CAN
>>  			  registers map
>>  - interrupts		: property with a value describing the interrupt
>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>> index d058820..dc618ce 100644
>> --- a/drivers/net/can/c_can/c_can_platform.c
>> +++ b/drivers/net/can/c_can/c_can_platform.c
>> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
>>  	.id = BOSCH_D_CAN,
>>  };
>>  
>> +static struct c_can_driver_data dra7_dcan1_drvdata = {
>> +	.id = BOSCH_D_CAN,
>> +	.raminit_start_bit = 3,
>> +	.raminit_done_bit = 1,
>> +	.raminit_pulse = true,
>> +};
>> +
>> +static struct c_can_driver_data dra7_dcan2_drvdata = {
>> +	.id = BOSCH_D_CAN,
>> +	.raminit_start_bit = 5,
>> +	.raminit_done_bit = 2,
>> +	.raminit_pulse = true,
>> +};
>> +
>>  static struct platform_device_id c_can_id_table[] = {
>>  	{
>>  		.name = KBUILD_MODNAME,
>> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
>>  static const struct of_device_id c_can_of_table[] = {
>>  	{ .compatible = "bosch,c_can", .data = &c_can_drvdata },
>>  	{ .compatible = "bosch,d_can", .data = &d_can_drvdata },
>> +	{ .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
>> +	{ .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
>>  	{ /* sentinel */ },
>>  };
>>  MODULE_DEVICE_TABLE(of, c_can_of_table);
>>
> 
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
  2014-11-05 13:36       ` Roger Quadros
@ 2014-11-05 13:43         ` Marc Kleine-Budde
  -1 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:43 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar

[-- Attachment #1: Type: text/plain, Size: 1175 bytes --]

On 11/05/2014 02:36 PM, Roger Quadros wrote:
> On 11/05/2014 03:30 PM, Marc Kleine-Budde wrote:
>> On 11/04/2014 11:21 AM, Roger Quadros wrote:
>>> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
>>> register data for both.
>>
>> My understanding of the discussion with Wolfram was:
>> - We should put the number of the Interface into to DT as a regmap
>>   parameter.
>> - We put the method how to find the correct bits into the DT, via the
>>   compatible.
>>
>> So for both CAN instances on the DRA7 we have a single compatible
>> "ti,dra7-d_can" and in the driver a mechanism that translates the number
>> of the instance into the needed bit offsets, e.g. via two arrays.
>>
> 
> OK. I'll revise this series.
> 
> The new syscon-raminit property will be like
> syscon-raminit = <syscon_phandle raminit-reg-offset dcan-interface-number>;

Yes. Wolfram?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
@ 2014-11-05 13:43         ` Marc Kleine-Budde
  0 siblings, 0 replies; 30+ messages in thread
From: Marc Kleine-Budde @ 2014-11-05 13:43 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev

[-- Attachment #1: Type: text/plain, Size: 1175 bytes --]

On 11/05/2014 02:36 PM, Roger Quadros wrote:
> On 11/05/2014 03:30 PM, Marc Kleine-Budde wrote:
>> On 11/04/2014 11:21 AM, Roger Quadros wrote:
>>> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
>>> register data for both.
>>
>> My understanding of the discussion with Wolfram was:
>> - We should put the number of the Interface into to DT as a regmap
>>   parameter.
>> - We put the method how to find the correct bits into the DT, via the
>>   compatible.
>>
>> So for both CAN instances on the DRA7 we have a single compatible
>> "ti,dra7-d_can" and in the driver a mechanism that translates the number
>> of the instance into the needed bit offsets, e.g. via two arrays.
>>
> 
> OK. I'll revise this series.
> 
> The new syscon-raminit property will be like
> syscon-raminit = <syscon_phandle raminit-reg-offset dcan-interface-number>;

Yes. Wolfram?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2014-11-05 13:43 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-04 10:20 [PATCH v3 0/8] net: can: Use syscon regmap for TI specific RAMINIT register Roger Quadros
2014-11-04 10:20 ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 1/8] net: can: c_can: Add timeout to c_can_hw_raminit_ti() Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 2/8] net: can: c_can: Introduce c_can_driver_data structure Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 3/8] net: can: c_can: Add RAMINIT register information to driver data Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-05 11:37   ` Roger Quadros
2014-11-05 11:37     ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 5/8] net: can: c_can: Add support for START pulse in RAMINIT sequence Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-04 10:20 ` [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down Roger Quadros
2014-11-04 10:20   ` Roger Quadros
2014-11-05 13:24   ` Marc Kleine-Budde
2014-11-05 13:24     ` Marc Kleine-Budde
2014-11-05 13:33     ` Roger Quadros
2014-11-05 13:33       ` Roger Quadros
2014-11-04 10:21 ` [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN Roger Quadros
2014-11-04 10:21   ` Roger Quadros
2014-11-05 13:30   ` Marc Kleine-Budde
2014-11-05 13:30     ` Marc Kleine-Budde
2014-11-05 13:36     ` Roger Quadros
2014-11-05 13:36       ` Roger Quadros
2014-11-05 13:43       ` Marc Kleine-Budde
2014-11-05 13:43         ` Marc Kleine-Budde
2014-11-04 10:21 ` [PATCH v3 8/8] net: can: c_can: Add support for TI am3352 DCAN Roger Quadros
2014-11-04 10:21   ` Roger Quadros

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.