0533-brcmvirt_gpio-Create-coherent-buffer-and-push-to-fir.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. From 07afae52a73991a3ea948aab5d0303a5a9805b41 Mon Sep 17 00:00:00 2001
  2. From: popcornmix <popcornmix@gmail.com>
  3. Date: Wed, 9 Nov 2016 22:42:39 +0000
  4. Subject: [PATCH] brcmvirt_gpio: Create coherent buffer and push to firmware
  5. ---
  6. drivers/gpio/gpio-bcm-virt.c | 88 +++++++++++++++++++++---------
  7. include/soc/bcm2835/raspberrypi-firmware.h | 1 +
  8. 2 files changed, 62 insertions(+), 27 deletions(-)
  9. --- a/drivers/gpio/gpio-bcm-virt.c
  10. +++ b/drivers/gpio/gpio-bcm-virt.c
  11. @@ -15,6 +15,7 @@
  12. #include <linux/module.h>
  13. #include <linux/basic_mmio_gpio.h>
  14. #include <linux/platform_device.h>
  15. +#include <linux/dma-mapping.h>
  16. #include <soc/bcm2835/raspberrypi-firmware.h>
  17. #define MODULE_NAME "brcmvirt-gpio"
  18. @@ -26,6 +27,7 @@ struct brcmvirt_gpio {
  19. /* two packed 16-bit counts of enabled and disables
  20. Allows host to detect a brief enable that was missed */
  21. u32 enables_disables[NUM_GPIO];
  22. + dma_addr_t bus_addr;
  23. };
  24. static int brcmvirt_gpio_dir_in(struct gpio_chip *gc, unsigned off)
  25. @@ -76,13 +78,13 @@ static void brcmvirt_gpio_set(struct gpi
  26. static int brcmvirt_gpio_probe(struct platform_device *pdev)
  27. {
  28. + int err = 0;
  29. struct device *dev = &pdev->dev;
  30. struct device_node *np = dev->of_node;
  31. struct device_node *fw_node;
  32. struct rpi_firmware *fw;
  33. struct brcmvirt_gpio *ucb;
  34. u32 gpiovirtbuf;
  35. - int err = 0;
  36. fw_node = of_parse_phandle(np, "firmware", 0);
  37. if (!fw_node) {
  38. @@ -94,35 +96,56 @@ static int brcmvirt_gpio_probe(struct pl
  39. if (!fw)
  40. return -EPROBE_DEFER;
  41. - err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF,
  42. - &gpiovirtbuf, sizeof(gpiovirtbuf));
  43. -
  44. - if (err) {
  45. - dev_err(dev, "Failed to get gpiovirtbuf\n");
  46. - goto err;
  47. - }
  48. -
  49. - if (!gpiovirtbuf) {
  50. - dev_err(dev, "No virtgpio buffer\n");
  51. - err = -ENOENT;
  52. - goto err;
  53. - }
  54. -
  55. ucb = devm_kzalloc(dev, sizeof *ucb, GFP_KERNEL);
  56. if (!ucb) {
  57. err = -EINVAL;
  58. - goto err;
  59. + goto out;
  60. }
  61. - // mmap the physical memory
  62. - gpiovirtbuf &= ~0xc0000000;
  63. - ucb->ts_base = ioremap(gpiovirtbuf, 4096);
  64. - if (ucb->ts_base == NULL) {
  65. - dev_err(dev, "Failed to map physical address\n");
  66. - err = -ENOENT;
  67. - goto err;
  68. + ucb->ts_base = dma_zalloc_coherent(NULL, PAGE_SIZE, &ucb->bus_addr, GFP_KERNEL);
  69. + if (!ucb->ts_base) {
  70. + pr_err("[%s]: failed to dma_alloc_coherent(%ld)\n",
  71. + __func__, PAGE_SIZE);
  72. + err = -ENOMEM;
  73. + goto out;
  74. }
  75. + gpiovirtbuf = (u32)ucb->bus_addr;
  76. + err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF,
  77. + &gpiovirtbuf, sizeof(gpiovirtbuf));
  78. +
  79. + if (err || gpiovirtbuf != 0) {
  80. + dev_warn(dev, "Failed to set gpiovirtbuf, trying to get err:%x\n", err);
  81. + dma_free_coherent(NULL, PAGE_SIZE, ucb->ts_base, ucb->bus_addr);
  82. + ucb->ts_base = 0;
  83. + ucb->bus_addr = 0;
  84. + }
  85. +
  86. + if (!ucb->ts_base) {
  87. + err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF,
  88. + &gpiovirtbuf, sizeof(gpiovirtbuf));
  89. +
  90. + if (err) {
  91. + dev_err(dev, "Failed to get gpiovirtbuf\n");
  92. + goto out;
  93. + }
  94. +
  95. + if (!gpiovirtbuf) {
  96. + dev_err(dev, "No virtgpio buffer\n");
  97. + err = -ENOENT;
  98. + goto out;
  99. + }
  100. +
  101. + // mmap the physical memory
  102. + gpiovirtbuf &= ~0xc0000000;
  103. + ucb->ts_base = ioremap(gpiovirtbuf, 4096);
  104. + if (ucb->ts_base == NULL) {
  105. + dev_err(dev, "Failed to map physical address\n");
  106. + err = -ENOENT;
  107. + goto out;
  108. + }
  109. + ucb->bus_addr = 0;
  110. + }
  111. ucb->gc.label = MODULE_NAME;
  112. ucb->gc.owner = THIS_MODULE;
  113. ucb->gc.dev = dev;
  114. @@ -138,13 +161,21 @@ static int brcmvirt_gpio_probe(struct pl
  115. err = gpiochip_add(&ucb->gc);
  116. if (err)
  117. - goto err;
  118. + goto out;
  119. platform_set_drvdata(pdev, ucb);
  120. -err:
  121. + return 0;
  122. +out:
  123. + if (ucb->bus_addr) {
  124. + dma_free_coherent(NULL, PAGE_SIZE, ucb->ts_base, ucb->bus_addr);
  125. + ucb->bus_addr = 0;
  126. + ucb->ts_base = NULL;
  127. + } else if (ucb->ts_base) {
  128. + iounmap(ucb->ts_base);
  129. + ucb->ts_base = NULL;
  130. + }
  131. return err;
  132. -
  133. }
  134. static int brcmvirt_gpio_remove(struct platform_device *pdev)
  135. @@ -153,7 +184,10 @@ static int brcmvirt_gpio_remove(struct p
  136. struct brcmvirt_gpio *ucb = platform_get_drvdata(pdev);
  137. gpiochip_remove(&ucb->gc);
  138. - iounmap(ucb->ts_base);
  139. + if (ucb->bus_addr)
  140. + dma_free_coherent(NULL, PAGE_SIZE, ucb->ts_base, ucb->bus_addr);
  141. + else if (ucb->ts_base)
  142. + iounmap(ucb->ts_base);
  143. return err;
  144. }
  145. --- a/include/soc/bcm2835/raspberrypi-firmware.h
  146. +++ b/include/soc/bcm2835/raspberrypi-firmware.h
  147. @@ -118,6 +118,7 @@ enum rpi_firmware_property_tag {
  148. RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a,
  149. RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b,
  150. RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f,
  151. + RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020,
  152. RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
  153. RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,