scom.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright 2010 Benjamin Herrenschmidt, IBM Corp
  3. * <benh@kernel.crashing.org>
  4. * and David Gibson, IBM Corporation.
  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 as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  14. * the GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #ifndef _ASM_POWERPC_SCOM_H
  21. #define _ASM_POWERPC_SCOM_H
  22. #ifdef __KERNEL__
  23. #ifndef __ASSEMBLY__
  24. #ifdef CONFIG_PPC_SCOM
  25. /*
  26. * The SCOM bus is a sideband bus used for accessing various internal
  27. * registers of the processor or the chipset. The implementation details
  28. * differ between processors and platforms, and the access method as
  29. * well.
  30. *
  31. * This API allows to "map" ranges of SCOM register numbers associated
  32. * with a given SCOM controller. The later must be represented by a
  33. * device node, though some implementations might support NULL if there
  34. * is no possible ambiguity
  35. *
  36. * Then, scom_read/scom_write can be used to accesses registers inside
  37. * that range. The argument passed is a register number relative to
  38. * the beginning of the range mapped.
  39. */
  40. typedef void *scom_map_t;
  41. /* Value for an invalid SCOM map */
  42. #define SCOM_MAP_INVALID (NULL)
  43. /* The scom_controller data structure is what the platform passes
  44. * to the core code in scom_init, it provides the actual implementation
  45. * of all the SCOM functions
  46. */
  47. struct scom_controller {
  48. scom_map_t (*map)(struct device_node *ctrl_dev, u64 reg, u64 count);
  49. void (*unmap)(scom_map_t map);
  50. int (*read)(scom_map_t map, u64 reg, u64 *value);
  51. int (*write)(scom_map_t map, u64 reg, u64 value);
  52. };
  53. extern const struct scom_controller *scom_controller;
  54. /**
  55. * scom_init - Initialize the SCOM backend, called by the platform
  56. * @controller: The platform SCOM controller
  57. */
  58. static inline void scom_init(const struct scom_controller *controller)
  59. {
  60. scom_controller = controller;
  61. }
  62. /**
  63. * scom_map_ok - Test is a SCOM mapping is successful
  64. * @map: The result of scom_map to test
  65. */
  66. static inline int scom_map_ok(scom_map_t map)
  67. {
  68. return map != SCOM_MAP_INVALID;
  69. }
  70. /**
  71. * scom_map - Map a block of SCOM registers
  72. * @ctrl_dev: Device node of the SCOM controller
  73. * some implementations allow NULL here
  74. * @reg: first SCOM register to map
  75. * @count: Number of SCOM registers to map
  76. */
  77. static inline scom_map_t scom_map(struct device_node *ctrl_dev,
  78. u64 reg, u64 count)
  79. {
  80. return scom_controller->map(ctrl_dev, reg, count);
  81. }
  82. /**
  83. * scom_find_parent - Find the SCOM controller for a device
  84. * @dev: OF node of the device
  85. *
  86. * This is not meant for general usage, but in combination with
  87. * scom_map() allows to map registers not represented by the
  88. * device own scom-reg property. Useful for applying HW workarounds
  89. * on things not properly represented in the device-tree for example.
  90. */
  91. struct device_node *scom_find_parent(struct device_node *dev);
  92. /**
  93. * scom_map_device - Map a device's block of SCOM registers
  94. * @dev: OF node of the device
  95. * @index: Register bank index (index in "scom-reg" property)
  96. *
  97. * This function will use the device-tree binding for SCOM which
  98. * is to follow "scom-parent" properties until it finds a node with
  99. * a "scom-controller" property to find the controller. It will then
  100. * use the "scom-reg" property which is made of reg/count pairs,
  101. * each of them having a size defined by the controller's #scom-cells
  102. * property
  103. */
  104. extern scom_map_t scom_map_device(struct device_node *dev, int index);
  105. /**
  106. * scom_unmap - Unmap a block of SCOM registers
  107. * @map: Result of scom_map is to be unmapped
  108. */
  109. static inline void scom_unmap(scom_map_t map)
  110. {
  111. if (scom_map_ok(map))
  112. scom_controller->unmap(map);
  113. }
  114. /**
  115. * scom_read - Read a SCOM register
  116. * @map: Result of scom_map
  117. * @reg: Register index within that map
  118. * @value: Updated with the value read
  119. *
  120. * Returns 0 (success) or a negative error code
  121. */
  122. static inline int scom_read(scom_map_t map, u64 reg, u64 *value)
  123. {
  124. int rc;
  125. rc = scom_controller->read(map, reg, value);
  126. if (rc)
  127. *value = 0xfffffffffffffffful;
  128. return rc;
  129. }
  130. /**
  131. * scom_write - Write to a SCOM register
  132. * @map: Result of scom_map
  133. * @reg: Register index within that map
  134. * @value: Value to write
  135. *
  136. * Returns 0 (success) or a negative error code
  137. */
  138. static inline int scom_write(scom_map_t map, u64 reg, u64 value)
  139. {
  140. return scom_controller->write(map, reg, value);
  141. }
  142. #endif /* CONFIG_PPC_SCOM */
  143. #endif /* __ASSEMBLY__ */
  144. #endif /* __KERNEL__ */
  145. #endif /* _ASM_POWERPC_SCOM_H */