Advertisement
trini

0001-misc-add-gpevt-driver.patch

Oct 17th, 2012
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.80 KB | None | 0 0
  1. From 621754e996519300582f8ecf3a514c2b3c1efb93 Mon Sep 17 00:00:00 2001
  2. From: Matt Porter <mporter@ti.com>
  3. Date: Wed, 17 Oct 2012 10:48:22 -0400
  4. Subject: [PATCH] misc: add gpevt driver
  5.  
  6. Simply amazing...'nuff said.
  7.  
  8. Signed-off-by: Matt Porter <mporter@ti.com>
  9. ---
  10. drivers/misc/Kconfig | 6 ++
  11. drivers/misc/Makefile | 1 +
  12. drivers/misc/gpevt.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++
  13. 3 files changed, 179 insertions(+)
  14. create mode 100644 drivers/misc/gpevt.c
  15.  
  16. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
  17. index b151b7c..cd43cbd 100644
  18. --- a/drivers/misc/Kconfig
  19. +++ b/drivers/misc/Kconfig
  20. @@ -499,6 +499,12 @@ config USB_SWITCH_FSA9480
  21. stereo and mono audio, video, microphone and UART data to use
  22. a common connector port.
  23.  
  24. +config GPEVT
  25. + tristate "Amazing GPIO DMA Event Test Driver(tm)"
  26. + depends on TI_EDMA
  27. + help
  28. + Simply amazing!
  29. +
  30. source "drivers/misc/c2port/Kconfig"
  31. source "drivers/misc/eeprom/Kconfig"
  32. source "drivers/misc/cb710/Kconfig"
  33. diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
  34. index 2129377..661d093 100644
  35. --- a/drivers/misc/Makefile
  36. +++ b/drivers/misc/Makefile
  37. @@ -49,3 +49,4 @@ obj-y += carma/
  38. obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
  39. obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
  40. obj-$(CONFIG_INTEL_MEI) += mei/
  41. +obj-$(CONFIG_GPEVT) += gpevt.o
  42. diff --git a/drivers/misc/gpevt.c b/drivers/misc/gpevt.c
  43. new file mode 100644
  44. index 0000000..4fe256c
  45. --- /dev/null
  46. +++ b/drivers/misc/gpevt.c
  47. @@ -0,0 +1,172 @@
  48. +/*
  49. + * This file is subject to the terms and conditions of the GNU General Public
  50. + * License. See the file COPYING in the main directory of this archive for
  51. + * more details.
  52. + */
  53. +
  54. +#include <linux/module.h>
  55. +#include <linux/kernel.h>
  56. +#include <linux/errno.h>
  57. +#include <linux/string.h>
  58. +#include <linux/mm.h>
  59. +#include <linux/slab.h>
  60. +#include <linux/init.h>
  61. +#include <linux/interrupt.h>
  62. +#include <linux/irq.h>
  63. +#include <linux/dma-mapping.h>
  64. +#include <linux/dmaengine.h>
  65. +#include <linux/gpio.h>
  66. +#include <linux/err.h>
  67. +#include <linux/uaccess.h>
  68. +#include <linux/of.h>
  69. +#include <linux/of_device.h>
  70. +#include <linux/of_gpio.h>
  71. +#include <linux/pinctrl/consumer.h>
  72. +#include <linux/platform_device.h>
  73. +
  74. +#define GPEVT_MAGIC 0xdeadbeef
  75. +
  76. +static u32 *dst_fifo;
  77. +static dma_addr_t fifo_addr;
  78. +
  79. +static void gpevt_callback(void *data)
  80. +{
  81. + struct device *dev = data;
  82. +
  83. + dma_unmap_single(dev, fifo_addr, 32, DMA_FROM_DEVICE);
  84. +
  85. + if (*dst_fifo == GPEVT_MAGIC)
  86. + dev_info(dev, "*** DMA transfer succeeded ***\n");
  87. + else
  88. + dev_info(dev, "*** DMA transfer failed ***\n");
  89. +}
  90. +
  91. +static int __devinit gpevt_probe (struct platform_device *pdev)
  92. +{
  93. + struct device_node *np = pdev->dev.of_node;
  94. + struct pinctrl *pinctrl;
  95. + struct dma_chan *chan;
  96. + struct dma_slave_config cfg;
  97. + struct dma_async_tx_descriptor *tx;
  98. + int gpio_evt = 0;
  99. + int ret;
  100. + u32 *src_buf;
  101. + struct scatterlist sg;
  102. +
  103. + src_buf = devm_kzalloc(&pdev->dev, 32, GFP_KERNEL);
  104. + if (!src_buf) {
  105. + dev_err(&pdev->dev, "failed to allocate src buffer\n");
  106. + return -ENOMEM;
  107. + }
  108. +
  109. + dst_fifo = devm_kzalloc(&pdev->dev, 32, GFP_KERNEL);
  110. + if (!dst_fifo) {
  111. + dev_err(&pdev->dev, "failed to allocate dst fifo\n");
  112. + return -ENOMEM;
  113. + }
  114. +
  115. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  116. + if (IS_ERR(pinctrl))
  117. + dev_warn(&pdev->dev,
  118. + "pins are not configured from the driver\n");
  119. +
  120. + gpio_evt = of_get_named_gpio(np, "gpio-evt", 0);
  121. + if (gpio_evt < 0) {
  122. + dev_err(&pdev->dev, "failed to find gpio event signal!\n");
  123. + return -EINVAL;
  124. + }
  125. +
  126. + ret = devm_gpio_request_one(&pdev->dev, gpio_evt,
  127. + GPIOF_IN, "GPIO Event Pin");
  128. + if (ret < 0) {
  129. + dev_err(&pdev->dev, "failed to claim gpio-evt pin\n");
  130. + return ret;
  131. + }
  132. +
  133. + ret = request_irq(gpio_to_irq(gpio_evt), no_action,
  134. + IRQ_TYPE_EDGE_FALLING, "gpevt", &pdev->dev);
  135. + if (ret < 0) {
  136. + dev_err(&pdev->dev, "failed to request falling edge irq/event\n");
  137. + return ret;
  138. + }
  139. +
  140. + chan = dma_request_slave_channel(&pdev->dev, "gpioevt");
  141. + if (!chan) {
  142. + dev_err(&pdev->dev, "no gpio channel for gpevt\n");
  143. + return -EAGAIN;
  144. + }
  145. +
  146. + fifo_addr = dma_map_single(&pdev->dev, dst_fifo, 32, DMA_FROM_DEVICE);
  147. + if (!fifo_addr) {
  148. + dev_err(&pdev->dev, "could not map dst fifo\n");
  149. + return -EIO;
  150. + }
  151. + cfg.dst_addr = fifo_addr;
  152. + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  153. + cfg.dst_maxburst = 1;
  154. +
  155. + ret = dmaengine_slave_config(chan, &cfg);
  156. + if (ret)
  157. + return ret;
  158. +
  159. + *src_buf = GPEVT_MAGIC;
  160. + sg_init_table(&sg, 1);
  161. + sg_dma_address(&sg) = dma_map_single(&pdev->dev, src_buf, 32, DMA_TO_DEVICE);
  162. + sg_dma_len(&sg) = 4;
  163. +
  164. + tx = dmaengine_prep_slave_sg(chan, &sg, 1, DMA_MEM_TO_DEV,
  165. + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
  166. + if (!tx) {
  167. + dev_err(&pdev->dev, "prep_slave_sg() failed\n");
  168. + return -EIO;
  169. + }
  170. +
  171. + tx->callback = gpevt_callback;
  172. + tx->callback_param = &pdev->dev;
  173. + dmaengine_submit(tx);
  174. +
  175. + dma_async_issue_pending(chan);
  176. +
  177. + dev_info(&pdev->dev, "Amazing GPIO DMA Event Test Driver(tm) engaged\n");
  178. +
  179. + return 0;
  180. +}
  181. +
  182. +static int __devexit gpevt_remove(struct platform_device *pdev)
  183. +{
  184. + return 0;
  185. +}
  186. +
  187. +static const struct of_device_id gpevt_dt_ids[] = {
  188. + { .compatible = "gpevt", .data = (void *) NULL, },
  189. +};
  190. +MODULE_DEVICE_TABLE(of, gpevt_dt_ids);
  191. +
  192. +static struct platform_driver gpevt_driver = {
  193. + .driver = {
  194. + .name = "gpevt",
  195. + .owner = THIS_MODULE,
  196. + .of_match_table = gpevt_dt_ids,
  197. + },
  198. + .probe = gpevt_probe,
  199. + .remove = __devexit_p(gpevt_remove),
  200. +};
  201. +
  202. +static int __init gpevt_init(void)
  203. +{
  204. + return platform_driver_register(&gpevt_driver);
  205. +}
  206. +
  207. +static void __exit gpevt_exit(void)
  208. +{
  209. + platform_driver_unregister(&gpevt_driver);
  210. +}
  211. +
  212. +/* ------------------------------------------------------------------------- */
  213. +
  214. +module_init(gpevt_init);
  215. +module_exit(gpevt_exit);
  216. +
  217. +MODULE_DESCRIPTION("Amazing GPIO DMA Event Test Driver(tm)");
  218. +MODULE_AUTHOR("Matt Porter <mporter@ti.com>");
  219. +MODULE_LICENSE("GPL");
  220. --
  221. 1.7.9.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement