950-0049-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. From f7cccb2e66f0187f69a432536f227b32a458f94b Mon Sep 17 00:00:00 2001
  2. From: Martin Sperl <[email protected]>
  3. Date: Tue, 26 Apr 2016 14:59:21 +0000
  4. Subject: [PATCH] MISC: bcm2835: smi: use clock manager and fix reload
  5. issues
  6. Use clock manager instead of self-made clockmanager.
  7. Also fix some error paths that showd up during development
  8. (especially missing release of dma resources on rmmod)
  9. Signed-off-by: Martin Sperl <[email protected]>
  10. ---
  11. drivers/misc/bcm2835_smi.c | 86 +++++++++++++-------------------------
  12. 1 file changed, 28 insertions(+), 58 deletions(-)
  13. --- a/drivers/misc/bcm2835_smi.c
  14. +++ b/drivers/misc/bcm2835_smi.c
  15. @@ -34,6 +34,7 @@
  16. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17. */
  18. +#include <linux/clk.h>
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/of.h>
  22. @@ -62,7 +63,7 @@
  23. struct bcm2835_smi_instance {
  24. struct device *dev;
  25. struct smi_settings settings;
  26. - __iomem void *smi_regs_ptr, *cm_smi_regs_ptr;
  27. + __iomem void *smi_regs_ptr;
  28. dma_addr_t smi_regs_busaddr;
  29. struct dma_chan *dma_chan;
  30. @@ -72,8 +73,7 @@ struct bcm2835_smi_instance {
  31. struct scatterlist buffer_sgl;
  32. - int clock_source;
  33. - int clock_divisor;
  34. + struct clk *clk;
  35. /* Sometimes we are called into in an atomic context (e.g. by
  36. JFFS2 + MTD) so we can't use a mutex */
  37. @@ -82,42 +82,6 @@ struct bcm2835_smi_instance {
  38. /****************************************************************************
  39. *
  40. -* SMI clock manager setup
  41. -*
  42. -***************************************************************************/
  43. -
  44. -static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst,
  45. - u32 val, unsigned reg)
  46. -{
  47. - writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg);
  48. -}
  49. -
  50. -static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst,
  51. - unsigned reg)
  52. -{
  53. - return readl(inst->cm_smi_regs_ptr + reg);
  54. -}
  55. -
  56. -static void smi_setup_clock(struct bcm2835_smi_instance *inst)
  57. -{
  58. - dev_dbg(inst->dev, "Setting up clock...");
  59. - /* Disable SMI clock and wait for it to stop. */
  60. - write_smi_cm_reg(inst, 0, CM_SMI_CTL);
  61. - while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY)
  62. - ;
  63. -
  64. - write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS),
  65. - CM_SMI_DIV);
  66. - write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS),
  67. - CM_SMI_CTL);
  68. -
  69. - /* Enable the clock */
  70. - write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) |
  71. - CM_SMI_CTL_ENAB, CM_SMI_CTL);
  72. -}
  73. -
  74. -/****************************************************************************
  75. -*
  76. * SMI peripheral setup
  77. *
  78. ***************************************************************************/
  79. @@ -894,42 +858,40 @@ static int bcm2835_smi_probe(struct plat
  80. struct device_node *node = dev->of_node;
  81. struct resource *ioresource;
  82. struct bcm2835_smi_instance *inst;
  83. + const __be32 *addr;
  84. + /* We require device tree support */
  85. + if (!node)
  86. + return -EINVAL;
  87. /* Allocate buffers and instance data */
  88. -
  89. inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance),
  90. GFP_KERNEL);
  91. -
  92. if (!inst)
  93. return -ENOMEM;
  94. inst->dev = dev;
  95. spin_lock_init(&inst->transaction_lock);
  96. - /* We require device tree support */
  97. - if (!node)
  98. - return -EINVAL;
  99. -
  100. ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  101. inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource);
  102. - ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  103. - inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource);
  104. - inst->smi_regs_busaddr = be32_to_cpu(
  105. - *of_get_address(node, 0, NULL, NULL));
  106. - of_property_read_u32(node,
  107. - "brcm,smi-clock-source",
  108. - &inst->clock_source);
  109. - of_property_read_u32(node,
  110. - "brcm,smi-clock-divisor",
  111. - &inst->clock_divisor);
  112. + if (IS_ERR(inst->smi_regs_ptr)) {
  113. + err = PTR_ERR(inst->smi_regs_ptr);
  114. + goto err;
  115. + }
  116. + addr = of_get_address(node, 0, NULL, NULL);
  117. + inst->smi_regs_busaddr = be32_to_cpu(addr);
  118. err = bcm2835_smi_dma_setup(inst);
  119. if (err)
  120. - return err;
  121. + goto err;
  122. - /* Finally, do peripheral setup */
  123. + /* request clock */
  124. + inst->clk = devm_clk_get(dev, NULL);
  125. + if (!inst->clk)
  126. + goto err;
  127. + clk_prepare_enable(inst->clk);
  128. - smi_setup_clock(inst);
  129. + /* Finally, do peripheral setup */
  130. smi_setup_regs(inst);
  131. platform_set_drvdata(pdev, inst);
  132. @@ -937,6 +899,9 @@ static int bcm2835_smi_probe(struct plat
  133. dev_info(inst->dev, "initialised");
  134. return 0;
  135. +err:
  136. + kfree(inst);
  137. + return err;
  138. }
  139. /****************************************************************************
  140. @@ -950,6 +915,11 @@ static int bcm2835_smi_remove(struct pla
  141. struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev);
  142. struct device *dev = inst->dev;
  143. + dmaengine_terminate_all(inst->dma_chan);
  144. + dma_release_channel(inst->dma_chan);
  145. +
  146. + clk_disable_unprepare(inst->clk);
  147. +
  148. dev_info(dev, "SMI device removed - OK");
  149. return 0;
  150. }