sram.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * linux/arch/arm/mach-mmp/sram.c
  3. *
  4. * based on mach-davinci/sram.c - DaVinci simple SRAM allocator
  5. *
  6. * Copyright (c) 2011 Marvell Semiconductors Inc.
  7. * All Rights Reserved
  8. *
  9. * Add for mmp sram support - Leo Yan <leoy@marvell.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. *
  15. */
  16. #include <linux/module.h>
  17. #include <linux/mod_devicetable.h>
  18. #include <linux/init.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/io.h>
  21. #include <linux/err.h>
  22. #include <linux/slab.h>
  23. #include <linux/genalloc.h>
  24. #include <linux/platform_data/dma-mmp_tdma.h>
  25. struct sram_bank_info {
  26. char *pool_name;
  27. struct gen_pool *gpool;
  28. int granularity;
  29. phys_addr_t sram_phys;
  30. void __iomem *sram_virt;
  31. u32 sram_size;
  32. struct list_head node;
  33. };
  34. static DEFINE_MUTEX(sram_lock);
  35. static LIST_HEAD(sram_bank_list);
  36. struct gen_pool *sram_get_gpool(char *pool_name)
  37. {
  38. struct sram_bank_info *info = NULL;
  39. if (!pool_name)
  40. return NULL;
  41. mutex_lock(&sram_lock);
  42. list_for_each_entry(info, &sram_bank_list, node)
  43. if (!strcmp(pool_name, info->pool_name))
  44. break;
  45. mutex_unlock(&sram_lock);
  46. if (&info->node == &sram_bank_list)
  47. return NULL;
  48. return info->gpool;
  49. }
  50. EXPORT_SYMBOL(sram_get_gpool);
  51. static int sram_probe(struct platform_device *pdev)
  52. {
  53. struct sram_platdata *pdata = pdev->dev.platform_data;
  54. struct sram_bank_info *info;
  55. struct resource *res;
  56. int ret = 0;
  57. if (!pdata || !pdata->pool_name)
  58. return -ENODEV;
  59. info = kzalloc(sizeof(*info), GFP_KERNEL);
  60. if (!info)
  61. return -ENOMEM;
  62. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  63. if (res == NULL) {
  64. dev_err(&pdev->dev, "no memory resource defined\n");
  65. ret = -ENODEV;
  66. goto out;
  67. }
  68. if (!resource_size(res))
  69. return 0;
  70. info->sram_phys = (phys_addr_t)res->start;
  71. info->sram_size = resource_size(res);
  72. info->sram_virt = ioremap(info->sram_phys, info->sram_size);
  73. info->pool_name = kstrdup(pdata->pool_name, GFP_KERNEL);
  74. info->granularity = pdata->granularity;
  75. info->gpool = gen_pool_create(ilog2(info->granularity), -1);
  76. if (!info->gpool) {
  77. dev_err(&pdev->dev, "create pool failed\n");
  78. ret = -ENOMEM;
  79. goto create_pool_err;
  80. }
  81. ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
  82. info->sram_phys, info->sram_size, -1);
  83. if (ret < 0) {
  84. dev_err(&pdev->dev, "add new chunk failed\n");
  85. ret = -ENOMEM;
  86. goto add_chunk_err;
  87. }
  88. mutex_lock(&sram_lock);
  89. list_add(&info->node, &sram_bank_list);
  90. mutex_unlock(&sram_lock);
  91. platform_set_drvdata(pdev, info);
  92. dev_info(&pdev->dev, "initialized\n");
  93. return 0;
  94. add_chunk_err:
  95. gen_pool_destroy(info->gpool);
  96. create_pool_err:
  97. iounmap(info->sram_virt);
  98. kfree(info->pool_name);
  99. out:
  100. kfree(info);
  101. return ret;
  102. }
  103. static int sram_remove(struct platform_device *pdev)
  104. {
  105. struct sram_bank_info *info;
  106. info = platform_get_drvdata(pdev);
  107. if (info == NULL)
  108. return -ENODEV;
  109. mutex_lock(&sram_lock);
  110. list_del(&info->node);
  111. mutex_unlock(&sram_lock);
  112. gen_pool_destroy(info->gpool);
  113. iounmap(info->sram_virt);
  114. kfree(info->pool_name);
  115. kfree(info);
  116. return 0;
  117. }
  118. static const struct platform_device_id sram_id_table[] = {
  119. { "asram", MMP_ASRAM },
  120. { "isram", MMP_ISRAM },
  121. { }
  122. };
  123. static struct platform_driver sram_driver = {
  124. .probe = sram_probe,
  125. .remove = sram_remove,
  126. .driver = {
  127. .name = "mmp-sram",
  128. },
  129. .id_table = sram_id_table,
  130. };
  131. static int __init sram_init(void)
  132. {
  133. return platform_driver_register(&sram_driver);
  134. }
  135. core_initcall(sram_init);
  136. MODULE_LICENSE("GPL");