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