ibm_rtl.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * IBM Real-Time Linux driver
  4. *
  5. * Copyright (C) IBM Corporation, 2010
  6. *
  7. * Author: Keith Mannthey <kmannth@us.ibm.com>
  8. * Vernon Mauery <vernux@us.ibm.com>
  9. */
  10. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11. #include <linux/kernel.h>
  12. #include <linux/delay.h>
  13. #include <linux/module.h>
  14. #include <linux/io.h>
  15. #include <linux/dmi.h>
  16. #include <linux/efi.h>
  17. #include <linux/mutex.h>
  18. #include <asm/bios_ebda.h>
  19. #include <linux/io-64-nonatomic-lo-hi.h>
  20. static bool force;
  21. module_param(force, bool, 0);
  22. MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
  23. static bool debug;
  24. module_param(debug, bool, 0644);
  25. MODULE_PARM_DESC(debug, "Show debug output");
  26. MODULE_LICENSE("GPL");
  27. MODULE_AUTHOR("Keith Mannthey <kmmanth@us.ibm.com>");
  28. MODULE_AUTHOR("Vernon Mauery <vernux@us.ibm.com>");
  29. #define RTL_ADDR_TYPE_IO 1
  30. #define RTL_ADDR_TYPE_MMIO 2
  31. #define RTL_CMD_ENTER_PRTM 1
  32. #define RTL_CMD_EXIT_PRTM 2
  33. /* The RTL table as presented by the EBDA: */
  34. struct ibm_rtl_table {
  35. char signature[5]; /* signature should be "_RTL_" */
  36. u8 version;
  37. u8 rt_status;
  38. u8 command;
  39. u8 command_status;
  40. u8 cmd_address_type;
  41. u8 cmd_granularity;
  42. u8 cmd_offset;
  43. u16 reserve1;
  44. u32 cmd_port_address; /* platform dependent address */
  45. u32 cmd_port_value; /* platform dependent value */
  46. } __attribute__((packed));
  47. /* to locate "_RTL_" signature do a masked 5-byte integer compare */
  48. #define RTL_SIGNATURE 0x0000005f4c54525fULL
  49. #define RTL_MASK 0x000000ffffffffffULL
  50. #define RTL_DEBUG(fmt, ...) \
  51. do { \
  52. if (debug) \
  53. pr_info(fmt, ##__VA_ARGS__); \
  54. } while (0)
  55. static DEFINE_MUTEX(rtl_lock);
  56. static struct ibm_rtl_table __iomem *rtl_table;
  57. static void __iomem *ebda_map;
  58. static void __iomem *rtl_cmd_addr;
  59. static u8 rtl_cmd_type;
  60. static u8 rtl_cmd_width;
  61. static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len)
  62. {
  63. if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
  64. return ioremap(addr, len);
  65. return ioport_map(addr, len);
  66. }
  67. static void rtl_port_unmap(void __iomem *addr)
  68. {
  69. if (addr && rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
  70. iounmap(addr);
  71. else
  72. ioport_unmap(addr);
  73. }
  74. static int ibm_rtl_write(u8 value)
  75. {
  76. int ret = 0, count = 0;
  77. u32 cmd_port_val;
  78. RTL_DEBUG("%s(%d)\n", __func__, value);
  79. value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM;
  80. mutex_lock(&rtl_lock);
  81. if (ioread8(&rtl_table->rt_status) != value) {
  82. iowrite8(value, &rtl_table->command);
  83. switch (rtl_cmd_width) {
  84. case 8:
  85. cmd_port_val = ioread8(&rtl_table->cmd_port_value);
  86. RTL_DEBUG("cmd_port_val = %u\n", cmd_port_val);
  87. iowrite8((u8)cmd_port_val, rtl_cmd_addr);
  88. break;
  89. case 16:
  90. cmd_port_val = ioread16(&rtl_table->cmd_port_value);
  91. RTL_DEBUG("cmd_port_val = %u\n", cmd_port_val);
  92. iowrite16((u16)cmd_port_val, rtl_cmd_addr);
  93. break;
  94. case 32:
  95. cmd_port_val = ioread32(&rtl_table->cmd_port_value);
  96. RTL_DEBUG("cmd_port_val = %u\n", cmd_port_val);
  97. iowrite32(cmd_port_val, rtl_cmd_addr);
  98. break;
  99. }
  100. while (ioread8(&rtl_table->command)) {
  101. msleep(10);
  102. if (count++ > 500) {
  103. pr_err("Hardware not responding to "
  104. "mode switch request\n");
  105. ret = -EIO;
  106. break;
  107. }
  108. }
  109. if (ioread8(&rtl_table->command_status)) {
  110. RTL_DEBUG("command_status reports failed command\n");
  111. ret = -EIO;
  112. }
  113. }
  114. mutex_unlock(&rtl_lock);
  115. return ret;
  116. }
  117. static ssize_t rtl_show_version(struct device *dev,
  118. struct device_attribute *attr,
  119. char *buf)
  120. {
  121. return sprintf(buf, "%d\n", (int)ioread8(&rtl_table->version));
  122. }
  123. static ssize_t rtl_show_state(struct device *dev,
  124. struct device_attribute *attr,
  125. char *buf)
  126. {
  127. return sprintf(buf, "%d\n", ioread8(&rtl_table->rt_status));
  128. }
  129. static ssize_t rtl_set_state(struct device *dev,
  130. struct device_attribute *attr,
  131. const char *buf,
  132. size_t count)
  133. {
  134. ssize_t ret;
  135. if (count < 1 || count > 2)
  136. return -EINVAL;
  137. switch (buf[0]) {
  138. case '0':
  139. ret = ibm_rtl_write(0);
  140. break;
  141. case '1':
  142. ret = ibm_rtl_write(1);
  143. break;
  144. default:
  145. ret = -EINVAL;
  146. }
  147. if (ret >= 0)
  148. ret = count;
  149. return ret;
  150. }
  151. static struct bus_type rtl_subsys = {
  152. .name = "ibm_rtl",
  153. .dev_name = "ibm_rtl",
  154. };
  155. static DEVICE_ATTR(version, S_IRUGO, rtl_show_version, NULL);
  156. static DEVICE_ATTR(state, 0600, rtl_show_state, rtl_set_state);
  157. static struct device_attribute *rtl_attributes[] = {
  158. &dev_attr_version,
  159. &dev_attr_state,
  160. NULL
  161. };
  162. static int rtl_setup_sysfs(void) {
  163. int ret, i;
  164. ret = subsys_system_register(&rtl_subsys, NULL);
  165. if (!ret) {
  166. for (i = 0; rtl_attributes[i]; i ++)
  167. device_create_file(rtl_subsys.dev_root, rtl_attributes[i]);
  168. }
  169. return ret;
  170. }
  171. static void rtl_teardown_sysfs(void) {
  172. int i;
  173. for (i = 0; rtl_attributes[i]; i ++)
  174. device_remove_file(rtl_subsys.dev_root, rtl_attributes[i]);
  175. bus_unregister(&rtl_subsys);
  176. }
  177. static const struct dmi_system_id ibm_rtl_dmi_table[] __initconst = {
  178. { \
  179. .matches = { \
  180. DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \
  181. }, \
  182. },
  183. { }
  184. };
  185. static int __init ibm_rtl_init(void) {
  186. unsigned long ebda_addr, ebda_size;
  187. unsigned int ebda_kb;
  188. int ret = -ENODEV, i;
  189. if (force)
  190. pr_warn("module loaded by force\n");
  191. /* first ensure that we are running on IBM HW */
  192. else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table))
  193. return -ENODEV;
  194. /* Get the address for the Extended BIOS Data Area */
  195. ebda_addr = get_bios_ebda();
  196. if (!ebda_addr) {
  197. RTL_DEBUG("no BIOS EBDA found\n");
  198. return -ENODEV;
  199. }
  200. ebda_map = ioremap(ebda_addr, 4);
  201. if (!ebda_map)
  202. return -ENOMEM;
  203. /* First word in the EDBA is the Size in KB */
  204. ebda_kb = ioread16(ebda_map);
  205. RTL_DEBUG("EBDA is %d kB\n", ebda_kb);
  206. if (ebda_kb == 0)
  207. goto out;
  208. iounmap(ebda_map);
  209. ebda_size = ebda_kb*1024;
  210. /* Remap the whole table */
  211. ebda_map = ioremap(ebda_addr, ebda_size);
  212. if (!ebda_map)
  213. return -ENOMEM;
  214. /* search for the _RTL_ signature at the start of the table */
  215. for (i = 0 ; i < ebda_size/sizeof(unsigned int); i++) {
  216. struct ibm_rtl_table __iomem * tmp;
  217. tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i);
  218. if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) {
  219. phys_addr_t addr;
  220. unsigned int plen;
  221. RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp);
  222. rtl_table = tmp;
  223. /* The address, value, width and offset are platform
  224. * dependent and found in the ibm_rtl_table */
  225. rtl_cmd_width = ioread8(&rtl_table->cmd_granularity);
  226. rtl_cmd_type = ioread8(&rtl_table->cmd_address_type);
  227. RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
  228. rtl_cmd_width, rtl_cmd_type);
  229. addr = ioread32(&rtl_table->cmd_port_address);
  230. RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
  231. plen = rtl_cmd_width/sizeof(char);
  232. rtl_cmd_addr = rtl_port_map(addr, plen);
  233. RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr);
  234. if (!rtl_cmd_addr) {
  235. ret = -ENOMEM;
  236. break;
  237. }
  238. ret = rtl_setup_sysfs();
  239. break;
  240. }
  241. }
  242. out:
  243. if (ret) {
  244. iounmap(ebda_map);
  245. rtl_port_unmap(rtl_cmd_addr);
  246. }
  247. return ret;
  248. }
  249. static void __exit ibm_rtl_exit(void)
  250. {
  251. if (rtl_table) {
  252. RTL_DEBUG("cleaning up");
  253. /* do not leave the machine in SMI-free mode */
  254. ibm_rtl_write(0);
  255. /* unmap, unlink and remove all traces */
  256. rtl_teardown_sysfs();
  257. iounmap(ebda_map);
  258. rtl_port_unmap(rtl_cmd_addr);
  259. }
  260. }
  261. module_init(ibm_rtl_init);
  262. module_exit(ibm_rtl_exit);