soc-realview.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (C) 2014 Linaro Ltd.
  3. *
  4. * Author: Linus Walleij <linus.walleij@linaro.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2, as
  8. * published by the Free Software Foundation.
  9. *
  10. */
  11. #include <linux/init.h>
  12. #include <linux/io.h>
  13. #include <linux/slab.h>
  14. #include <linux/sys_soc.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/mfd/syscon.h>
  17. #include <linux/regmap.h>
  18. #include <linux/of.h>
  19. /* System ID in syscon */
  20. #define REALVIEW_SYS_ID_OFFSET 0x00
  21. static const struct of_device_id realview_soc_of_match[] = {
  22. { .compatible = "arm,realview-eb-soc", },
  23. { .compatible = "arm,realview-pb1176-soc", },
  24. { .compatible = "arm,realview-pb11mp-soc", },
  25. { .compatible = "arm,realview-pba8-soc", },
  26. { .compatible = "arm,realview-pbx-soc", },
  27. { }
  28. };
  29. static u32 realview_coreid;
  30. static const char *realview_board_str(u32 id)
  31. {
  32. switch ((id >> 16) & 0xfff) {
  33. case 0x0147:
  34. return "HBI-0147";
  35. default:
  36. return "Unknown";
  37. }
  38. }
  39. static const char *realview_arch_str(u32 id)
  40. {
  41. switch ((id >> 8) & 0xf) {
  42. case 0x05:
  43. return "Multi-layer AXI";
  44. default:
  45. return "Unknown";
  46. }
  47. }
  48. static ssize_t realview_get_manf(struct device *dev,
  49. struct device_attribute *attr,
  50. char *buf)
  51. {
  52. return sprintf(buf, "%02x\n", realview_coreid >> 24);
  53. }
  54. static struct device_attribute realview_manf_attr =
  55. __ATTR(manufacturer, S_IRUGO, realview_get_manf, NULL);
  56. static ssize_t realview_get_board(struct device *dev,
  57. struct device_attribute *attr,
  58. char *buf)
  59. {
  60. return sprintf(buf, "%s\n", realview_board_str(realview_coreid));
  61. }
  62. static struct device_attribute realview_board_attr =
  63. __ATTR(board, S_IRUGO, realview_get_board, NULL);
  64. static ssize_t realview_get_arch(struct device *dev,
  65. struct device_attribute *attr,
  66. char *buf)
  67. {
  68. return sprintf(buf, "%s\n", realview_arch_str(realview_coreid));
  69. }
  70. static struct device_attribute realview_arch_attr =
  71. __ATTR(fpga, S_IRUGO, realview_get_arch, NULL);
  72. static ssize_t realview_get_build(struct device *dev,
  73. struct device_attribute *attr,
  74. char *buf)
  75. {
  76. return sprintf(buf, "%02x\n", (realview_coreid & 0xFF));
  77. }
  78. static struct device_attribute realview_build_attr =
  79. __ATTR(build, S_IRUGO, realview_get_build, NULL);
  80. static int realview_soc_probe(struct platform_device *pdev)
  81. {
  82. static struct regmap *syscon_regmap;
  83. struct soc_device *soc_dev;
  84. struct soc_device_attribute *soc_dev_attr;
  85. struct device_node *np = pdev->dev.of_node;
  86. int ret;
  87. syscon_regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
  88. if (IS_ERR(syscon_regmap))
  89. return PTR_ERR(syscon_regmap);
  90. soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
  91. if (!soc_dev_attr)
  92. return -ENOMEM;
  93. ret = of_property_read_string(np, "compatible",
  94. &soc_dev_attr->soc_id);
  95. if (ret)
  96. return -EINVAL;
  97. soc_dev_attr->machine = "RealView";
  98. soc_dev_attr->family = "Versatile";
  99. soc_dev = soc_device_register(soc_dev_attr);
  100. if (IS_ERR(soc_dev)) {
  101. kfree(soc_dev_attr);
  102. return -ENODEV;
  103. }
  104. ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET,
  105. &realview_coreid);
  106. if (ret)
  107. return -ENODEV;
  108. device_create_file(soc_device_to_device(soc_dev), &realview_manf_attr);
  109. device_create_file(soc_device_to_device(soc_dev), &realview_board_attr);
  110. device_create_file(soc_device_to_device(soc_dev), &realview_arch_attr);
  111. device_create_file(soc_device_to_device(soc_dev), &realview_build_attr);
  112. dev_info(&pdev->dev, "RealView Syscon Core ID: 0x%08x\n",
  113. realview_coreid);
  114. /* FIXME: add attributes for SoC to sysfs */
  115. return 0;
  116. }
  117. static struct platform_driver realview_soc_driver = {
  118. .probe = realview_soc_probe,
  119. .driver = {
  120. .name = "realview-soc",
  121. .of_match_table = realview_soc_of_match,
  122. },
  123. };
  124. builtin_platform_driver(realview_soc_driver);