Advertisement
Guest User

Untitled

a guest
Sep 29th, 2021
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.51 KB | None | 0 0
  1. --- linux-5.10.64/drivers/firmware/raspberrypi.c 2021-09-29 23:19:57.006485785 +0200
  2. +++ build_dir/target-aarch64_cortex-a53_musl/linux-bcm27xx_bcm2710/linux-5.10.69/drivers/firmware/raspberrypi.c 2021-09-29 23:26:45.117905773 +0200
  3. @@ -7,6 +7,7 @@
  4. */
  5.  
  6. #include <linux/dma-mapping.h>
  7. +#include <linux/kref.h>
  8. #include <linux/mailbox_client.h>
  9. #include <linux/module.h>
  10. #include <linux/of_platform.h>
  11. @@ -29,6 +30,8 @@
  12. struct completion c;
  13. u32 enabled;
  14. u32 get_throttled;
  15. +
  16. + struct kref consumers;
  17. };
  18.  
  19. static struct platform_device *g_pdev;
  20. @@ -340,12 +343,31 @@
  21. -1, NULL, 0);
  22. }
  23.  
  24. +static void rpi_firmware_delete(struct kref *kref)
  25. +{
  26. + struct rpi_firmware *fw = container_of(kref, struct rpi_firmware,
  27. + consumers);
  28. +
  29. + mbox_free_channel(fw->chan);
  30. + kfree(fw);
  31. +}
  32. +
  33. +void rpi_firmware_put(struct rpi_firmware *fw)
  34. +{
  35. + kref_put(&fw->consumers, rpi_firmware_delete);
  36. +}
  37. +EXPORT_SYMBOL_GPL(rpi_firmware_put);
  38. +
  39. static int rpi_firmware_probe(struct platform_device *pdev)
  40. {
  41. struct device *dev = &pdev->dev;
  42. struct rpi_firmware *fw;
  43.  
  44. - fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
  45. + /*
  46. + * Memory will be freed by rpi_firmware_delete() once all users have
  47. + * released their firmware handles. Don't use devm_kzalloc() here.
  48. + */
  49. + fw = kzalloc(sizeof(*fw), GFP_KERNEL);
  50. if (!fw)
  51. return -ENOMEM;
  52.  
  53. @@ -362,6 +384,7 @@
  54. }
  55.  
  56. init_completion(&fw->c);
  57. + kref_init(&fw->consumers);
  58.  
  59. platform_set_drvdata(pdev, fw);
  60. g_pdev = pdev;
  61. @@ -392,7 +415,9 @@
  62. rpi_hwmon = NULL;
  63. platform_device_unregister(rpi_clk);
  64. rpi_clk = NULL;
  65. - mbox_free_channel(fw->chan);
  66. +
  67. + rpi_firmware_put(fw);
  68. +
  69. g_pdev = NULL;
  70.  
  71. return 0;
  72. @@ -402,16 +427,32 @@
  73. * rpi_firmware_get - Get pointer to rpi_firmware structure.
  74. * @firmware_node: Pointer to the firmware Device Tree node.
  75. *
  76. + * The reference to rpi_firmware has to be released with rpi_firmware_put().
  77. + *
  78. * Returns NULL is the firmware device is not ready.
  79. */
  80. struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
  81. {
  82. struct platform_device *pdev = g_pdev;
  83. + struct rpi_firmware *fw;
  84.  
  85. if (!pdev)
  86. return NULL;
  87.  
  88. - return platform_get_drvdata(pdev);
  89. + fw = platform_get_drvdata(pdev);
  90. + if (!fw)
  91. + goto err_put_device;
  92. +
  93. + if (!kref_get_unless_zero(&fw->consumers))
  94. + goto err_put_device;
  95. +
  96. + put_device(&pdev->dev);
  97. +
  98. + return fw;
  99. +
  100. +err_put_device:
  101. + put_device(&pdev->dev);
  102. + return NULL;
  103. }
  104. EXPORT_SYMBOL_GPL(rpi_firmware_get);
  105.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement