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