dfl-fme-main.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Driver for FPGA Management Engine (FME)
  4. *
  5. * Copyright (C) 2017-2018 Intel Corporation, Inc.
  6. *
  7. * Authors:
  8. * Kang Luwei <luwei.kang@intel.com>
  9. * Xiao Guangrong <guangrong.xiao@linux.intel.com>
  10. * Joseph Grecco <joe.grecco@intel.com>
  11. * Enno Luebbers <enno.luebbers@intel.com>
  12. * Tim Whisonant <tim.whisonant@intel.com>
  13. * Ananda Ravuri <ananda.ravuri@intel.com>
  14. * Henry Mitchel <henry.mitchel@intel.com>
  15. */
  16. #include <linux/hwmon.h>
  17. #include <linux/hwmon-sysfs.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/units.h>
  22. #include <linux/fpga-dfl.h>
  23. #include "dfl.h"
  24. #include "dfl-fme.h"
  25. static ssize_t ports_num_show(struct device *dev,
  26. struct device_attribute *attr, char *buf)
  27. {
  28. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  29. void __iomem *base;
  30. u64 v;
  31. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  32. v = readq(base + FME_HDR_CAP);
  33. return scnprintf(buf, PAGE_SIZE, "%u\n",
  34. (unsigned int)FIELD_GET(FME_CAP_NUM_PORTS, v));
  35. }
  36. static DEVICE_ATTR_RO(ports_num);
  37. /*
  38. * Bitstream (static FPGA region) identifier number. It contains the
  39. * detailed version and other information of this static FPGA region.
  40. */
  41. static ssize_t bitstream_id_show(struct device *dev,
  42. struct device_attribute *attr, char *buf)
  43. {
  44. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  45. void __iomem *base;
  46. u64 v;
  47. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  48. v = readq(base + FME_HDR_BITSTREAM_ID);
  49. return scnprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)v);
  50. }
  51. static DEVICE_ATTR_RO(bitstream_id);
  52. /*
  53. * Bitstream (static FPGA region) meta data. It contains the synthesis
  54. * date, seed and other information of this static FPGA region.
  55. */
  56. static ssize_t bitstream_metadata_show(struct device *dev,
  57. struct device_attribute *attr, char *buf)
  58. {
  59. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  60. void __iomem *base;
  61. u64 v;
  62. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  63. v = readq(base + FME_HDR_BITSTREAM_MD);
  64. return scnprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)v);
  65. }
  66. static DEVICE_ATTR_RO(bitstream_metadata);
  67. static ssize_t cache_size_show(struct device *dev,
  68. struct device_attribute *attr, char *buf)
  69. {
  70. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  71. void __iomem *base;
  72. u64 v;
  73. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  74. v = readq(base + FME_HDR_CAP);
  75. return sprintf(buf, "%u\n",
  76. (unsigned int)FIELD_GET(FME_CAP_CACHE_SIZE, v));
  77. }
  78. static DEVICE_ATTR_RO(cache_size);
  79. static ssize_t fabric_version_show(struct device *dev,
  80. struct device_attribute *attr, char *buf)
  81. {
  82. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  83. void __iomem *base;
  84. u64 v;
  85. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  86. v = readq(base + FME_HDR_CAP);
  87. return sprintf(buf, "%u\n",
  88. (unsigned int)FIELD_GET(FME_CAP_FABRIC_VERID, v));
  89. }
  90. static DEVICE_ATTR_RO(fabric_version);
  91. static ssize_t socket_id_show(struct device *dev,
  92. struct device_attribute *attr, char *buf)
  93. {
  94. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev);
  95. void __iomem *base;
  96. u64 v;
  97. base = dfl_get_feature_ioaddr_by_id(fdata, FME_FEATURE_ID_HEADER);
  98. v = readq(base + FME_HDR_CAP);
  99. return sprintf(buf, "%u\n",
  100. (unsigned int)FIELD_GET(FME_CAP_SOCKET_ID, v));
  101. }
  102. static DEVICE_ATTR_RO(socket_id);
  103. static struct attribute *fme_hdr_attrs[] = {
  104. &dev_attr_ports_num.attr,
  105. &dev_attr_bitstream_id.attr,
  106. &dev_attr_bitstream_metadata.attr,
  107. &dev_attr_cache_size.attr,
  108. &dev_attr_fabric_version.attr,
  109. &dev_attr_socket_id.attr,
  110. NULL,
  111. };
  112. static const struct attribute_group fme_hdr_group = {
  113. .attrs = fme_hdr_attrs,
  114. };
  115. static long fme_hdr_ioctl_release_port(struct dfl_feature_dev_data *fdata,
  116. unsigned long arg)
  117. {
  118. struct dfl_fpga_cdev *cdev = fdata->dfl_cdev;
  119. int port_id;
  120. if (get_user(port_id, (int __user *)arg))
  121. return -EFAULT;
  122. return dfl_fpga_cdev_release_port(cdev, port_id);
  123. }
  124. static long fme_hdr_ioctl_assign_port(struct dfl_feature_dev_data *fdata,
  125. unsigned long arg)
  126. {
  127. struct dfl_fpga_cdev *cdev = fdata->dfl_cdev;
  128. int port_id;
  129. if (get_user(port_id, (int __user *)arg))
  130. return -EFAULT;
  131. return dfl_fpga_cdev_assign_port(cdev, port_id);
  132. }
  133. static long fme_hdr_ioctl(struct platform_device *pdev,
  134. struct dfl_feature *feature,
  135. unsigned int cmd, unsigned long arg)
  136. {
  137. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
  138. switch (cmd) {
  139. case DFL_FPGA_FME_PORT_RELEASE:
  140. return fme_hdr_ioctl_release_port(fdata, arg);
  141. case DFL_FPGA_FME_PORT_ASSIGN:
  142. return fme_hdr_ioctl_assign_port(fdata, arg);
  143. }
  144. return -ENODEV;
  145. }
  146. static const struct dfl_feature_id fme_hdr_id_table[] = {
  147. {.id = FME_FEATURE_ID_HEADER,},
  148. {0,}
  149. };
  150. static const struct dfl_feature_ops fme_hdr_ops = {
  151. .ioctl = fme_hdr_ioctl,
  152. };
  153. #define FME_THERM_THRESHOLD 0x8
  154. #define TEMP_THRESHOLD1 GENMASK_ULL(6, 0)
  155. #define TEMP_THRESHOLD1_EN BIT_ULL(7)
  156. #define TEMP_THRESHOLD2 GENMASK_ULL(14, 8)
  157. #define TEMP_THRESHOLD2_EN BIT_ULL(15)
  158. #define TRIP_THRESHOLD GENMASK_ULL(30, 24)
  159. #define TEMP_THRESHOLD1_STATUS BIT_ULL(32) /* threshold1 reached */
  160. #define TEMP_THRESHOLD2_STATUS BIT_ULL(33) /* threshold2 reached */
  161. /* threshold1 policy: 0 - AP2 (90% throttle) / 1 - AP1 (50% throttle) */
  162. #define TEMP_THRESHOLD1_POLICY BIT_ULL(44)
  163. #define FME_THERM_RDSENSOR_FMT1 0x10
  164. #define FPGA_TEMPERATURE GENMASK_ULL(6, 0)
  165. #define FME_THERM_CAP 0x20
  166. #define THERM_NO_THROTTLE BIT_ULL(0)
  167. #define MD_PRE_DEG
  168. static bool fme_thermal_throttle_support(void __iomem *base)
  169. {
  170. u64 v = readq(base + FME_THERM_CAP);
  171. return FIELD_GET(THERM_NO_THROTTLE, v) ? false : true;
  172. }
  173. static umode_t thermal_hwmon_attrs_visible(const void *drvdata,
  174. enum hwmon_sensor_types type,
  175. u32 attr, int channel)
  176. {
  177. const struct dfl_feature *feature = drvdata;
  178. /* temperature is always supported, and check hardware cap for others */
  179. if (attr == hwmon_temp_input)
  180. return 0444;
  181. return fme_thermal_throttle_support(feature->ioaddr) ? 0444 : 0;
  182. }
  183. static int thermal_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
  184. u32 attr, int channel, long *val)
  185. {
  186. struct dfl_feature *feature = dev_get_drvdata(dev);
  187. u64 v;
  188. switch (attr) {
  189. case hwmon_temp_input:
  190. v = readq(feature->ioaddr + FME_THERM_RDSENSOR_FMT1);
  191. *val = (long)(FIELD_GET(FPGA_TEMPERATURE, v) * MILLI);
  192. break;
  193. case hwmon_temp_max:
  194. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  195. *val = (long)(FIELD_GET(TEMP_THRESHOLD1, v) * MILLI);
  196. break;
  197. case hwmon_temp_crit:
  198. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  199. *val = (long)(FIELD_GET(TEMP_THRESHOLD2, v) * MILLI);
  200. break;
  201. case hwmon_temp_emergency:
  202. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  203. *val = (long)(FIELD_GET(TRIP_THRESHOLD, v) * MILLI);
  204. break;
  205. case hwmon_temp_max_alarm:
  206. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  207. *val = (long)FIELD_GET(TEMP_THRESHOLD1_STATUS, v);
  208. break;
  209. case hwmon_temp_crit_alarm:
  210. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  211. *val = (long)FIELD_GET(TEMP_THRESHOLD2_STATUS, v);
  212. break;
  213. default:
  214. return -EOPNOTSUPP;
  215. }
  216. return 0;
  217. }
  218. static const struct hwmon_ops thermal_hwmon_ops = {
  219. .is_visible = thermal_hwmon_attrs_visible,
  220. .read = thermal_hwmon_read,
  221. };
  222. static const struct hwmon_channel_info * const thermal_hwmon_info[] = {
  223. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_EMERGENCY |
  224. HWMON_T_MAX | HWMON_T_MAX_ALARM |
  225. HWMON_T_CRIT | HWMON_T_CRIT_ALARM),
  226. NULL
  227. };
  228. static const struct hwmon_chip_info thermal_hwmon_chip_info = {
  229. .ops = &thermal_hwmon_ops,
  230. .info = thermal_hwmon_info,
  231. };
  232. static ssize_t temp1_max_policy_show(struct device *dev,
  233. struct device_attribute *attr, char *buf)
  234. {
  235. struct dfl_feature *feature = dev_get_drvdata(dev);
  236. u64 v;
  237. v = readq(feature->ioaddr + FME_THERM_THRESHOLD);
  238. return sprintf(buf, "%u\n",
  239. (unsigned int)FIELD_GET(TEMP_THRESHOLD1_POLICY, v));
  240. }
  241. static DEVICE_ATTR_RO(temp1_max_policy);
  242. static struct attribute *thermal_extra_attrs[] = {
  243. &dev_attr_temp1_max_policy.attr,
  244. NULL,
  245. };
  246. static umode_t thermal_extra_attrs_visible(struct kobject *kobj,
  247. struct attribute *attr, int index)
  248. {
  249. struct device *dev = kobj_to_dev(kobj);
  250. struct dfl_feature *feature = dev_get_drvdata(dev);
  251. return fme_thermal_throttle_support(feature->ioaddr) ? attr->mode : 0;
  252. }
  253. static const struct attribute_group thermal_extra_group = {
  254. .attrs = thermal_extra_attrs,
  255. .is_visible = thermal_extra_attrs_visible,
  256. };
  257. __ATTRIBUTE_GROUPS(thermal_extra);
  258. static int fme_thermal_mgmt_init(struct platform_device *pdev,
  259. struct dfl_feature *feature)
  260. {
  261. struct device *hwmon;
  262. /*
  263. * create hwmon to allow userspace monitoring temperature and other
  264. * threshold information.
  265. *
  266. * temp1_input -> FPGA device temperature
  267. * temp1_max -> hardware threshold 1 -> 50% or 90% throttling
  268. * temp1_crit -> hardware threshold 2 -> 100% throttling
  269. * temp1_emergency -> hardware trip_threshold to shutdown FPGA
  270. * temp1_max_alarm -> hardware threshold 1 alarm
  271. * temp1_crit_alarm -> hardware threshold 2 alarm
  272. *
  273. * create device specific sysfs interfaces, e.g. read temp1_max_policy
  274. * to understand the actual hardware throttling action (50% vs 90%).
  275. *
  276. * If hardware doesn't support automatic throttling per thresholds,
  277. * then all above sysfs interfaces are not visible except temp1_input
  278. * for temperature.
  279. */
  280. hwmon = devm_hwmon_device_register_with_info(&pdev->dev,
  281. "dfl_fme_thermal", feature,
  282. &thermal_hwmon_chip_info,
  283. thermal_extra_groups);
  284. if (IS_ERR(hwmon)) {
  285. dev_err(&pdev->dev, "Fail to register thermal hwmon\n");
  286. return PTR_ERR(hwmon);
  287. }
  288. return 0;
  289. }
  290. static const struct dfl_feature_id fme_thermal_mgmt_id_table[] = {
  291. {.id = FME_FEATURE_ID_THERMAL_MGMT,},
  292. {0,}
  293. };
  294. static const struct dfl_feature_ops fme_thermal_mgmt_ops = {
  295. .init = fme_thermal_mgmt_init,
  296. };
  297. #define FME_PWR_STATUS 0x8
  298. #define FME_LATENCY_TOLERANCE BIT_ULL(18)
  299. #define PWR_CONSUMED GENMASK_ULL(17, 0)
  300. #define FME_PWR_THRESHOLD 0x10
  301. #define PWR_THRESHOLD1 GENMASK_ULL(6, 0) /* in Watts */
  302. #define PWR_THRESHOLD2 GENMASK_ULL(14, 8) /* in Watts */
  303. #define PWR_THRESHOLD_MAX 0x7f /* in Watts */
  304. #define PWR_THRESHOLD1_STATUS BIT_ULL(16)
  305. #define PWR_THRESHOLD2_STATUS BIT_ULL(17)
  306. #define FME_PWR_XEON_LIMIT 0x18
  307. #define XEON_PWR_LIMIT GENMASK_ULL(14, 0) /* in 0.1 Watts */
  308. #define XEON_PWR_EN BIT_ULL(15)
  309. #define FME_PWR_FPGA_LIMIT 0x20
  310. #define FPGA_PWR_LIMIT GENMASK_ULL(14, 0) /* in 0.1 Watts */
  311. #define FPGA_PWR_EN BIT_ULL(15)
  312. static int power_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
  313. u32 attr, int channel, long *val)
  314. {
  315. struct dfl_feature *feature = dev_get_drvdata(dev);
  316. u64 v;
  317. switch (attr) {
  318. case hwmon_power_input:
  319. v = readq(feature->ioaddr + FME_PWR_STATUS);
  320. *val = (long)(FIELD_GET(PWR_CONSUMED, v) * MICRO);
  321. break;
  322. case hwmon_power_max:
  323. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  324. *val = (long)(FIELD_GET(PWR_THRESHOLD1, v) * MICRO);
  325. break;
  326. case hwmon_power_crit:
  327. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  328. *val = (long)(FIELD_GET(PWR_THRESHOLD2, v) * MICRO);
  329. break;
  330. case hwmon_power_max_alarm:
  331. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  332. *val = (long)FIELD_GET(PWR_THRESHOLD1_STATUS, v);
  333. break;
  334. case hwmon_power_crit_alarm:
  335. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  336. *val = (long)FIELD_GET(PWR_THRESHOLD2_STATUS, v);
  337. break;
  338. default:
  339. return -EOPNOTSUPP;
  340. }
  341. return 0;
  342. }
  343. static int power_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
  344. u32 attr, int channel, long val)
  345. {
  346. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(dev->parent);
  347. struct dfl_feature *feature = dev_get_drvdata(dev);
  348. int ret = 0;
  349. u64 v;
  350. val = clamp_val(val / MICRO, 0, PWR_THRESHOLD_MAX);
  351. mutex_lock(&fdata->lock);
  352. switch (attr) {
  353. case hwmon_power_max:
  354. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  355. v &= ~PWR_THRESHOLD1;
  356. v |= FIELD_PREP(PWR_THRESHOLD1, val);
  357. writeq(v, feature->ioaddr + FME_PWR_THRESHOLD);
  358. break;
  359. case hwmon_power_crit:
  360. v = readq(feature->ioaddr + FME_PWR_THRESHOLD);
  361. v &= ~PWR_THRESHOLD2;
  362. v |= FIELD_PREP(PWR_THRESHOLD2, val);
  363. writeq(v, feature->ioaddr + FME_PWR_THRESHOLD);
  364. break;
  365. default:
  366. ret = -EOPNOTSUPP;
  367. break;
  368. }
  369. mutex_unlock(&fdata->lock);
  370. return ret;
  371. }
  372. static umode_t power_hwmon_attrs_visible(const void *drvdata,
  373. enum hwmon_sensor_types type,
  374. u32 attr, int channel)
  375. {
  376. switch (attr) {
  377. case hwmon_power_input:
  378. case hwmon_power_max_alarm:
  379. case hwmon_power_crit_alarm:
  380. return 0444;
  381. case hwmon_power_max:
  382. case hwmon_power_crit:
  383. return 0644;
  384. }
  385. return 0;
  386. }
  387. static const struct hwmon_ops power_hwmon_ops = {
  388. .is_visible = power_hwmon_attrs_visible,
  389. .read = power_hwmon_read,
  390. .write = power_hwmon_write,
  391. };
  392. static const struct hwmon_channel_info * const power_hwmon_info[] = {
  393. HWMON_CHANNEL_INFO(power, HWMON_P_INPUT |
  394. HWMON_P_MAX | HWMON_P_MAX_ALARM |
  395. HWMON_P_CRIT | HWMON_P_CRIT_ALARM),
  396. NULL
  397. };
  398. static const struct hwmon_chip_info power_hwmon_chip_info = {
  399. .ops = &power_hwmon_ops,
  400. .info = power_hwmon_info,
  401. };
  402. static ssize_t power1_xeon_limit_show(struct device *dev,
  403. struct device_attribute *attr, char *buf)
  404. {
  405. struct dfl_feature *feature = dev_get_drvdata(dev);
  406. u16 xeon_limit = 0;
  407. u64 v;
  408. v = readq(feature->ioaddr + FME_PWR_XEON_LIMIT);
  409. if (FIELD_GET(XEON_PWR_EN, v))
  410. xeon_limit = FIELD_GET(XEON_PWR_LIMIT, v);
  411. return sprintf(buf, "%u\n", xeon_limit * 100000);
  412. }
  413. static ssize_t power1_fpga_limit_show(struct device *dev,
  414. struct device_attribute *attr, char *buf)
  415. {
  416. struct dfl_feature *feature = dev_get_drvdata(dev);
  417. u16 fpga_limit = 0;
  418. u64 v;
  419. v = readq(feature->ioaddr + FME_PWR_FPGA_LIMIT);
  420. if (FIELD_GET(FPGA_PWR_EN, v))
  421. fpga_limit = FIELD_GET(FPGA_PWR_LIMIT, v);
  422. return sprintf(buf, "%u\n", fpga_limit * 100000);
  423. }
  424. static ssize_t power1_ltr_show(struct device *dev,
  425. struct device_attribute *attr, char *buf)
  426. {
  427. struct dfl_feature *feature = dev_get_drvdata(dev);
  428. u64 v;
  429. v = readq(feature->ioaddr + FME_PWR_STATUS);
  430. return sprintf(buf, "%u\n",
  431. (unsigned int)FIELD_GET(FME_LATENCY_TOLERANCE, v));
  432. }
  433. static DEVICE_ATTR_RO(power1_xeon_limit);
  434. static DEVICE_ATTR_RO(power1_fpga_limit);
  435. static DEVICE_ATTR_RO(power1_ltr);
  436. static struct attribute *power_extra_attrs[] = {
  437. &dev_attr_power1_xeon_limit.attr,
  438. &dev_attr_power1_fpga_limit.attr,
  439. &dev_attr_power1_ltr.attr,
  440. NULL
  441. };
  442. ATTRIBUTE_GROUPS(power_extra);
  443. static int fme_power_mgmt_init(struct platform_device *pdev,
  444. struct dfl_feature *feature)
  445. {
  446. struct device *hwmon;
  447. hwmon = devm_hwmon_device_register_with_info(&pdev->dev,
  448. "dfl_fme_power", feature,
  449. &power_hwmon_chip_info,
  450. power_extra_groups);
  451. if (IS_ERR(hwmon)) {
  452. dev_err(&pdev->dev, "Fail to register power hwmon\n");
  453. return PTR_ERR(hwmon);
  454. }
  455. return 0;
  456. }
  457. static const struct dfl_feature_id fme_power_mgmt_id_table[] = {
  458. {.id = FME_FEATURE_ID_POWER_MGMT,},
  459. {0,}
  460. };
  461. static const struct dfl_feature_ops fme_power_mgmt_ops = {
  462. .init = fme_power_mgmt_init,
  463. };
  464. static struct dfl_feature_driver fme_feature_drvs[] = {
  465. {
  466. .id_table = fme_hdr_id_table,
  467. .ops = &fme_hdr_ops,
  468. },
  469. {
  470. .id_table = fme_pr_mgmt_id_table,
  471. .ops = &fme_pr_mgmt_ops,
  472. },
  473. {
  474. .id_table = fme_global_err_id_table,
  475. .ops = &fme_global_err_ops,
  476. },
  477. {
  478. .id_table = fme_thermal_mgmt_id_table,
  479. .ops = &fme_thermal_mgmt_ops,
  480. },
  481. {
  482. .id_table = fme_power_mgmt_id_table,
  483. .ops = &fme_power_mgmt_ops,
  484. },
  485. {
  486. .id_table = fme_perf_id_table,
  487. .ops = &fme_perf_ops,
  488. },
  489. {
  490. .ops = NULL,
  491. },
  492. };
  493. static long fme_ioctl_check_extension(struct dfl_feature_dev_data *fdata,
  494. unsigned long arg)
  495. {
  496. /* No extension support for now */
  497. return 0;
  498. }
  499. static int fme_open(struct inode *inode, struct file *filp)
  500. {
  501. struct dfl_feature_dev_data *fdata = dfl_fpga_inode_to_feature_dev_data(inode);
  502. struct platform_device *fdev = fdata->dev;
  503. int ret;
  504. mutex_lock(&fdata->lock);
  505. ret = dfl_feature_dev_use_begin(fdata, filp->f_flags & O_EXCL);
  506. if (!ret) {
  507. dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
  508. dfl_feature_dev_use_count(fdata));
  509. filp->private_data = fdata;
  510. }
  511. mutex_unlock(&fdata->lock);
  512. return ret;
  513. }
  514. static int fme_release(struct inode *inode, struct file *filp)
  515. {
  516. struct dfl_feature_dev_data *fdata = filp->private_data;
  517. struct platform_device *pdev = fdata->dev;
  518. struct dfl_feature *feature;
  519. dev_dbg(&pdev->dev, "Device File Release\n");
  520. mutex_lock(&fdata->lock);
  521. dfl_feature_dev_use_end(fdata);
  522. if (!dfl_feature_dev_use_count(fdata))
  523. dfl_fpga_dev_for_each_feature(fdata, feature)
  524. dfl_fpga_set_irq_triggers(feature, 0,
  525. feature->nr_irqs, NULL);
  526. mutex_unlock(&fdata->lock);
  527. return 0;
  528. }
  529. static long fme_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  530. {
  531. struct dfl_feature_dev_data *fdata = filp->private_data;
  532. struct platform_device *pdev = fdata->dev;
  533. struct dfl_feature *f;
  534. long ret;
  535. dev_dbg(&pdev->dev, "%s cmd 0x%x\n", __func__, cmd);
  536. switch (cmd) {
  537. case DFL_FPGA_GET_API_VERSION:
  538. return DFL_FPGA_API_VERSION;
  539. case DFL_FPGA_CHECK_EXTENSION:
  540. return fme_ioctl_check_extension(fdata, arg);
  541. default:
  542. /*
  543. * Let sub-feature's ioctl function to handle the cmd.
  544. * Sub-feature's ioctl returns -ENODEV when cmd is not
  545. * handled in this sub feature, and returns 0 or other
  546. * error code if cmd is handled.
  547. */
  548. dfl_fpga_dev_for_each_feature(fdata, f) {
  549. if (f->ops && f->ops->ioctl) {
  550. ret = f->ops->ioctl(pdev, f, cmd, arg);
  551. if (ret != -ENODEV)
  552. return ret;
  553. }
  554. }
  555. }
  556. return -EINVAL;
  557. }
  558. static int fme_dev_init(struct platform_device *pdev)
  559. {
  560. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
  561. struct dfl_fme *fme;
  562. fme = devm_kzalloc(&pdev->dev, sizeof(*fme), GFP_KERNEL);
  563. if (!fme)
  564. return -ENOMEM;
  565. mutex_lock(&fdata->lock);
  566. dfl_fpga_fdata_set_private(fdata, fme);
  567. mutex_unlock(&fdata->lock);
  568. return 0;
  569. }
  570. static void fme_dev_destroy(struct platform_device *pdev)
  571. {
  572. struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
  573. mutex_lock(&fdata->lock);
  574. dfl_fpga_fdata_set_private(fdata, NULL);
  575. mutex_unlock(&fdata->lock);
  576. }
  577. static const struct file_operations fme_fops = {
  578. .owner = THIS_MODULE,
  579. .open = fme_open,
  580. .release = fme_release,
  581. .unlocked_ioctl = fme_ioctl,
  582. };
  583. static int fme_probe(struct platform_device *pdev)
  584. {
  585. int ret;
  586. ret = fme_dev_init(pdev);
  587. if (ret)
  588. goto exit;
  589. ret = dfl_fpga_dev_feature_init(pdev, fme_feature_drvs);
  590. if (ret)
  591. goto dev_destroy;
  592. ret = dfl_fpga_dev_ops_register(pdev, &fme_fops, THIS_MODULE);
  593. if (ret)
  594. goto feature_uinit;
  595. return 0;
  596. feature_uinit:
  597. dfl_fpga_dev_feature_uinit(pdev);
  598. dev_destroy:
  599. fme_dev_destroy(pdev);
  600. exit:
  601. return ret;
  602. }
  603. static void fme_remove(struct platform_device *pdev)
  604. {
  605. dfl_fpga_dev_ops_unregister(pdev);
  606. dfl_fpga_dev_feature_uinit(pdev);
  607. fme_dev_destroy(pdev);
  608. }
  609. static const struct attribute_group *fme_dev_groups[] = {
  610. &fme_hdr_group,
  611. &fme_global_err_group,
  612. NULL
  613. };
  614. static struct platform_driver fme_driver = {
  615. .driver = {
  616. .name = DFL_FPGA_FEATURE_DEV_FME,
  617. .dev_groups = fme_dev_groups,
  618. },
  619. .probe = fme_probe,
  620. .remove = fme_remove,
  621. };
  622. module_platform_driver(fme_driver);
  623. MODULE_DESCRIPTION("FPGA Management Engine driver");
  624. MODULE_AUTHOR("Intel Corporation");
  625. MODULE_LICENSE("GPL v2");
  626. MODULE_ALIAS("platform:dfl-fme");