aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/flexcan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/flexcan.c')
-rw-r--r--drivers/net/can/flexcan.c179
1 files changed, 136 insertions, 43 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index aaed97bee471..61376abdab39 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -144,6 +144,8 @@
144 144
145#define FLEXCAN_MB_CODE_MASK (0xf0ffffff) 145#define FLEXCAN_MB_CODE_MASK (0xf0ffffff)
146 146
147#define FLEXCAN_TIMEOUT_US (50)
148
147/* 149/*
148 * FLEXCAN hardware feature flags 150 * FLEXCAN hardware feature flags
149 * 151 *
@@ -235,9 +237,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
235}; 237};
236 238
237/* 239/*
238 * Abstract off the read/write for arm versus ppc. 240 * Abstract off the read/write for arm versus ppc. This
241 * assumes that PPC uses big-endian registers and everything
242 * else uses little-endian registers, independent of CPU
243 * endianess.
239 */ 244 */
240#if defined(__BIG_ENDIAN) 245#if defined(CONFIG_PPC)
241static inline u32 flexcan_read(void __iomem *addr) 246static inline u32 flexcan_read(void __iomem *addr)
242{ 247{
243 return in_be32(addr); 248 return in_be32(addr);
@@ -259,6 +264,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
259} 264}
260#endif 265#endif
261 266
267static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
268{
269 if (!priv->reg_xceiver)
270 return 0;
271
272 return regulator_enable(priv->reg_xceiver);
273}
274
275static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
276{
277 if (!priv->reg_xceiver)
278 return 0;
279
280 return regulator_disable(priv->reg_xceiver);
281}
282
262static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, 283static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
263 u32 reg_esr) 284 u32 reg_esr)
264{ 285{
@@ -266,26 +287,95 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
266 (reg_esr & FLEXCAN_ESR_ERR_BUS); 287 (reg_esr & FLEXCAN_ESR_ERR_BUS);
267} 288}
268 289
269static inline void flexcan_chip_enable(struct flexcan_priv *priv) 290static int flexcan_chip_enable(struct flexcan_priv *priv)
270{ 291{
271 struct flexcan_regs __iomem *regs = priv->base; 292 struct flexcan_regs __iomem *regs = priv->base;
293 unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
272 u32 reg; 294 u32 reg;
273 295
274 reg = flexcan_read(&regs->mcr); 296 reg = flexcan_read(&regs->mcr);
275 reg &= ~FLEXCAN_MCR_MDIS; 297 reg &= ~FLEXCAN_MCR_MDIS;
276 flexcan_write(reg, &regs->mcr); 298 flexcan_write(reg, &regs->mcr);
277 299
278 udelay(10); 300 while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
301 usleep_range(10, 20);
302
303 if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
304 return -ETIMEDOUT;
305
306 return 0;
279} 307}
280 308
281static inline void flexcan_chip_disable(struct flexcan_priv *priv) 309static int flexcan_chip_disable(struct flexcan_priv *priv)
282{ 310{
283 struct flexcan_regs __iomem *regs = priv->base; 311 struct flexcan_regs __iomem *regs = priv->base;
312 unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
284 u32 reg; 313 u32 reg;
285 314
286 reg = flexcan_read(&regs->mcr); 315 reg = flexcan_read(&regs->mcr);
287 reg |= FLEXCAN_MCR_MDIS; 316 reg |= FLEXCAN_MCR_MDIS;
288 flexcan_write(reg, &regs->mcr); 317 flexcan_write(reg, &regs->mcr);
318
319 while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
320 usleep_range(10, 20);
321
322 if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
323 return -ETIMEDOUT;
324
325 return 0;
326}
327
328static int flexcan_chip_freeze(struct flexcan_priv *priv)
329{
330 struct flexcan_regs __iomem *regs = priv->base;
331 unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
332 u32 reg;
333
334 reg = flexcan_read(&regs->mcr);
335 reg |= FLEXCAN_MCR_HALT;
336 flexcan_write(reg, &regs->mcr);
337
338 while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
339 usleep_range(100, 200);
340
341 if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
342 return -ETIMEDOUT;
343
344 return 0;
345}
346
347static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
348{
349 struct flexcan_regs __iomem *regs = priv->base;
350 unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
351 u32 reg;
352
353 reg = flexcan_read(&regs->mcr);
354 reg &= ~FLEXCAN_MCR_HALT;
355 flexcan_write(reg, &regs->mcr);
356
357 while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
358 usleep_range(10, 20);
359
360 if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
361 return -ETIMEDOUT;
362
363 return 0;
364}
365
366static int flexcan_chip_softreset(struct flexcan_priv *priv)
367{
368 struct flexcan_regs __iomem *regs = priv->base;
369 unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
370
371 flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
372 while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
373 usleep_range(10, 20);
374
375 if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
376 return -ETIMEDOUT;
377
378 return 0;
289} 379}
290 380
291static int flexcan_get_berr_counter(const struct net_device *dev, 381static int flexcan_get_berr_counter(const struct net_device *dev,
@@ -706,19 +796,14 @@ static int flexcan_chip_start(struct net_device *dev)
706 u32 reg_mcr, reg_ctrl; 796 u32 reg_mcr, reg_ctrl;
707 797
708 /* enable module */ 798 /* enable module */
709 flexcan_chip_enable(priv); 799 err = flexcan_chip_enable(priv);
800 if (err)
801 return err;
710 802
711 /* soft reset */ 803 /* soft reset */
712 flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr); 804 err = flexcan_chip_softreset(priv);
713 udelay(10); 805 if (err)
714 806 goto out_chip_disable;
715 reg_mcr = flexcan_read(&regs->mcr);
716 if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
717 netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n",
718 reg_mcr);
719 err = -ENODEV;
720 goto out;
721 }
722 807
723 flexcan_set_bittiming(dev); 808 flexcan_set_bittiming(dev);
724 809
@@ -785,16 +870,14 @@ static int flexcan_chip_start(struct net_device *dev)
785 if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) 870 if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
786 flexcan_write(0x0, &regs->rxfgmask); 871 flexcan_write(0x0, &regs->rxfgmask);
787 872
788 if (priv->reg_xceiver) { 873 err = flexcan_transceiver_enable(priv);
789 err = regulator_enable(priv->reg_xceiver); 874 if (err)
790 if (err) 875 goto out_chip_disable;
791 goto out;
792 }
793 876
794 /* synchronize with the can bus */ 877 /* synchronize with the can bus */
795 reg_mcr = flexcan_read(&regs->mcr); 878 err = flexcan_chip_unfreeze(priv);
796 reg_mcr &= ~FLEXCAN_MCR_HALT; 879 if (err)
797 flexcan_write(reg_mcr, &regs->mcr); 880 goto out_transceiver_disable;
798 881
799 priv->can.state = CAN_STATE_ERROR_ACTIVE; 882 priv->can.state = CAN_STATE_ERROR_ACTIVE;
800 883
@@ -807,7 +890,9 @@ static int flexcan_chip_start(struct net_device *dev)
807 890
808 return 0; 891 return 0;
809 892
810 out: 893 out_transceiver_disable:
894 flexcan_transceiver_disable(priv);
895 out_chip_disable:
811 flexcan_chip_disable(priv); 896 flexcan_chip_disable(priv);
812 return err; 897 return err;
813} 898}
@@ -822,18 +907,17 @@ static void flexcan_chip_stop(struct net_device *dev)
822{ 907{
823 struct flexcan_priv *priv = netdev_priv(dev); 908 struct flexcan_priv *priv = netdev_priv(dev);
824 struct flexcan_regs __iomem *regs = priv->base; 909 struct flexcan_regs __iomem *regs = priv->base;
825 u32 reg; 910
911 /* freeze + disable module */
912 flexcan_chip_freeze(priv);
913 flexcan_chip_disable(priv);
826 914
827 /* Disable all interrupts */ 915 /* Disable all interrupts */
828 flexcan_write(0, &regs->imask1); 916 flexcan_write(0, &regs->imask1);
917 flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
918 &regs->ctrl);
829 919
830 /* Disable + halt module */ 920 flexcan_transceiver_disable(priv);
831 reg = flexcan_read(&regs->mcr);
832 reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
833 flexcan_write(reg, &regs->mcr);
834
835 if (priv->reg_xceiver)
836 regulator_disable(priv->reg_xceiver);
837 priv->can.state = CAN_STATE_STOPPED; 921 priv->can.state = CAN_STATE_STOPPED;
838 922
839 return; 923 return;
@@ -863,7 +947,7 @@ static int flexcan_open(struct net_device *dev)
863 /* start chip and queuing */ 947 /* start chip and queuing */
864 err = flexcan_chip_start(dev); 948 err = flexcan_chip_start(dev);
865 if (err) 949 if (err)
866 goto out_close; 950 goto out_free_irq;
867 951
868 can_led_event(dev, CAN_LED_EVENT_OPEN); 952 can_led_event(dev, CAN_LED_EVENT_OPEN);
869 953
@@ -872,6 +956,8 @@ static int flexcan_open(struct net_device *dev)
872 956
873 return 0; 957 return 0;
874 958
959 out_free_irq:
960 free_irq(dev->irq, dev);
875 out_close: 961 out_close:
876 close_candev(dev); 962 close_candev(dev);
877 out_disable_per: 963 out_disable_per:
@@ -942,12 +1028,16 @@ static int register_flexcandev(struct net_device *dev)
942 goto out_disable_ipg; 1028 goto out_disable_ipg;
943 1029
944 /* select "bus clock", chip must be disabled */ 1030 /* select "bus clock", chip must be disabled */
945 flexcan_chip_disable(priv); 1031 err = flexcan_chip_disable(priv);
1032 if (err)
1033 goto out_disable_per;
946 reg = flexcan_read(&regs->ctrl); 1034 reg = flexcan_read(&regs->ctrl);
947 reg |= FLEXCAN_CTRL_CLK_SRC; 1035 reg |= FLEXCAN_CTRL_CLK_SRC;
948 flexcan_write(reg, &regs->ctrl); 1036 flexcan_write(reg, &regs->ctrl);
949 1037
950 flexcan_chip_enable(priv); 1038 err = flexcan_chip_enable(priv);
1039 if (err)
1040 goto out_chip_disable;
951 1041
952 /* set freeze, halt and activate FIFO, restrict register access */ 1042 /* set freeze, halt and activate FIFO, restrict register access */
953 reg = flexcan_read(&regs->mcr); 1043 reg = flexcan_read(&regs->mcr);
@@ -964,14 +1054,15 @@ static int register_flexcandev(struct net_device *dev)
964 if (!(reg & FLEXCAN_MCR_FEN)) { 1054 if (!(reg & FLEXCAN_MCR_FEN)) {
965 netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); 1055 netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
966 err = -ENODEV; 1056 err = -ENODEV;
967 goto out_disable_per; 1057 goto out_chip_disable;
968 } 1058 }
969 1059
970 err = register_candev(dev); 1060 err = register_candev(dev);
971 1061
972 out_disable_per:
973 /* disable core and turn off clocks */ 1062 /* disable core and turn off clocks */
1063 out_chip_disable:
974 flexcan_chip_disable(priv); 1064 flexcan_chip_disable(priv);
1065 out_disable_per:
975 clk_disable_unprepare(priv->clk_per); 1066 clk_disable_unprepare(priv->clk_per);
976 out_disable_ipg: 1067 out_disable_ipg:
977 clk_disable_unprepare(priv->clk_ipg); 1068 clk_disable_unprepare(priv->clk_ipg);
@@ -1101,9 +1192,10 @@ static int flexcan_probe(struct platform_device *pdev)
1101static int flexcan_remove(struct platform_device *pdev) 1192static int flexcan_remove(struct platform_device *pdev)
1102{ 1193{
1103 struct net_device *dev = platform_get_drvdata(pdev); 1194 struct net_device *dev = platform_get_drvdata(pdev);
1195 struct flexcan_priv *priv = netdev_priv(dev);
1104 1196
1105 unregister_flexcandev(dev); 1197 unregister_flexcandev(dev);
1106 1198 netif_napi_del(&priv->napi);
1107 free_candev(dev); 1199 free_candev(dev);
1108 1200
1109 return 0; 1201 return 0;
@@ -1114,8 +1206,11 @@ static int flexcan_suspend(struct device *device)
1114{ 1206{
1115 struct net_device *dev = dev_get_drvdata(device); 1207 struct net_device *dev = dev_get_drvdata(device);
1116 struct flexcan_priv *priv = netdev_priv(dev); 1208 struct flexcan_priv *priv = netdev_priv(dev);
1209 int err;
1117 1210
1118 flexcan_chip_disable(priv); 1211 err = flexcan_chip_disable(priv);
1212 if (err)
1213 return err;
1119 1214
1120 if (netif_running(dev)) { 1215 if (netif_running(dev)) {
1121 netif_stop_queue(dev); 1216 netif_stop_queue(dev);
@@ -1136,9 +1231,7 @@ static int flexcan_resume(struct device *device)
1136 netif_device_attach(dev); 1231 netif_device_attach(dev);
1137 netif_start_queue(dev); 1232 netif_start_queue(dev);
1138 } 1233 }
1139 flexcan_chip_enable(priv); 1234 return flexcan_chip_enable(priv);
1140
1141 return 0;
1142} 1235}
1143#endif /* CONFIG_PM_SLEEP */ 1236#endif /* CONFIG_PM_SLEEP */
1144 1237