mlxreg-hotplug.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Mellanox hotplug driver
  4. *
  5. * Copyright (C) 2016-2020 Mellanox Technologies
  6. */
  7. #include <linux/bitops.h>
  8. #include <linux/device.h>
  9. #include <linux/hwmon.h>
  10. #include <linux/hwmon-sysfs.h>
  11. #include <linux/i2c.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/module.h>
  14. #include <linux/of_device.h>
  15. #include <linux/platform_data/mlxreg.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/string_helpers.h>
  19. #include <linux/regmap.h>
  20. #include <linux/workqueue.h>
  21. /* Offset of event and mask registers from status register. */
  22. #define MLXREG_HOTPLUG_EVENT_OFF 1
  23. #define MLXREG_HOTPLUG_MASK_OFF 2
  24. #define MLXREG_HOTPLUG_AGGR_MASK_OFF 1
  25. /* ASIC good health mask. */
  26. #define MLXREG_HOTPLUG_GOOD_HEALTH_MASK 0x02
  27. #define MLXREG_HOTPLUG_ATTRS_MAX 128
  28. #define MLXREG_HOTPLUG_NOT_ASSERT 3
  29. /**
  30. * struct mlxreg_hotplug_priv_data - platform private data:
  31. * @irq: platform device interrupt number;
  32. * @dev: basic device;
  33. * @pdev: platform device;
  34. * @plat: platform data;
  35. * @regmap: register map handle;
  36. * @dwork_irq: delayed work template;
  37. * @lock: spin lock;
  38. * @hwmon: hwmon device;
  39. * @mlxreg_hotplug_attr: sysfs attributes array;
  40. * @mlxreg_hotplug_dev_attr: sysfs sensor device attribute array;
  41. * @group: sysfs attribute group;
  42. * @groups: list of sysfs attribute group for hwmon registration;
  43. * @cell: location of top aggregation interrupt register;
  44. * @mask: top aggregation interrupt common mask;
  45. * @aggr_cache: last value of aggregation register status;
  46. * @after_probe: flag indication probing completion;
  47. * @not_asserted: number of entries in workqueue with no signal assertion;
  48. */
  49. struct mlxreg_hotplug_priv_data {
  50. int irq;
  51. struct device *dev;
  52. struct platform_device *pdev;
  53. struct mlxreg_hotplug_platform_data *plat;
  54. struct regmap *regmap;
  55. struct delayed_work dwork_irq;
  56. spinlock_t lock; /* sync with interrupt */
  57. struct device *hwmon;
  58. struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1];
  59. struct sensor_device_attribute_2
  60. mlxreg_hotplug_dev_attr[MLXREG_HOTPLUG_ATTRS_MAX];
  61. struct attribute_group group;
  62. const struct attribute_group *groups[2];
  63. u32 cell;
  64. u32 mask;
  65. u32 aggr_cache;
  66. bool after_probe;
  67. u8 not_asserted;
  68. };
  69. /* Environment variables array for udev. */
  70. static char *mlxreg_hotplug_udev_envp[] = { NULL, NULL };
  71. static int
  72. mlxreg_hotplug_udev_event_send(struct kobject *kobj,
  73. struct mlxreg_core_data *data, bool action)
  74. {
  75. char event_str[MLXREG_CORE_LABEL_MAX_SIZE + 2];
  76. char label[MLXREG_CORE_LABEL_MAX_SIZE] = { 0 };
  77. mlxreg_hotplug_udev_envp[0] = event_str;
  78. string_upper(label, data->label);
  79. snprintf(event_str, MLXREG_CORE_LABEL_MAX_SIZE, "%s=%d", label, !!action);
  80. return kobject_uevent_env(kobj, KOBJ_CHANGE, mlxreg_hotplug_udev_envp);
  81. }
  82. static void
  83. mlxreg_hotplug_pdata_export(void *pdata, void *regmap)
  84. {
  85. struct mlxreg_core_hotplug_platform_data *dev_pdata = pdata;
  86. /* Export regmap to underlying device. */
  87. dev_pdata->regmap = regmap;
  88. }
  89. static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
  90. struct mlxreg_core_data *data,
  91. enum mlxreg_hotplug_kind kind)
  92. {
  93. struct i2c_board_info *brdinfo = data->hpdev.brdinfo;
  94. struct mlxreg_core_hotplug_platform_data *pdata;
  95. struct i2c_client *client;
  96. /* Notify user by sending hwmon uevent. */
  97. mlxreg_hotplug_udev_event_send(&priv->hwmon->kobj, data, true);
  98. /*
  99. * Return if adapter number is negative. It could be in case hotplug
  100. * event is not associated with hotplug device.
  101. */
  102. if (data->hpdev.nr < 0)
  103. return 0;
  104. pdata = dev_get_platdata(&priv->pdev->dev);
  105. switch (data->hpdev.action) {
  106. case MLXREG_HOTPLUG_DEVICE_DEFAULT_ACTION:
  107. data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr +
  108. pdata->shift_nr);
  109. if (!data->hpdev.adapter) {
  110. dev_err(priv->dev, "Failed to get adapter for bus %d\n",
  111. data->hpdev.nr + pdata->shift_nr);
  112. return -EFAULT;
  113. }
  114. /* Export platform data to underlying device. */
  115. if (brdinfo->platform_data)
  116. mlxreg_hotplug_pdata_export(brdinfo->platform_data, pdata->regmap);
  117. client = i2c_new_client_device(data->hpdev.adapter,
  118. brdinfo);
  119. if (IS_ERR(client)) {
  120. dev_err(priv->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
  121. brdinfo->type, data->hpdev.nr +
  122. pdata->shift_nr, brdinfo->addr);
  123. i2c_put_adapter(data->hpdev.adapter);
  124. data->hpdev.adapter = NULL;
  125. return PTR_ERR(client);
  126. }
  127. data->hpdev.client = client;
  128. break;
  129. case MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION:
  130. /* Export platform data to underlying device. */
  131. if (data->hpdev.brdinfo && data->hpdev.brdinfo->platform_data)
  132. mlxreg_hotplug_pdata_export(data->hpdev.brdinfo->platform_data,
  133. pdata->regmap);
  134. /* Pass parent hotplug device handle to underlying device. */
  135. data->notifier = data->hpdev.notifier;
  136. data->hpdev.pdev = platform_device_register_resndata(&priv->pdev->dev,
  137. brdinfo->type,
  138. data->hpdev.nr,
  139. NULL, 0, data,
  140. sizeof(*data));
  141. if (IS_ERR(data->hpdev.pdev))
  142. return PTR_ERR(data->hpdev.pdev);
  143. break;
  144. default:
  145. break;
  146. }
  147. if (data->hpdev.notifier && data->hpdev.notifier->user_handler)
  148. return data->hpdev.notifier->user_handler(data->hpdev.notifier->handle, kind, 1);
  149. return 0;
  150. }
  151. static void
  152. mlxreg_hotplug_device_destroy(struct mlxreg_hotplug_priv_data *priv,
  153. struct mlxreg_core_data *data,
  154. enum mlxreg_hotplug_kind kind)
  155. {
  156. /* Notify user by sending hwmon uevent. */
  157. mlxreg_hotplug_udev_event_send(&priv->hwmon->kobj, data, false);
  158. if (data->hpdev.notifier && data->hpdev.notifier->user_handler)
  159. data->hpdev.notifier->user_handler(data->hpdev.notifier->handle, kind, 0);
  160. switch (data->hpdev.action) {
  161. case MLXREG_HOTPLUG_DEVICE_DEFAULT_ACTION:
  162. if (data->hpdev.client) {
  163. i2c_unregister_device(data->hpdev.client);
  164. data->hpdev.client = NULL;
  165. }
  166. if (data->hpdev.adapter) {
  167. i2c_put_adapter(data->hpdev.adapter);
  168. data->hpdev.adapter = NULL;
  169. }
  170. break;
  171. case MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION:
  172. if (data->hpdev.pdev)
  173. platform_device_unregister(data->hpdev.pdev);
  174. break;
  175. default:
  176. break;
  177. }
  178. }
  179. static ssize_t mlxreg_hotplug_attr_show(struct device *dev,
  180. struct device_attribute *attr,
  181. char *buf)
  182. {
  183. struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(dev);
  184. struct mlxreg_core_hotplug_platform_data *pdata;
  185. int index = to_sensor_dev_attr_2(attr)->index;
  186. int nr = to_sensor_dev_attr_2(attr)->nr;
  187. struct mlxreg_core_item *item;
  188. struct mlxreg_core_data *data;
  189. u32 regval;
  190. int ret;
  191. pdata = dev_get_platdata(&priv->pdev->dev);
  192. item = pdata->items + nr;
  193. data = item->data + index;
  194. ret = regmap_read(priv->regmap, data->reg, &regval);
  195. if (ret)
  196. return ret;
  197. if (item->health) {
  198. regval &= data->mask;
  199. } else {
  200. /* Bit = 0 : functional if item->inversed is true. */
  201. if (item->inversed)
  202. regval = !(regval & data->mask);
  203. else
  204. regval = !!(regval & data->mask);
  205. }
  206. return sprintf(buf, "%u\n", regval);
  207. }
  208. #define PRIV_ATTR(i) priv->mlxreg_hotplug_attr[i]
  209. #define PRIV_DEV_ATTR(i) priv->mlxreg_hotplug_dev_attr[i]
  210. static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
  211. {
  212. struct mlxreg_core_hotplug_platform_data *pdata;
  213. struct mlxreg_core_item *item;
  214. struct mlxreg_core_data *data;
  215. unsigned long mask;
  216. u32 regval;
  217. int num_attrs = 0, id = 0, i, j, k, ret;
  218. pdata = dev_get_platdata(&priv->pdev->dev);
  219. item = pdata->items;
  220. /* Go over all kinds of items - psu, pwr, fan. */
  221. for (i = 0; i < pdata->counter; i++, item++) {
  222. if (item->capability) {
  223. /*
  224. * Read group capability register to get actual number
  225. * of interrupt capable components and set group mask
  226. * accordingly.
  227. */
  228. ret = regmap_read(priv->regmap, item->capability,
  229. &regval);
  230. if (ret)
  231. return ret;
  232. item->mask = GENMASK((regval & item->mask) - 1, 0);
  233. }
  234. data = item->data;
  235. /* Go over all unmasked units within item. */
  236. mask = item->mask;
  237. k = 0;
  238. for_each_set_bit(j, &mask, item->count) {
  239. if (data->capability) {
  240. /*
  241. * Read capability register and skip non
  242. * relevant attributes.
  243. */
  244. ret = regmap_read(priv->regmap,
  245. data->capability, &regval);
  246. if (ret)
  247. return ret;
  248. if (!(regval & data->bit)) {
  249. data++;
  250. continue;
  251. }
  252. }
  253. PRIV_ATTR(id) = &PRIV_DEV_ATTR(id).dev_attr.attr;
  254. PRIV_ATTR(id)->name = devm_kasprintf(&priv->pdev->dev,
  255. GFP_KERNEL,
  256. data->label);
  257. if (!PRIV_ATTR(id)->name) {
  258. dev_err(priv->dev, "Memory allocation failed for attr %d.\n",
  259. id);
  260. return -ENOMEM;
  261. }
  262. PRIV_DEV_ATTR(id).dev_attr.attr.name =
  263. PRIV_ATTR(id)->name;
  264. PRIV_DEV_ATTR(id).dev_attr.attr.mode = 0444;
  265. PRIV_DEV_ATTR(id).dev_attr.show =
  266. mlxreg_hotplug_attr_show;
  267. PRIV_DEV_ATTR(id).nr = i;
  268. PRIV_DEV_ATTR(id).index = k;
  269. sysfs_attr_init(&PRIV_DEV_ATTR(id).dev_attr.attr);
  270. data++;
  271. id++;
  272. k++;
  273. }
  274. num_attrs += k;
  275. }
  276. priv->group.attrs = devm_kcalloc(&priv->pdev->dev,
  277. num_attrs,
  278. sizeof(struct attribute *),
  279. GFP_KERNEL);
  280. if (!priv->group.attrs)
  281. return -ENOMEM;
  282. priv->group.attrs = priv->mlxreg_hotplug_attr;
  283. priv->groups[0] = &priv->group;
  284. priv->groups[1] = NULL;
  285. return 0;
  286. }
  287. static void
  288. mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
  289. struct mlxreg_core_item *item)
  290. {
  291. struct mlxreg_core_data *data;
  292. unsigned long asserted;
  293. u32 regval, bit;
  294. int ret;
  295. /*
  296. * Validate if item related to received signal type is valid.
  297. * It should never happen, excepted the situation when some
  298. * piece of hardware is broken. In such situation just produce
  299. * error message and return. Caller must continue to handle the
  300. * signals from other devices if any.
  301. */
  302. if (unlikely(!item)) {
  303. dev_err(priv->dev, "False signal: at offset:mask 0x%02x:0x%02x.\n",
  304. item->reg, item->mask);
  305. return;
  306. }
  307. /* Mask event. */
  308. ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
  309. 0);
  310. if (ret)
  311. goto out;
  312. /* Read status. */
  313. ret = regmap_read(priv->regmap, item->reg, &regval);
  314. if (ret)
  315. goto out;
  316. /* Set asserted bits and save last status. */
  317. regval &= item->mask;
  318. asserted = item->cache ^ regval;
  319. item->cache = regval;
  320. for_each_set_bit(bit, &asserted, 8) {
  321. data = item->data + bit;
  322. if (regval & BIT(bit)) {
  323. if (item->inversed)
  324. mlxreg_hotplug_device_destroy(priv, data, item->kind);
  325. else
  326. mlxreg_hotplug_device_create(priv, data, item->kind);
  327. } else {
  328. if (item->inversed)
  329. mlxreg_hotplug_device_create(priv, data, item->kind);
  330. else
  331. mlxreg_hotplug_device_destroy(priv, data, item->kind);
  332. }
  333. }
  334. /* Acknowledge event. */
  335. ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_EVENT_OFF,
  336. 0);
  337. if (ret)
  338. goto out;
  339. /* Unmask event. */
  340. ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
  341. item->mask);
  342. out:
  343. if (ret)
  344. dev_err(priv->dev, "Failed to complete workqueue.\n");
  345. }
  346. static void
  347. mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
  348. struct mlxreg_core_item *item)
  349. {
  350. struct mlxreg_core_data *data = item->data;
  351. u32 regval;
  352. int i, ret = 0;
  353. for (i = 0; i < item->count; i++, data++) {
  354. /* Mask event. */
  355. ret = regmap_write(priv->regmap, data->reg +
  356. MLXREG_HOTPLUG_MASK_OFF, 0);
  357. if (ret)
  358. goto out;
  359. /* Read status. */
  360. ret = regmap_read(priv->regmap, data->reg, &regval);
  361. if (ret)
  362. goto out;
  363. regval &= data->mask;
  364. if (item->cache == regval)
  365. goto ack_event;
  366. /*
  367. * ASIC health indication is provided through two bits. Bits
  368. * value 0x2 indicates that ASIC reached the good health, value
  369. * 0x0 indicates ASIC the bad health or dormant state and value
  370. * 0x3 indicates the booting state. During ASIC reset it should
  371. * pass the following states: dormant -> booting -> good.
  372. */
  373. if (regval == MLXREG_HOTPLUG_GOOD_HEALTH_MASK) {
  374. if (!data->attached) {
  375. /*
  376. * ASIC is in steady state. Connect associated
  377. * device, if configured.
  378. */
  379. mlxreg_hotplug_device_create(priv, data, item->kind);
  380. data->attached = true;
  381. }
  382. } else {
  383. if (data->attached) {
  384. /*
  385. * ASIC health is failed after ASIC has been
  386. * in steady state. Disconnect associated
  387. * device, if it has been connected.
  388. */
  389. mlxreg_hotplug_device_destroy(priv, data, item->kind);
  390. data->attached = false;
  391. data->health_cntr = 0;
  392. }
  393. }
  394. item->cache = regval;
  395. ack_event:
  396. /* Acknowledge event. */
  397. ret = regmap_write(priv->regmap, data->reg +
  398. MLXREG_HOTPLUG_EVENT_OFF, 0);
  399. if (ret)
  400. goto out;
  401. /* Unmask event. */
  402. ret = regmap_write(priv->regmap, data->reg +
  403. MLXREG_HOTPLUG_MASK_OFF, data->mask);
  404. if (ret)
  405. goto out;
  406. }
  407. out:
  408. if (ret)
  409. dev_err(priv->dev, "Failed to complete workqueue.\n");
  410. }
  411. /*
  412. * mlxreg_hotplug_work_handler - performs traversing of device interrupt
  413. * registers according to the below hierarchy schema:
  414. *
  415. * Aggregation registers (status/mask)
  416. * PSU registers: *---*
  417. * *-----------------* | |
  418. * |status/event/mask|-----> | * |
  419. * *-----------------* | |
  420. * Power registers: | |
  421. * *-----------------* | |
  422. * |status/event/mask|-----> | * |
  423. * *-----------------* | |
  424. * FAN registers: | |--> CPU
  425. * *-----------------* | |
  426. * |status/event/mask|-----> | * |
  427. * *-----------------* | |
  428. * ASIC registers: | |
  429. * *-----------------* | |
  430. * |status/event/mask|-----> | * |
  431. * *-----------------* | |
  432. * *---*
  433. *
  434. * In case some system changed are detected: FAN in/out, PSU in/out, power
  435. * cable attached/detached, ASIC health good/bad, relevant device is created
  436. * or destroyed.
  437. */
  438. static void mlxreg_hotplug_work_handler(struct work_struct *work)
  439. {
  440. struct mlxreg_core_hotplug_platform_data *pdata;
  441. struct mlxreg_hotplug_priv_data *priv;
  442. struct mlxreg_core_item *item;
  443. u32 regval, aggr_asserted;
  444. unsigned long flags;
  445. int i, ret;
  446. priv = container_of(work, struct mlxreg_hotplug_priv_data,
  447. dwork_irq.work);
  448. pdata = dev_get_platdata(&priv->pdev->dev);
  449. item = pdata->items;
  450. /* Mask aggregation event. */
  451. ret = regmap_write(priv->regmap, pdata->cell +
  452. MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
  453. if (ret < 0)
  454. goto out;
  455. /* Read aggregation status. */
  456. ret = regmap_read(priv->regmap, pdata->cell, &regval);
  457. if (ret)
  458. goto out;
  459. regval &= pdata->mask;
  460. aggr_asserted = priv->aggr_cache ^ regval;
  461. priv->aggr_cache = regval;
  462. /*
  463. * Handler is invoked, but no assertion is detected at top aggregation
  464. * status level. Set aggr_asserted to mask value to allow handler extra
  465. * run over all relevant signals to recover any missed signal.
  466. */
  467. if (priv->not_asserted == MLXREG_HOTPLUG_NOT_ASSERT) {
  468. priv->not_asserted = 0;
  469. aggr_asserted = pdata->mask;
  470. }
  471. if (!aggr_asserted)
  472. goto unmask_event;
  473. /* Handle topology and health configuration changes. */
  474. for (i = 0; i < pdata->counter; i++, item++) {
  475. if (aggr_asserted & item->aggr_mask) {
  476. if (item->health)
  477. mlxreg_hotplug_health_work_helper(priv, item);
  478. else
  479. mlxreg_hotplug_work_helper(priv, item);
  480. }
  481. }
  482. spin_lock_irqsave(&priv->lock, flags);
  483. /*
  484. * It is possible, that some signals have been inserted, while
  485. * interrupt has been masked by mlxreg_hotplug_work_handler. In this
  486. * case such signals will be missed. In order to handle these signals
  487. * delayed work is canceled and work task re-scheduled for immediate
  488. * execution. It allows to handle missed signals, if any. In other case
  489. * work handler just validates that no new signals have been received
  490. * during masking.
  491. */
  492. cancel_delayed_work(&priv->dwork_irq);
  493. schedule_delayed_work(&priv->dwork_irq, 0);
  494. spin_unlock_irqrestore(&priv->lock, flags);
  495. return;
  496. unmask_event:
  497. priv->not_asserted++;
  498. /* Unmask aggregation event (no need acknowledge). */
  499. ret = regmap_write(priv->regmap, pdata->cell +
  500. MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
  501. out:
  502. if (ret)
  503. dev_err(priv->dev, "Failed to complete workqueue.\n");
  504. }
  505. static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
  506. {
  507. struct mlxreg_core_hotplug_platform_data *pdata;
  508. struct mlxreg_core_item *item;
  509. struct mlxreg_core_data *data;
  510. u32 regval;
  511. int i, j, ret;
  512. pdata = dev_get_platdata(&priv->pdev->dev);
  513. item = pdata->items;
  514. for (i = 0; i < pdata->counter; i++, item++) {
  515. /* Clear group presense event. */
  516. ret = regmap_write(priv->regmap, item->reg +
  517. MLXREG_HOTPLUG_EVENT_OFF, 0);
  518. if (ret)
  519. goto out;
  520. /*
  521. * Verify if hardware configuration requires to disable
  522. * interrupt capability for some of components.
  523. */
  524. data = item->data;
  525. for (j = 0; j < item->count; j++, data++) {
  526. /* Verify if the attribute has capability register. */
  527. if (data->capability) {
  528. /* Read capability register. */
  529. ret = regmap_read(priv->regmap,
  530. data->capability, &regval);
  531. if (ret)
  532. goto out;
  533. if (!(regval & data->bit))
  534. item->mask &= ~BIT(j);
  535. }
  536. }
  537. /* Set group initial status as mask and unmask group event. */
  538. if (item->inversed) {
  539. item->cache = item->mask;
  540. ret = regmap_write(priv->regmap, item->reg +
  541. MLXREG_HOTPLUG_MASK_OFF,
  542. item->mask);
  543. if (ret)
  544. goto out;
  545. }
  546. }
  547. /* Keep aggregation initial status as zero and unmask events. */
  548. ret = regmap_write(priv->regmap, pdata->cell +
  549. MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
  550. if (ret)
  551. goto out;
  552. /* Keep low aggregation initial status as zero and unmask events. */
  553. if (pdata->cell_low) {
  554. ret = regmap_write(priv->regmap, pdata->cell_low +
  555. MLXREG_HOTPLUG_AGGR_MASK_OFF,
  556. pdata->mask_low);
  557. if (ret)
  558. goto out;
  559. }
  560. /* Invoke work handler for initializing hot plug devices setting. */
  561. mlxreg_hotplug_work_handler(&priv->dwork_irq.work);
  562. out:
  563. if (ret)
  564. dev_err(priv->dev, "Failed to set interrupts.\n");
  565. enable_irq(priv->irq);
  566. return ret;
  567. }
  568. static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
  569. {
  570. struct mlxreg_core_hotplug_platform_data *pdata;
  571. struct mlxreg_core_item *item;
  572. struct mlxreg_core_data *data;
  573. int count, i, j;
  574. pdata = dev_get_platdata(&priv->pdev->dev);
  575. item = pdata->items;
  576. disable_irq(priv->irq);
  577. cancel_delayed_work_sync(&priv->dwork_irq);
  578. /* Mask low aggregation event, if defined. */
  579. if (pdata->cell_low)
  580. regmap_write(priv->regmap, pdata->cell_low +
  581. MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
  582. /* Mask aggregation event. */
  583. regmap_write(priv->regmap, pdata->cell + MLXREG_HOTPLUG_AGGR_MASK_OFF,
  584. 0);
  585. /* Clear topology configurations. */
  586. for (i = 0; i < pdata->counter; i++, item++) {
  587. data = item->data;
  588. /* Mask group presense event. */
  589. regmap_write(priv->regmap, data->reg + MLXREG_HOTPLUG_MASK_OFF,
  590. 0);
  591. /* Clear group presense event. */
  592. regmap_write(priv->regmap, data->reg +
  593. MLXREG_HOTPLUG_EVENT_OFF, 0);
  594. /* Remove all the attached devices in group. */
  595. count = item->count;
  596. for (j = 0; j < count; j++, data++)
  597. mlxreg_hotplug_device_destroy(priv, data, item->kind);
  598. }
  599. }
  600. static irqreturn_t mlxreg_hotplug_irq_handler(int irq, void *dev)
  601. {
  602. struct mlxreg_hotplug_priv_data *priv;
  603. priv = (struct mlxreg_hotplug_priv_data *)dev;
  604. /* Schedule work task for immediate execution.*/
  605. schedule_delayed_work(&priv->dwork_irq, 0);
  606. return IRQ_HANDLED;
  607. }
  608. static int mlxreg_hotplug_probe(struct platform_device *pdev)
  609. {
  610. struct mlxreg_core_hotplug_platform_data *pdata;
  611. struct mlxreg_hotplug_priv_data *priv;
  612. struct i2c_adapter *deferred_adap;
  613. int err;
  614. pdata = dev_get_platdata(&pdev->dev);
  615. if (!pdata) {
  616. dev_err(&pdev->dev, "Failed to get platform data.\n");
  617. return -EINVAL;
  618. }
  619. /* Defer probing if the necessary adapter is not configured yet. */
  620. deferred_adap = i2c_get_adapter(pdata->deferred_nr);
  621. if (!deferred_adap)
  622. return -EPROBE_DEFER;
  623. i2c_put_adapter(deferred_adap);
  624. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  625. if (!priv)
  626. return -ENOMEM;
  627. if (pdata->irq) {
  628. priv->irq = pdata->irq;
  629. } else {
  630. priv->irq = platform_get_irq(pdev, 0);
  631. if (priv->irq < 0)
  632. return priv->irq;
  633. }
  634. priv->regmap = pdata->regmap;
  635. priv->dev = pdev->dev.parent;
  636. priv->pdev = pdev;
  637. err = devm_request_irq(&pdev->dev, priv->irq,
  638. mlxreg_hotplug_irq_handler, IRQF_TRIGGER_FALLING
  639. | IRQF_SHARED, "mlxreg-hotplug", priv);
  640. if (err) {
  641. dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
  642. return err;
  643. }
  644. disable_irq(priv->irq);
  645. spin_lock_init(&priv->lock);
  646. INIT_DELAYED_WORK(&priv->dwork_irq, mlxreg_hotplug_work_handler);
  647. dev_set_drvdata(&pdev->dev, priv);
  648. err = mlxreg_hotplug_attr_init(priv);
  649. if (err) {
  650. dev_err(&pdev->dev, "Failed to allocate attributes: %d\n",
  651. err);
  652. return err;
  653. }
  654. priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
  655. "mlxreg_hotplug", priv, priv->groups);
  656. if (IS_ERR(priv->hwmon)) {
  657. dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
  658. PTR_ERR(priv->hwmon));
  659. return PTR_ERR(priv->hwmon);
  660. }
  661. /* Perform initial interrupts setup. */
  662. mlxreg_hotplug_set_irq(priv);
  663. priv->after_probe = true;
  664. return 0;
  665. }
  666. static int mlxreg_hotplug_remove(struct platform_device *pdev)
  667. {
  668. struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(&pdev->dev);
  669. /* Clean interrupts setup. */
  670. mlxreg_hotplug_unset_irq(priv);
  671. devm_free_irq(&pdev->dev, priv->irq, priv);
  672. return 0;
  673. }
  674. static struct platform_driver mlxreg_hotplug_driver = {
  675. .driver = {
  676. .name = "mlxreg-hotplug",
  677. },
  678. .probe = mlxreg_hotplug_probe,
  679. .remove = mlxreg_hotplug_remove,
  680. };
  681. module_platform_driver(mlxreg_hotplug_driver);
  682. MODULE_AUTHOR("Vadim Pasternak <[email protected]>");
  683. MODULE_DESCRIPTION("Mellanox regmap hotplug platform driver");
  684. MODULE_LICENSE("Dual BSD/GPL");
  685. MODULE_ALIAS("platform:mlxreg-hotplug");