7018-devres-add-devm_alloc_percpu.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. From f7792176d939e79b4f525114a95d0fd8266bef8e Mon Sep 17 00:00:00 2001
  2. From: Madalin Bucur <madalin.bucur@freescale.com>
  3. Date: Wed, 19 Nov 2014 13:06:54 +0200
  4. Subject: [PATCH 18/70] devres: add devm_alloc_percpu()
  5. Introduce managed counterparts for alloc_percpu() and free_percpu().
  6. Add devm_alloc_percpu() and devm_free_percpu() into the managed
  7. interfaces list.
  8. Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
  9. Change-Id: I93546348e7b0e1974fda8b6c7a3b3710ce45b724
  10. Reviewed-on: http://git.am.freescale.net:8181/24140
  11. Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
  12. Tested-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
  13. Conflicts:
  14. Documentation/driver-model/devres.txt
  15. drivers/base/devres.c
  16. Conflicts:
  17. drivers/base/devres.c
  18. ---
  19. Documentation/driver-model/devres.txt | 4 +++
  20. drivers/base/devres.c | 63 +++++++++++++++++++++++++++++++++
  21. include/linux/device.h | 19 ++++++++++
  22. 3 files changed, 86 insertions(+)
  23. --- a/Documentation/driver-model/devres.txt
  24. +++ b/Documentation/driver-model/devres.txt
  25. @@ -321,6 +321,10 @@ PHY
  26. devm_usb_get_phy()
  27. devm_usb_put_phy()
  28. +PER-CPU MEM
  29. + devm_alloc_percpu()
  30. + devm_free_percpu()
  31. +
  32. PINCTRL
  33. devm_pinctrl_get()
  34. devm_pinctrl_put()
  35. --- a/drivers/base/devres.c
  36. +++ b/drivers/base/devres.c
  37. @@ -985,3 +985,66 @@ void devm_free_pages(struct device *dev,
  38. &devres));
  39. }
  40. EXPORT_SYMBOL_GPL(devm_free_pages);
  41. +
  42. +static void devm_percpu_release(struct device *dev, void *pdata)
  43. +{
  44. + void __percpu *p;
  45. +
  46. + p = *(void __percpu **)pdata;
  47. + free_percpu(p);
  48. +}
  49. +
  50. +static int devm_percpu_match(struct device *dev, void *data, void *p)
  51. +{
  52. + struct devres *devr = container_of(data, struct devres, data);
  53. +
  54. + return *(void **)devr->data == p;
  55. +}
  56. +
  57. +/**
  58. + * __devm_alloc_percpu - Resource-managed alloc_percpu
  59. + * @dev: Device to allocate per-cpu memory for
  60. + * @size: Size of per-cpu memory to allocate
  61. + * @align: Alignement of per-cpu memory to allocate
  62. + *
  63. + * Managed alloc_percpu. Per-cpu memory allocated with this function is
  64. + * automatically freed on driver detach.
  65. + *
  66. + * RETURNS:
  67. + * Pointer to allocated memory on success, NULL on failure.
  68. + */
  69. +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
  70. + size_t align)
  71. +{
  72. + void *p;
  73. + void __percpu *pcpu;
  74. +
  75. + pcpu = __alloc_percpu(size, align);
  76. + if (!pcpu)
  77. + return NULL;
  78. +
  79. + p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
  80. + if (!p)
  81. + return NULL;
  82. +
  83. + *(void __percpu **)p = pcpu;
  84. +
  85. + devres_add(dev, p);
  86. +
  87. + return pcpu;
  88. +}
  89. +EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
  90. +
  91. +/**
  92. + * devm_free_percpu - Resource-managed free_percpu
  93. + * @dev: Device this memory belongs to
  94. + * @pdata: Per-cpu memory to free
  95. + *
  96. + * Free memory allocated with devm_alloc_percpu().
  97. + */
  98. +void devm_free_percpu(struct device *dev, void __percpu *pdata)
  99. +{
  100. + WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
  101. + (void *)pdata));
  102. +}
  103. +EXPORT_SYMBOL_GPL(devm_free_percpu);
  104. --- a/include/linux/device.h
  105. +++ b/include/linux/device.h
  106. @@ -683,6 +683,25 @@ void __iomem *devm_ioremap_resource(stru
  107. int devm_add_action(struct device *dev, void (*action)(void *), void *data);
  108. void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
  109. +/**
  110. + * devm_alloc_percpu - Resource-managed alloc_percpu
  111. + * @dev: Device to allocate per-cpu memory for
  112. + * @type: Type to allocate per-cpu memory for
  113. + *
  114. + * Managed alloc_percpu. Per-cpu memory allocated with this function is
  115. + * automatically freed on driver detach.
  116. + *
  117. + * RETURNS:
  118. + * Pointer to allocated memory on success, NULL on failure.
  119. + */
  120. +#define devm_alloc_percpu(dev, type) \
  121. + (typeof(type) __percpu *)__devm_alloc_percpu(dev, sizeof(type), \
  122. + __alignof__(type))
  123. +
  124. +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
  125. + size_t align);
  126. +void devm_free_percpu(struct device *dev, void __percpu *pdata);
  127. +
  128. struct device_dma_parameters {
  129. /*
  130. * a low level driver may set these to teach IOMMU code about