Advertisement
Guest User

mcp251x patch for multiplatform linux

a guest
Jan 6th, 2014
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.43 KB | None | 0 0
  1. diff -Naur a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
  2. --- a/drivers/net/can/mcp251x.c 2012-11-22 12:06:42.000000000 +0100
  3. +++ b/drivers/net/can/mcp251x.c 2014-01-02 14:50:05.984543370 +0100
  4. @@ -60,6 +60,7 @@
  5.  
  6. #include <linux/can/core.h>
  7. #include <linux/can/dev.h>
  8. +#include <linux/can/led.h>
  9. #include <linux/can/platform/mcp251x.h>
  10. #include <linux/completion.h>
  11. #include <linux/delay.h>
  12. @@ -83,6 +84,11 @@
  13. #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n))
  14. #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94)
  15. #define INSTRUCTION_RESET 0xC0
  16. +#define RTS_TXB0 0x01
  17. +#define RTS_TXB1 0x02
  18. +#define RTS_TXB2 0x04
  19. +#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07))
  20. +
  21.  
  22. /* MPC251x registers */
  23. #define CANSTAT 0x0e
  24. @@ -214,7 +220,7 @@
  25. module_param(mcp251x_enable_dma, int, S_IRUGO);
  26. MODULE_PARM_DESC(mcp251x_enable_dma, "Enable SPI DMA. Default: 0 (Off)");
  27.  
  28. -static struct can_bittiming_const mcp251x_bittiming_const = {
  29. +static const struct can_bittiming_const mcp251x_bittiming_const = {
  30. .name = DEVICE_NAME,
  31. .tseg1_min = 3,
  32. .tseg1_max = 16,
  33. @@ -263,7 +269,7 @@
  34. #define MCP251X_IS(_model) \
  35. static inline int mcp251x_is_##_model(struct spi_device *spi) \
  36. { \
  37. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \
  38. + struct mcp251x_priv *priv = spi_get_drvdata(spi); \
  39. return priv->model == CAN_MCP251X_MCP##_model; \
  40. }
  41.  
  42. @@ -299,7 +305,7 @@
  43. */
  44. static int mcp251x_spi_trans(struct spi_device *spi, int len)
  45. {
  46. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  47. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  48. struct spi_transfer t = {
  49. .tx_buf = priv->spi_tx_buf,
  50. .rx_buf = priv->spi_rx_buf,
  51. @@ -327,7 +333,7 @@
  52.  
  53. static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
  54. {
  55. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  56. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  57. u8 val = 0;
  58.  
  59. priv->spi_tx_buf[0] = INSTRUCTION_READ;
  60. @@ -342,7 +348,7 @@
  61. static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg,
  62. uint8_t *v1, uint8_t *v2)
  63. {
  64. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  65. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  66.  
  67. priv->spi_tx_buf[0] = INSTRUCTION_READ;
  68. priv->spi_tx_buf[1] = reg;
  69. @@ -355,7 +361,7 @@
  70.  
  71. static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
  72. {
  73. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  74. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  75.  
  76. priv->spi_tx_buf[0] = INSTRUCTION_WRITE;
  77. priv->spi_tx_buf[1] = reg;
  78. @@ -367,7 +373,7 @@
  79. static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
  80. u8 mask, uint8_t val)
  81. {
  82. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  83. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  84.  
  85. priv->spi_tx_buf[0] = INSTRUCTION_BIT_MODIFY;
  86. priv->spi_tx_buf[1] = reg;
  87. @@ -380,7 +386,7 @@
  88. static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
  89. int len, int tx_buf_idx)
  90. {
  91. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  92. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  93.  
  94. if (mcp251x_is_2510(spi)) {
  95. int i;
  96. @@ -397,6 +403,7 @@
  97. static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
  98. int tx_buf_idx)
  99. {
  100. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  101. u32 sid, eid, exide, rtr;
  102. u8 buf[SPI_TRANSFER_BUF_LEN];
  103.  
  104. @@ -418,13 +425,16 @@
  105. buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
  106. memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
  107. mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
  108. - mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
  109. +
  110. + /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
  111. + priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
  112. + mcp251x_spi_trans(priv->spi, 1);
  113. }
  114.  
  115. static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
  116. int buf_idx)
  117. {
  118. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  119. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  120.  
  121. if (mcp251x_is_2510(spi)) {
  122. int i, len;
  123. @@ -444,7 +454,7 @@
  124.  
  125. static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
  126. {
  127. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  128. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  129. struct sk_buff *skb;
  130. struct can_frame *frame;
  131. u8 buf[SPI_TRANSFER_BUF_LEN];
  132. @@ -485,6 +495,9 @@
  133.  
  134. priv->net->stats.rx_packets++;
  135. priv->net->stats.rx_bytes += frame->can_dlc;
  136. +
  137. + can_led_event(priv->net, CAN_LED_EVENT_RX);
  138. +
  139. netif_rx_ni(skb);
  140. }
  141.  
  142. @@ -537,7 +550,7 @@
  143.  
  144. static int mcp251x_set_normal_mode(struct spi_device *spi)
  145. {
  146. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  147. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  148. unsigned long timeout;
  149.  
  150. /* Enable interrupts */
  151. @@ -607,7 +620,7 @@
  152.  
  153. static int mcp251x_hw_reset(struct spi_device *spi)
  154. {
  155. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  156. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  157. int ret;
  158. unsigned long timeout;
  159.  
  160. @@ -698,6 +711,8 @@
  161.  
  162. mutex_unlock(&priv->mcp_lock);
  163.  
  164. + can_led_event(net, CAN_LED_EVENT_STOP);
  165. +
  166. return 0;
  167. }
  168.  
  169. @@ -712,8 +727,7 @@
  170. frame->data[1] = data1;
  171. netif_rx_ni(skb);
  172. } else {
  173. - dev_err(&net->dev,
  174. - "cannot allocate error skb\n");
  175. + netdev_err(net, "cannot allocate error skb\n");
  176. }
  177. }
  178.  
  179. @@ -897,6 +911,7 @@
  180. if (intf & CANINTF_TX) {
  181. net->stats.tx_packets++;
  182. net->stats.tx_bytes += priv->tx_len - 1;
  183. + can_led_event(net, CAN_LED_EVENT_TX);
  184. if (priv->tx_len) {
  185. can_get_echo_skb(net, 0);
  186. priv->tx_len = 0;
  187. @@ -914,6 +929,7 @@
  188. struct mcp251x_priv *priv = netdev_priv(net);
  189. struct spi_device *spi = priv->spi;
  190. struct mcp251x_platform_data *pdata = spi->dev.platform_data;
  191. + unsigned long flags;
  192. int ret;
  193.  
  194. ret = open_candev(net);
  195. @@ -930,9 +946,14 @@
  196. priv->tx_skb = NULL;
  197. priv->tx_len = 0;
  198.  
  199. + flags = IRQF_ONESHOT;
  200. + if (pdata->irq_flags)
  201. + flags |= pdata->irq_flags;
  202. + else
  203. + flags |= IRQF_TRIGGER_FALLING;
  204. +
  205. ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
  206. - pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
  207. - DEVICE_NAME, priv);
  208. + flags, DEVICE_NAME, priv);
  209. if (ret) {
  210. dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
  211. if (pdata->transceiver_enable)
  212. @@ -960,6 +981,9 @@
  213. mcp251x_open_clean(net);
  214. goto open_unlock;
  215. }
  216. +
  217. + can_led_event(net, CAN_LED_EVENT_OPEN);
  218. +
  219. netif_wake_queue(net);
  220.  
  221. open_unlock:
  222. @@ -973,11 +997,11 @@
  223. .ndo_start_xmit = mcp251x_hard_start_xmit,
  224. };
  225.  
  226. -static int __devinit mcp251x_can_probe(struct spi_device *spi)
  227. +static int mcp251x_can_probe(struct spi_device *spi)
  228. {
  229. struct net_device *net;
  230. struct mcp251x_priv *priv;
  231. - struct mcp251x_platform_data *pdata = spi->dev.platform_data;
  232. + struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
  233. int ret = -ENODEV;
  234.  
  235. if (!pdata)
  236. @@ -1002,7 +1026,7 @@
  237. CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
  238. priv->model = spi_get_device_id(spi)->driver_data;
  239. priv->net = net;
  240. - dev_set_drvdata(&spi->dev, priv);
  241. + spi_set_drvdata(spi, priv);
  242.  
  243. priv->spi = spi;
  244. mutex_init(&priv->mcp_lock);
  245. @@ -1021,8 +1045,7 @@
  246. GFP_DMA);
  247.  
  248. if (priv->spi_tx_buf) {
  249. - priv->spi_rx_buf = (u8 *)(priv->spi_tx_buf +
  250. - (PAGE_SIZE / 2));
  251. + priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
  252. priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
  253. (PAGE_SIZE / 2));
  254. } else {
  255. @@ -1033,15 +1056,15 @@
  256.  
  257. /* Allocate non-DMA buffers */
  258. if (!mcp251x_enable_dma) {
  259. - priv->spi_tx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
  260. + priv->spi_tx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
  261. if (!priv->spi_tx_buf) {
  262. ret = -ENOMEM;
  263. - goto error_tx_buf;
  264. + goto error_probe;
  265. }
  266. - priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
  267. + priv->spi_rx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
  268. if (!priv->spi_rx_buf) {
  269. ret = -ENOMEM;
  270. - goto error_rx_buf;
  271. + goto error_probe;
  272. }
  273. }
  274.  
  275. @@ -1055,13 +1078,18 @@
  276. SET_NETDEV_DEV(net, &spi->dev);
  277.  
  278. /* Configure the SPI bus */
  279. - spi->mode = SPI_MODE_0;
  280. + spi->mode = spi->mode ? : SPI_MODE_0;
  281. + if (mcp251x_is_2510(spi))
  282. + spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
  283. + else
  284. + spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
  285. +
  286. spi->bits_per_word = 8;
  287. spi_setup(spi);
  288.  
  289. /* Here is OK to not lock the MCP, no one knows about it yet */
  290. if (!mcp251x_hw_probe(spi)) {
  291. -//### dev_info(&spi->dev, "Probe failed\n");
  292. + dev_info(&spi->dev, "Probe failed\n");
  293. goto error_probe;
  294. }
  295. mcp251x_hw_sleep(spi);
  296. @@ -1070,17 +1098,16 @@
  297. pdata->transceiver_enable(0);
  298.  
  299. ret = register_candev(net);
  300. - if (!ret) {
  301. - dev_info(&spi->dev, "probed\n");
  302. - return ret;
  303. - }
  304. + if (ret)
  305. + goto error_probe;
  306. +
  307. + devm_can_led_init(net);
  308. +
  309. + dev_info(&spi->dev, "probed\n");
  310. +
  311. + return ret;
  312. +
  313. error_probe:
  314. - if (!mcp251x_enable_dma)
  315. - kfree(priv->spi_rx_buf);
  316. -error_rx_buf:
  317. - if (!mcp251x_enable_dma)
  318. - kfree(priv->spi_tx_buf);
  319. -error_tx_buf:
  320. free_candev(net);
  321. if (mcp251x_enable_dma)
  322. dma_free_coherent(&spi->dev, PAGE_SIZE,
  323. @@ -1093,10 +1120,10 @@
  324. return ret;
  325. }
  326.  
  327. -static int __devexit mcp251x_can_remove(struct spi_device *spi)
  328. +static int mcp251x_can_remove(struct spi_device *spi)
  329. {
  330. struct mcp251x_platform_data *pdata = spi->dev.platform_data;
  331. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  332. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  333. struct net_device *net = priv->net;
  334.  
  335. unregister_candev(net);
  336. @@ -1105,9 +1132,6 @@
  337. if (mcp251x_enable_dma) {
  338. dma_free_coherent(&spi->dev, PAGE_SIZE,
  339. priv->spi_tx_buf, priv->spi_tx_dma);
  340. - } else {
  341. - kfree(priv->spi_tx_buf);
  342. - kfree(priv->spi_rx_buf);
  343. }
  344.  
  345. if (pdata->power_enable)
  346. @@ -1116,11 +1140,13 @@
  347. return 0;
  348. }
  349.  
  350. -#ifdef CONFIG_PM
  351. -static int mcp251x_can_suspend(struct spi_device *spi, pm_message_t state)
  352. +#ifdef CONFIG_PM_SLEEP
  353. +
  354. +static int mcp251x_can_suspend(struct device *dev)
  355. {
  356. + struct spi_device *spi = to_spi_device(dev);
  357. struct mcp251x_platform_data *pdata = spi->dev.platform_data;
  358. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  359. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  360. struct net_device *net = priv->net;
  361.  
  362. priv->force_quit = 1;
  363. @@ -1148,10 +1174,11 @@
  364. return 0;
  365. }
  366.  
  367. -static int mcp251x_can_resume(struct spi_device *spi)
  368. +static int mcp251x_can_resume(struct device *dev)
  369. {
  370. + struct spi_device *spi = to_spi_device(dev);
  371. struct mcp251x_platform_data *pdata = spi->dev.platform_data;
  372. - struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
  373. + struct mcp251x_priv *priv = spi_get_drvdata(spi);
  374.  
  375. if (priv->after_suspend & AFTER_SUSPEND_POWER) {
  376. pdata->power_enable(1);
  377. @@ -1169,11 +1196,11 @@
  378. enable_irq(spi->irq);
  379. return 0;
  380. }
  381. -#else
  382. -#define mcp251x_can_suspend NULL
  383. -#define mcp251x_can_resume NULL
  384. #endif
  385.  
  386. +static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend,
  387. + mcp251x_can_resume);
  388. +
  389. static const struct spi_device_id mcp251x_id_table[] = {
  390. { "mcp2510", CAN_MCP251X_MCP2510 },
  391. { "mcp2515", CAN_MCP251X_MCP2515 },
  392. @@ -1185,31 +1212,18 @@
  393. static struct spi_driver mcp251x_can_driver = {
  394. .driver = {
  395. .name = DEVICE_NAME,
  396. - .bus = &spi_bus_type,
  397. .owner = THIS_MODULE,
  398. + .pm = &mcp251x_can_pm_ops,
  399. },
  400.  
  401. .id_table = mcp251x_id_table,
  402. .probe = mcp251x_can_probe,
  403. - .remove = __devexit_p(mcp251x_can_remove),
  404. - .suspend = mcp251x_can_suspend,
  405. - .resume = mcp251x_can_resume,
  406. + .remove = mcp251x_can_remove,
  407. };
  408. -
  409. -static int __init mcp251x_can_init(void)
  410. -{
  411. - return spi_register_driver(&mcp251x_can_driver);
  412. -}
  413. -
  414. -static void __exit mcp251x_can_exit(void)
  415. -{
  416. - spi_unregister_driver(&mcp251x_can_driver);
  417. -}
  418. -
  419. -module_init(mcp251x_can_init);
  420. -module_exit(mcp251x_can_exit);
  421. +module_spi_driver(mcp251x_can_driver);
  422.  
  423. MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
  424. "Christian Pellegrin <chripell@evolware.org>");
  425. MODULE_DESCRIPTION("Microchip 251x CAN driver");
  426. MODULE_LICENSE("GPL v2");
  427. +
  428. diff -Naur a/include/linux/can/led.h b/include/linux/can/led.h
  429. --- a/include/linux/can/led.h 1970-01-01 01:00:00.000000000 +0100
  430. +++ b/include/linux/can/led.h 2014-01-02 14:42:04.108435089 +0100
  431. @@ -0,0 +1,51 @@
  432. +/*
  433. + * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
  434. + *
  435. + * This program is free software; you can redistribute it and/or modify
  436. + * it under the terms of the GNU General Public License version 2 as
  437. + * published by the Free Software Foundation.
  438. + */
  439. +
  440. +#ifndef CAN_LED_H
  441. +#define CAN_LED_H
  442. +
  443. +#include <linux/if.h>
  444. +#include <linux/leds.h>
  445. +
  446. +enum can_led_event {
  447. + CAN_LED_EVENT_OPEN,
  448. + CAN_LED_EVENT_STOP,
  449. + CAN_LED_EVENT_TX,
  450. + CAN_LED_EVENT_RX,
  451. +};
  452. +
  453. +#ifdef CONFIG_CAN_LEDS
  454. +
  455. +/* keep space for interface name + "-tx"/"-rx" suffix and null terminator */
  456. +#define CAN_LED_NAME_SZ (IFNAMSIZ + 4)
  457. +
  458. +void can_led_event(struct net_device *netdev, enum can_led_event event);
  459. +void devm_can_led_init(struct net_device *netdev);
  460. +int __init can_led_notifier_init(void);
  461. +void __exit can_led_notifier_exit(void);
  462. +
  463. +#else
  464. +
  465. +static inline void can_led_event(struct net_device *netdev,
  466. + enum can_led_event event)
  467. +{
  468. +}
  469. +static inline void devm_can_led_init(struct net_device *netdev)
  470. +{
  471. +}
  472. +static inline int can_led_notifier_init(void)
  473. +{
  474. + return 0;
  475. +}
  476. +static inline void can_led_notifier_exit(void)
  477. +{
  478. +}
  479. +
  480. +#endif
  481. +
  482. +#endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement