aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorAnilKumar Ch <anilkumar@ti.com>2012-11-21 00:44:10 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2012-11-27 03:49:31 -0500
commit52cde85acc23f61b09dd0376c61eb891125c6990 (patch)
treeb44c83102549a37b8bd4abae7ace6989e1e6f0c5 /drivers/net/can
parent03f52a0a554210d5049eeed9f1bb29047dc807cb (diff)
can: c_can: Add d_can raminit support
Add D_CAN raminit support to C_CAN driver to enable D_CAN RAM, which holds all the message objects during transmission or receiving of data. This initialization/de-initialization should be done in synchronous with D_CAN clock. In case of AM335X-EVM (current user of D_CAN driver) message RAM is controlled through control module register for both instances. So control module register details is required to initialization or de-initialization of message RAM according to instance number. Control module memory resource is obtained from D_CAN dt node and instance number obtained from device tree aliases node. This patch was tested on AM335x-EVM along with pinctrl data addition patch, d_can dt aliases addition and control module data addition. pinctrl data addition is not added to am335x-evm.dts (only supports CPLD profile#0) because d_can1 is supported under CPLD profile#1. Signed-off-by: AnilKumar Ch <anilkumar@ti.com> [mkl: fix instance for non DT in probe, cleaned up raminit] Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/c_can/c_can.c12
-rw-r--r--drivers/net/can/c_can/c_can.h3
-rw-r--r--drivers/net/can/c_can/c_can_platform.c28
3 files changed, 42 insertions, 1 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index e5180dfddba5..5233b8f58d77 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -233,6 +233,12 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
233 pm_runtime_put_sync(priv->device); 233 pm_runtime_put_sync(priv->device);
234} 234}
235 235
236static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
237{
238 if (priv->raminit)
239 priv->raminit(priv, enable);
240}
241
236static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) 242static inline int get_tx_next_msg_obj(const struct c_can_priv *priv)
237{ 243{
238 return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + 244 return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) +
@@ -1090,6 +1096,7 @@ static int c_can_open(struct net_device *dev)
1090 struct c_can_priv *priv = netdev_priv(dev); 1096 struct c_can_priv *priv = netdev_priv(dev);
1091 1097
1092 c_can_pm_runtime_get_sync(priv); 1098 c_can_pm_runtime_get_sync(priv);
1099 c_can_reset_ram(priv, true);
1093 1100
1094 /* open the can device */ 1101 /* open the can device */
1095 err = open_candev(dev); 1102 err = open_candev(dev);
@@ -1118,6 +1125,7 @@ static int c_can_open(struct net_device *dev)
1118exit_irq_fail: 1125exit_irq_fail:
1119 close_candev(dev); 1126 close_candev(dev);
1120exit_open_fail: 1127exit_open_fail:
1128 c_can_reset_ram(priv, false);
1121 c_can_pm_runtime_put_sync(priv); 1129 c_can_pm_runtime_put_sync(priv);
1122 return err; 1130 return err;
1123} 1131}
@@ -1131,6 +1139,8 @@ static int c_can_close(struct net_device *dev)
1131 c_can_stop(dev); 1139 c_can_stop(dev);
1132 free_irq(dev->irq, dev); 1140 free_irq(dev->irq, dev);
1133 close_candev(dev); 1141 close_candev(dev);
1142
1143 c_can_reset_ram(priv, false);
1134 c_can_pm_runtime_put_sync(priv); 1144 c_can_pm_runtime_put_sync(priv);
1135 1145
1136 return 0; 1146 return 0;
@@ -1188,6 +1198,7 @@ int c_can_power_down(struct net_device *dev)
1188 1198
1189 c_can_stop(dev); 1199 c_can_stop(dev);
1190 1200
1201 c_can_reset_ram(priv, false);
1191 c_can_pm_runtime_put_sync(priv); 1202 c_can_pm_runtime_put_sync(priv);
1192 1203
1193 return 0; 1204 return 0;
@@ -1206,6 +1217,7 @@ int c_can_power_up(struct net_device *dev)
1206 WARN_ON(priv->type != BOSCH_D_CAN); 1217 WARN_ON(priv->type != BOSCH_D_CAN);
1207 1218
1208 c_can_pm_runtime_get_sync(priv); 1219 c_can_pm_runtime_get_sync(priv);
1220 c_can_reset_ram(priv, true);
1209 1221
1210 /* Clear PDR and INIT bits */ 1222 /* Clear PDR and INIT bits */
1211 val = priv->read_reg(priv, C_CAN_CTRL_EX_REG); 1223 val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index e5ed41dafa1b..d2e1c21b143f 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -169,6 +169,9 @@ struct c_can_priv {
169 void *priv; /* for board-specific data */ 169 void *priv; /* for board-specific data */
170 u16 irqstatus; 170 u16 irqstatus;
171 enum c_can_dev_id type; 171 enum c_can_dev_id type;
172 u32 __iomem *raminit_ctrlreg;
173 unsigned int instance;
174 void (*raminit) (const struct c_can_priv *priv, bool enable);
172}; 175};
173 176
174struct net_device *alloc_c_can_dev(void); 177struct 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 ee1416132aba..75c3f472a023 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -38,6 +38,8 @@
38 38
39#include "c_can.h" 39#include "c_can.h"
40 40
41#define CAN_RAMINIT_START_MASK(i) (1 << (i))
42
41/* 43/*
42 * 16-bit c_can registers can be arranged differently in the memory 44 * 16-bit c_can registers can be arranged differently in the memory
43 * architecture of different implementations. For example: 16-bit 45 * architecture of different implementations. For example: 16-bit
@@ -68,6 +70,18 @@ static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv,
68 writew(val, priv->base + 2 * priv->regs[index]); 70 writew(val, priv->base + 2 * priv->regs[index]);
69} 71}
70 72
73static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
74{
75 u32 val;
76
77 val = readl(priv->raminit_ctrlreg);
78 if (enable)
79 val |= CAN_RAMINIT_START_MASK(priv->instance);
80 else
81 val &= ~CAN_RAMINIT_START_MASK(priv->instance);
82 writel(val, priv->raminit_ctrlreg);
83}
84
71static struct platform_device_id c_can_id_table[] = { 85static struct platform_device_id c_can_id_table[] = {
72 [BOSCH_C_CAN_PLATFORM] = { 86 [BOSCH_C_CAN_PLATFORM] = {
73 .name = KBUILD_MODNAME, 87 .name = KBUILD_MODNAME,
@@ -99,7 +113,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
99 const struct of_device_id *match; 113 const struct of_device_id *match;
100 const struct platform_device_id *id; 114 const struct platform_device_id *id;
101 struct pinctrl *pinctrl; 115 struct pinctrl *pinctrl;
102 struct resource *mem; 116 struct resource *mem, *res;
103 int irq; 117 int irq;
104 struct clk *clk; 118 struct clk *clk;
105 119
@@ -178,6 +192,18 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
178 priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; 192 priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
179 priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; 193 priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
180 priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; 194 priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
195
196 if (pdev->dev.of_node)
197 priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
198 else
199 priv->instance = pdev->id;
200
201 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
202 priv->raminit_ctrlreg = devm_request_and_ioremap(&pdev->dev, res);
203 if (!priv->raminit_ctrlreg || priv->instance < 0)
204 dev_info(&pdev->dev, "control memory is not used for raminit\n");
205 else
206 priv->raminit = c_can_hw_raminit;
181 break; 207 break;
182 default: 208 default:
183 ret = -EINVAL; 209 ret = -EINVAL;