of_slimbus.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. /* OF helpers for SLIMbus */
  13. #include <linux/slimbus/slimbus.h>
  14. #include <linux/irq.h>
  15. #include <linux/slab.h>
  16. #include <linux/of.h>
  17. #include <linux/of_irq.h>
  18. #include <linux/of_slimbus.h>
  19. int of_register_slim_devices(struct slim_controller *ctrl)
  20. {
  21. struct device_node *node;
  22. struct slim_boardinfo *binfo = NULL;
  23. struct slim_boardinfo *temp;
  24. int n = 0;
  25. int ret = 0;
  26. if (!ctrl->dev.of_node)
  27. return -EINVAL;
  28. for_each_child_of_node(ctrl->dev.of_node, node) {
  29. struct property *prop;
  30. struct slim_device *slim;
  31. char *name;
  32. prop = of_find_property(node, "elemental-addr", NULL);
  33. if (!prop || prop->length != 6) {
  34. dev_err(&ctrl->dev, "of_slim: invalid E-addr");
  35. continue;
  36. }
  37. name = kzalloc(SLIMBUS_NAME_SIZE, GFP_KERNEL);
  38. if (!name) {
  39. dev_err(&ctrl->dev, "of_slim: out of memory");
  40. ret = -ENOMEM;
  41. goto of_slim_err;
  42. }
  43. if (of_modalias_node(node, name, SLIMBUS_NAME_SIZE) < 0) {
  44. dev_err(&ctrl->dev, "of_slim: modalias failure on %s\n",
  45. node->full_name);
  46. kfree(name);
  47. continue;
  48. }
  49. slim = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
  50. if (!slim) {
  51. dev_err(&ctrl->dev, "of_slim: out of memory");
  52. ret = -ENOMEM;
  53. kfree(name);
  54. goto of_slim_err;
  55. }
  56. memcpy(slim->e_addr, prop->value, 6);
  57. temp = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
  58. GFP_KERNEL);
  59. if (!temp) {
  60. dev_err(&ctrl->dev, "out of memory");
  61. kfree(name);
  62. kfree(slim);
  63. ret = -ENOMEM;
  64. goto of_slim_err;
  65. }
  66. binfo = temp;
  67. slim->dev.of_node = of_node_get(node);
  68. slim->name = (const char *)name;
  69. binfo[n].bus_num = ctrl->nr;
  70. binfo[n].slim_slave = slim;
  71. n++;
  72. }
  73. ret = slim_register_board_info(binfo, n);
  74. if (!ret)
  75. goto of_slim_ret;
  76. of_slim_err:
  77. while (n-- > 0) {
  78. kfree(binfo[n].slim_slave->name);
  79. kfree(binfo[n].slim_slave);
  80. }
  81. of_slim_ret:
  82. kfree(binfo);
  83. return ret;
  84. }