1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Framework for Ethernet Power Sourcing Equipment
4//
5// Copyright (c) 2022 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
6//
7
8#include <linux/device.h>
9#include <linux/ethtool.h>
10#include <linux/of.h>
11#include <linux/pse-pd/pse.h>
12#include <linux/regulator/driver.h>
13#include <linux/regulator/machine.h>
14
15static DEFINE_MUTEX(pse_list_mutex);
16static LIST_HEAD(pse_controller_list);
17
18/**
19 * struct pse_control - a PSE control
20 * @pcdev: a pointer to the PSE controller device
21 * this PSE control belongs to
22 * @ps: PSE PI supply of the PSE control
23 * @list: list entry for the pcdev's PSE controller list
24 * @id: ID of the PSE line in the PSE controller device
25 * @refcnt: Number of gets of this pse_control
26 */
27struct pse_control {
28 struct pse_controller_dev *pcdev;
29 struct regulator *ps;
30 struct list_head list;
31 unsigned int id;
32 struct kref refcnt;
33};
34
35static int of_load_single_pse_pi_pairset(struct device_node *node,
36 struct pse_pi *pi,
37 int pairset_num)
38{
39 struct device_node *pairset_np;
40 const char *name;
41 int ret;
42
43 ret = of_property_read_string_index(np: node, propname: "pairset-names",
44 index: pairset_num, output: &name);
45 if (ret)
46 return ret;
47
48 if (!strcmp(name, "alternative-a")) {
49 pi->pairset[pairset_num].pinout = ALTERNATIVE_A;
50 } else if (!strcmp(name, "alternative-b")) {
51 pi->pairset[pairset_num].pinout = ALTERNATIVE_B;
52 } else {
53 pr_err("pse: wrong pairset-names value %s (%pOF)\n",
54 name, node);
55 return -EINVAL;
56 }
57
58 pairset_np = of_parse_phandle(np: node, phandle_name: "pairsets", index: pairset_num);
59 if (!pairset_np)
60 return -ENODEV;
61
62 pi->pairset[pairset_num].np = pairset_np;
63
64 return 0;
65}
66
67/**
68 * of_load_pse_pi_pairsets - load PSE PI pairsets pinout and polarity
69 * @node: a pointer of the device node
70 * @pi: a pointer of the PSE PI to fill
71 * @npairsets: the number of pairsets (1 or 2) used by the PI
72 *
73 * Return: 0 on success and failure value on error
74 */
75static int of_load_pse_pi_pairsets(struct device_node *node,
76 struct pse_pi *pi,
77 int npairsets)
78{
79 int i, ret;
80
81 ret = of_property_count_strings(np: node, propname: "pairset-names");
82 if (ret != npairsets) {
83 pr_err("pse: amount of pairsets and pairset-names is not equal %d != %d (%pOF)\n",
84 npairsets, ret, node);
85 return -EINVAL;
86 }
87
88 for (i = 0; i < npairsets; i++) {
89 ret = of_load_single_pse_pi_pairset(node, pi, pairset_num: i);
90 if (ret)
91 goto out;
92 }
93
94 if (npairsets == 2 &&
95 pi->pairset[0].pinout == pi->pairset[1].pinout) {
96 pr_err("pse: two PI pairsets can not have identical pinout (%pOF)",
97 node);
98 ret = -EINVAL;
99 }
100
101out:
102 /* If an error appears, release all the pairset device node kref */
103 if (ret) {
104 of_node_put(node: pi->pairset[0].np);
105 pi->pairset[0].np = NULL;
106 of_node_put(node: pi->pairset[1].np);
107 pi->pairset[1].np = NULL;
108 }
109
110 return ret;
111}
112
113static void pse_release_pis(struct pse_controller_dev *pcdev)
114{
115 int i;
116
117 for (i = 0; i < pcdev->nr_lines; i++) {
118 of_node_put(node: pcdev->pi[i].pairset[0].np);
119 of_node_put(node: pcdev->pi[i].pairset[1].np);
120 of_node_put(node: pcdev->pi[i].np);
121 }
122 kfree(objp: pcdev->pi);
123}
124
125/**
126 * of_load_pse_pis - load all the PSE PIs
127 * @pcdev: a pointer to the PSE controller device
128 *
129 * Return: 0 on success and failure value on error
130 */
131static int of_load_pse_pis(struct pse_controller_dev *pcdev)
132{
133 struct device_node *np = pcdev->dev->of_node;
134 struct device_node *node, *pis;
135 int ret;
136
137 if (!np)
138 return -ENODEV;
139
140 pcdev->pi = kcalloc(pcdev->nr_lines, sizeof(*pcdev->pi), GFP_KERNEL);
141 if (!pcdev->pi)
142 return -ENOMEM;
143
144 pis = of_get_child_by_name(node: np, name: "pse-pis");
145 if (!pis) {
146 /* no description of PSE PIs */
147 pcdev->no_of_pse_pi = true;
148 return 0;
149 }
150
151 for_each_child_of_node(pis, node) {
152 struct pse_pi pi = {0};
153 u32 id;
154
155 if (!of_node_name_eq(np: node, name: "pse-pi"))
156 continue;
157
158 ret = of_property_read_u32(np: node, propname: "reg", out_value: &id);
159 if (ret) {
160 dev_err(pcdev->dev,
161 "can't get reg property for node '%pOF'",
162 node);
163 goto out;
164 }
165
166 if (id >= pcdev->nr_lines) {
167 dev_err(pcdev->dev,
168 "reg value (%u) is out of range (%u) (%pOF)\n",
169 id, pcdev->nr_lines, node);
170 ret = -EINVAL;
171 goto out;
172 }
173
174 if (pcdev->pi[id].np) {
175 dev_err(pcdev->dev,
176 "other node with same reg value was already registered. %pOF : %pOF\n",
177 pcdev->pi[id].np, node);
178 ret = -EINVAL;
179 goto out;
180 }
181
182 ret = of_count_phandle_with_args(np: node, list_name: "pairsets", NULL);
183 /* npairsets is limited to value one or two */
184 if (ret == 1 || ret == 2) {
185 ret = of_load_pse_pi_pairsets(node, pi: &pi, npairsets: ret);
186 if (ret)
187 goto out;
188 } else if (ret != ENOENT) {
189 dev_err(pcdev->dev,
190 "error: wrong number of pairsets. Should be 1 or 2, got %d (%pOF)\n",
191 ret, node);
192 ret = -EINVAL;
193 goto out;
194 }
195
196 of_node_get(node);
197 pi.np = node;
198 memcpy(&pcdev->pi[id], &pi, sizeof(pi));
199 }
200
201 of_node_put(node: pis);
202 return 0;
203
204out:
205 pse_release_pis(pcdev);
206 of_node_put(node);
207 of_node_put(node: pis);
208 return ret;
209}
210
211static int pse_pi_is_enabled(struct regulator_dev *rdev)
212{
213 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
214 struct pse_admin_state admin_state = {0};
215 const struct pse_controller_ops *ops;
216 int id, ret;
217
218 ops = pcdev->ops;
219 if (!ops->pi_get_admin_state)
220 return -EOPNOTSUPP;
221
222 id = rdev_get_id(rdev);
223 mutex_lock(&pcdev->lock);
224 ret = ops->pi_get_admin_state(pcdev, id, &admin_state);
225 if (ret)
226 goto out;
227
228 if (admin_state.podl_admin_state == ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED ||
229 admin_state.c33_admin_state == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
230 ret = 1;
231
232out:
233 mutex_unlock(lock: &pcdev->lock);
234
235 return ret;
236}
237
238static int pse_pi_enable(struct regulator_dev *rdev)
239{
240 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
241 const struct pse_controller_ops *ops;
242 int id, ret;
243
244 ops = pcdev->ops;
245 if (!ops->pi_enable)
246 return -EOPNOTSUPP;
247
248 id = rdev_get_id(rdev);
249 mutex_lock(&pcdev->lock);
250 ret = ops->pi_enable(pcdev, id);
251 if (!ret)
252 pcdev->pi[id].admin_state_enabled = 1;
253 mutex_unlock(lock: &pcdev->lock);
254
255 return ret;
256}
257
258static int pse_pi_disable(struct regulator_dev *rdev)
259{
260 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
261 const struct pse_controller_ops *ops;
262 int id, ret;
263
264 ops = pcdev->ops;
265 if (!ops->pi_disable)
266 return -EOPNOTSUPP;
267
268 id = rdev_get_id(rdev);
269 mutex_lock(&pcdev->lock);
270 ret = ops->pi_disable(pcdev, id);
271 if (!ret)
272 pcdev->pi[id].admin_state_enabled = 0;
273 mutex_unlock(lock: &pcdev->lock);
274
275 return ret;
276}
277
278static int _pse_pi_get_voltage(struct regulator_dev *rdev)
279{
280 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
281 const struct pse_controller_ops *ops;
282 int id;
283
284 ops = pcdev->ops;
285 if (!ops->pi_get_voltage)
286 return -EOPNOTSUPP;
287
288 id = rdev_get_id(rdev);
289 return ops->pi_get_voltage(pcdev, id);
290}
291
292static int pse_pi_get_voltage(struct regulator_dev *rdev)
293{
294 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
295 int ret;
296
297 mutex_lock(&pcdev->lock);
298 ret = _pse_pi_get_voltage(rdev);
299 mutex_unlock(lock: &pcdev->lock);
300
301 return ret;
302}
303
304static int pse_pi_get_current_limit(struct regulator_dev *rdev)
305{
306 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
307 const struct pse_controller_ops *ops;
308 int id, uV, mW, ret;
309 s64 tmp_64;
310
311 ops = pcdev->ops;
312 id = rdev_get_id(rdev);
313 if (!ops->pi_get_pw_limit || !ops->pi_get_voltage)
314 return -EOPNOTSUPP;
315
316 mutex_lock(&pcdev->lock);
317 ret = ops->pi_get_pw_limit(pcdev, id);
318 if (ret < 0)
319 goto out;
320 mW = ret;
321
322 ret = _pse_pi_get_voltage(rdev);
323 if (!ret) {
324 dev_err(pcdev->dev, "Voltage null\n");
325 ret = -ERANGE;
326 goto out;
327 }
328 if (ret < 0)
329 goto out;
330 uV = ret;
331
332 tmp_64 = mW;
333 tmp_64 *= 1000000000ull;
334 /* uA = mW * 1000000000 / uV */
335 ret = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
336
337out:
338 mutex_unlock(lock: &pcdev->lock);
339 return ret;
340}
341
342static int pse_pi_set_current_limit(struct regulator_dev *rdev, int min_uA,
343 int max_uA)
344{
345 struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
346 const struct pse_controller_ops *ops;
347 int id, mW, ret;
348 s64 tmp_64;
349
350 ops = pcdev->ops;
351 if (!ops->pi_set_pw_limit || !ops->pi_get_voltage)
352 return -EOPNOTSUPP;
353
354 if (max_uA > MAX_PI_CURRENT)
355 return -ERANGE;
356
357 id = rdev_get_id(rdev);
358 mutex_lock(&pcdev->lock);
359 ret = _pse_pi_get_voltage(rdev);
360 if (!ret) {
361 dev_err(pcdev->dev, "Voltage null\n");
362 ret = -ERANGE;
363 goto out;
364 }
365 if (ret < 0)
366 goto out;
367
368 tmp_64 = ret;
369 tmp_64 *= max_uA;
370 /* mW = uA * uV / 1000000000 */
371 mW = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
372 ret = ops->pi_set_pw_limit(pcdev, id, mW);
373out:
374 mutex_unlock(lock: &pcdev->lock);
375
376 return ret;
377}
378
379static const struct regulator_ops pse_pi_ops = {
380 .is_enabled = pse_pi_is_enabled,
381 .enable = pse_pi_enable,
382 .disable = pse_pi_disable,
383 .get_voltage = pse_pi_get_voltage,
384 .get_current_limit = pse_pi_get_current_limit,
385 .set_current_limit = pse_pi_set_current_limit,
386};
387
388static int
389devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev,
390 char *name, int id)
391{
392 struct regulator_init_data *rinit_data;
393 struct regulator_config rconfig = {0};
394 struct regulator_desc *rdesc;
395 struct regulator_dev *rdev;
396
397 rinit_data = devm_kzalloc(dev: pcdev->dev, size: sizeof(*rinit_data),
398 GFP_KERNEL);
399 if (!rinit_data)
400 return -ENOMEM;
401
402 rdesc = devm_kzalloc(dev: pcdev->dev, size: sizeof(*rdesc), GFP_KERNEL);
403 if (!rdesc)
404 return -ENOMEM;
405
406 /* Regulator descriptor id have to be the same as its associated
407 * PSE PI id for the well functioning of the PSE controls.
408 */
409 rdesc->id = id;
410 rdesc->name = name;
411 rdesc->type = REGULATOR_VOLTAGE;
412 rdesc->ops = &pse_pi_ops;
413 rdesc->owner = pcdev->owner;
414
415 rinit_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
416
417 if (pcdev->ops->pi_set_pw_limit)
418 rinit_data->constraints.valid_ops_mask |=
419 REGULATOR_CHANGE_CURRENT;
420
421 rinit_data->supply_regulator = "vpwr";
422
423 rconfig.dev = pcdev->dev;
424 rconfig.driver_data = pcdev;
425 rconfig.init_data = rinit_data;
426 rconfig.of_node = pcdev->pi[id].np;
427
428 rdev = devm_regulator_register(dev: pcdev->dev, regulator_desc: rdesc, config: &rconfig);
429 if (IS_ERR(ptr: rdev)) {
430 dev_err_probe(dev: pcdev->dev, err: PTR_ERR(ptr: rdev),
431 fmt: "Failed to register regulator\n");
432 return PTR_ERR(ptr: rdev);
433 }
434
435 pcdev->pi[id].rdev = rdev;
436
437 return 0;
438}
439
440/**
441 * pse_controller_register - register a PSE controller device
442 * @pcdev: a pointer to the initialized PSE controller device
443 *
444 * Return: 0 on success and failure value on error
445 */
446int pse_controller_register(struct pse_controller_dev *pcdev)
447{
448 size_t reg_name_len;
449 int ret, i;
450
451 mutex_init(&pcdev->lock);
452 INIT_LIST_HEAD(list: &pcdev->pse_control_head);
453
454 if (!pcdev->nr_lines)
455 pcdev->nr_lines = 1;
456
457 if (!pcdev->ops->pi_get_admin_state ||
458 !pcdev->ops->pi_get_pw_status) {
459 dev_err(pcdev->dev,
460 "Mandatory status report callbacks are missing");
461 return -EINVAL;
462 }
463
464 ret = of_load_pse_pis(pcdev);
465 if (ret)
466 return ret;
467
468 if (pcdev->ops->setup_pi_matrix) {
469 ret = pcdev->ops->setup_pi_matrix(pcdev);
470 if (ret)
471 return ret;
472 }
473
474 /* Each regulator name len is pcdev dev name + 7 char +
475 * int max digit number (10) + 1
476 */
477 reg_name_len = strlen(dev_name(pcdev->dev)) + 18;
478
479 /* Register PI regulators */
480 for (i = 0; i < pcdev->nr_lines; i++) {
481 char *reg_name;
482
483 /* Do not register regulator for PIs not described */
484 if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
485 continue;
486
487 reg_name = devm_kzalloc(dev: pcdev->dev, size: reg_name_len, GFP_KERNEL);
488 if (!reg_name)
489 return -ENOMEM;
490
491 snprintf(buf: reg_name, size: reg_name_len, fmt: "pse-%s_pi%d",
492 dev_name(dev: pcdev->dev), i);
493
494 ret = devm_pse_pi_regulator_register(pcdev, name: reg_name, id: i);
495 if (ret)
496 return ret;
497 }
498
499 mutex_lock(&pse_list_mutex);
500 list_add(new: &pcdev->list, head: &pse_controller_list);
501 mutex_unlock(lock: &pse_list_mutex);
502
503 return 0;
504}
505EXPORT_SYMBOL_GPL(pse_controller_register);
506
507/**
508 * pse_controller_unregister - unregister a PSE controller device
509 * @pcdev: a pointer to the PSE controller device
510 */
511void pse_controller_unregister(struct pse_controller_dev *pcdev)
512{
513 pse_release_pis(pcdev);
514 mutex_lock(&pse_list_mutex);
515 list_del(entry: &pcdev->list);
516 mutex_unlock(lock: &pse_list_mutex);
517}
518EXPORT_SYMBOL_GPL(pse_controller_unregister);
519
520static void devm_pse_controller_release(struct device *dev, void *res)
521{
522 pse_controller_unregister(*(struct pse_controller_dev **)res);
523}
524
525/**
526 * devm_pse_controller_register - resource managed pse_controller_register()
527 * @dev: device that is registering this PSE controller
528 * @pcdev: a pointer to the initialized PSE controller device
529 *
530 * Managed pse_controller_register(). For PSE controllers registered by
531 * this function, pse_controller_unregister() is automatically called on
532 * driver detach. See pse_controller_register() for more information.
533 *
534 * Return: 0 on success and failure value on error
535 */
536int devm_pse_controller_register(struct device *dev,
537 struct pse_controller_dev *pcdev)
538{
539 struct pse_controller_dev **pcdevp;
540 int ret;
541
542 pcdevp = devres_alloc(devm_pse_controller_release, sizeof(*pcdevp),
543 GFP_KERNEL);
544 if (!pcdevp)
545 return -ENOMEM;
546
547 ret = pse_controller_register(pcdev);
548 if (ret) {
549 devres_free(res: pcdevp);
550 return ret;
551 }
552
553 *pcdevp = pcdev;
554 devres_add(dev, res: pcdevp);
555
556 return 0;
557}
558EXPORT_SYMBOL_GPL(devm_pse_controller_register);
559
560/* PSE control section */
561
562static void __pse_control_release(struct kref *kref)
563{
564 struct pse_control *psec = container_of(kref, struct pse_control,
565 refcnt);
566
567 lockdep_assert_held(&pse_list_mutex);
568
569 if (psec->pcdev->pi[psec->id].admin_state_enabled)
570 regulator_disable(regulator: psec->ps);
571 devm_regulator_put(regulator: psec->ps);
572
573 module_put(module: psec->pcdev->owner);
574
575 list_del(entry: &psec->list);
576 kfree(objp: psec);
577}
578
579static void __pse_control_put_internal(struct pse_control *psec)
580{
581 lockdep_assert_held(&pse_list_mutex);
582
583 kref_put(kref: &psec->refcnt, release: __pse_control_release);
584}
585
586/**
587 * pse_control_put - free the PSE control
588 * @psec: PSE control pointer
589 */
590void pse_control_put(struct pse_control *psec)
591{
592 if (IS_ERR_OR_NULL(ptr: psec))
593 return;
594
595 mutex_lock(&pse_list_mutex);
596 __pse_control_put_internal(psec);
597 mutex_unlock(lock: &pse_list_mutex);
598}
599EXPORT_SYMBOL_GPL(pse_control_put);
600
601static struct pse_control *
602pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
603{
604 struct pse_control *psec;
605 int ret;
606
607 lockdep_assert_held(&pse_list_mutex);
608
609 list_for_each_entry(psec, &pcdev->pse_control_head, list) {
610 if (psec->id == index) {
611 kref_get(kref: &psec->refcnt);
612 return psec;
613 }
614 }
615
616 psec = kzalloc(sizeof(*psec), GFP_KERNEL);
617 if (!psec)
618 return ERR_PTR(error: -ENOMEM);
619
620 if (!try_module_get(module: pcdev->owner)) {
621 ret = -ENODEV;
622 goto free_psec;
623 }
624
625 psec->ps = devm_regulator_get_exclusive(dev: pcdev->dev,
626 id: rdev_get_name(rdev: pcdev->pi[index].rdev));
627 if (IS_ERR(ptr: psec->ps)) {
628 ret = PTR_ERR(ptr: psec->ps);
629 goto put_module;
630 }
631
632 ret = regulator_is_enabled(regulator: psec->ps);
633 if (ret < 0)
634 goto regulator_put;
635
636 pcdev->pi[index].admin_state_enabled = ret;
637
638 psec->pcdev = pcdev;
639 list_add(new: &psec->list, head: &pcdev->pse_control_head);
640 psec->id = index;
641 kref_init(kref: &psec->refcnt);
642
643 return psec;
644
645regulator_put:
646 devm_regulator_put(regulator: psec->ps);
647put_module:
648 module_put(module: pcdev->owner);
649free_psec:
650 kfree(objp: psec);
651
652 return ERR_PTR(error: ret);
653}
654
655/**
656 * of_pse_match_pi - Find the PSE PI id matching the device node phandle
657 * @pcdev: a pointer to the PSE controller device
658 * @np: a pointer to the device node
659 *
660 * Return: id of the PSE PI, -EINVAL if not found
661 */
662static int of_pse_match_pi(struct pse_controller_dev *pcdev,
663 struct device_node *np)
664{
665 int i;
666
667 for (i = 0; i < pcdev->nr_lines; i++) {
668 if (pcdev->pi[i].np == np)
669 return i;
670 }
671
672 return -EINVAL;
673}
674
675/**
676 * psec_id_xlate - translate pse_spec to the PSE line number according
677 * to the number of pse-cells in case of no pse_pi node
678 * @pcdev: a pointer to the PSE controller device
679 * @pse_spec: PSE line specifier as found in the device tree
680 *
681 * Return: 0 if #pse-cells = <0>. Return PSE line number otherwise.
682 */
683static int psec_id_xlate(struct pse_controller_dev *pcdev,
684 const struct of_phandle_args *pse_spec)
685{
686 if (!pcdev->of_pse_n_cells)
687 return 0;
688
689 if (pcdev->of_pse_n_cells > 1 ||
690 pse_spec->args[0] >= pcdev->nr_lines)
691 return -EINVAL;
692
693 return pse_spec->args[0];
694}
695
696struct pse_control *of_pse_control_get(struct device_node *node)
697{
698 struct pse_controller_dev *r, *pcdev;
699 struct of_phandle_args args;
700 struct pse_control *psec;
701 int psec_id;
702 int ret;
703
704 if (!node)
705 return ERR_PTR(error: -EINVAL);
706
707 ret = of_parse_phandle_with_args(np: node, list_name: "pses", cells_name: "#pse-cells", index: 0, out_args: &args);
708 if (ret)
709 return ERR_PTR(error: ret);
710
711 mutex_lock(&pse_list_mutex);
712 pcdev = NULL;
713 list_for_each_entry(r, &pse_controller_list, list) {
714 if (!r->no_of_pse_pi) {
715 ret = of_pse_match_pi(pcdev: r, np: args.np);
716 if (ret >= 0) {
717 pcdev = r;
718 psec_id = ret;
719 break;
720 }
721 } else if (args.np == r->dev->of_node) {
722 pcdev = r;
723 break;
724 }
725 }
726
727 if (!pcdev) {
728 psec = ERR_PTR(error: -EPROBE_DEFER);
729 goto out;
730 }
731
732 if (WARN_ON(args.args_count != pcdev->of_pse_n_cells)) {
733 psec = ERR_PTR(error: -EINVAL);
734 goto out;
735 }
736
737 if (pcdev->no_of_pse_pi) {
738 psec_id = psec_id_xlate(pcdev, pse_spec: &args);
739 if (psec_id < 0) {
740 psec = ERR_PTR(error: psec_id);
741 goto out;
742 }
743 }
744
745 /* pse_list_mutex also protects the pcdev's pse_control list */
746 psec = pse_control_get_internal(pcdev, index: psec_id);
747
748out:
749 mutex_unlock(lock: &pse_list_mutex);
750 of_node_put(node: args.np);
751
752 return psec;
753}
754EXPORT_SYMBOL_GPL(of_pse_control_get);
755
756/**
757 * pse_ethtool_get_status - get status of PSE control
758 * @psec: PSE control pointer
759 * @extack: extack for reporting useful error messages
760 * @status: struct to store PSE status
761 *
762 * Return: 0 on success and failure value on error
763 */
764int pse_ethtool_get_status(struct pse_control *psec,
765 struct netlink_ext_ack *extack,
766 struct ethtool_pse_control_status *status)
767{
768 struct pse_admin_state admin_state = {0};
769 struct pse_pw_status pw_status = {0};
770 const struct pse_controller_ops *ops;
771 struct pse_controller_dev *pcdev;
772 int ret;
773
774 pcdev = psec->pcdev;
775 ops = pcdev->ops;
776 mutex_lock(&pcdev->lock);
777 ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
778 if (ret)
779 goto out;
780 status->podl_admin_state = admin_state.podl_admin_state;
781 status->c33_admin_state = admin_state.c33_admin_state;
782
783 ret = ops->pi_get_pw_status(pcdev, psec->id, &pw_status);
784 if (ret)
785 goto out;
786 status->podl_pw_status = pw_status.podl_pw_status;
787 status->c33_pw_status = pw_status.c33_pw_status;
788
789 if (ops->pi_get_ext_state) {
790 struct pse_ext_state_info ext_state_info = {0};
791
792 ret = ops->pi_get_ext_state(pcdev, psec->id,
793 &ext_state_info);
794 if (ret)
795 goto out;
796
797 memcpy(&status->c33_ext_state_info,
798 &ext_state_info.c33_ext_state_info,
799 sizeof(status->c33_ext_state_info));
800 }
801
802 if (ops->pi_get_pw_class) {
803 ret = ops->pi_get_pw_class(pcdev, psec->id);
804 if (ret < 0)
805 goto out;
806
807 status->c33_pw_class = ret;
808 }
809
810 if (ops->pi_get_actual_pw) {
811 ret = ops->pi_get_actual_pw(pcdev, psec->id);
812 if (ret < 0)
813 goto out;
814
815 status->c33_actual_pw = ret;
816 }
817
818 if (ops->pi_get_pw_limit) {
819 ret = ops->pi_get_pw_limit(pcdev, psec->id);
820 if (ret < 0)
821 goto out;
822
823 status->c33_avail_pw_limit = ret;
824 }
825
826 if (ops->pi_get_pw_limit_ranges) {
827 struct pse_pw_limit_ranges pw_limit_ranges = {0};
828
829 ret = ops->pi_get_pw_limit_ranges(pcdev, psec->id,
830 &pw_limit_ranges);
831 if (ret < 0)
832 goto out;
833
834 status->c33_pw_limit_ranges =
835 pw_limit_ranges.c33_pw_limit_ranges;
836 status->c33_pw_limit_nb_ranges = ret;
837 }
838out:
839 mutex_unlock(lock: &psec->pcdev->lock);
840 return ret;
841}
842EXPORT_SYMBOL_GPL(pse_ethtool_get_status);
843
844static int pse_ethtool_c33_set_config(struct pse_control *psec,
845 const struct pse_control_config *config)
846{
847 int err = 0;
848
849 /* Look at admin_state_enabled status to not call regulator_enable
850 * or regulator_disable twice creating a regulator counter mismatch
851 */
852 switch (config->c33_admin_control) {
853 case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED:
854 /* We could have mismatch between admin_state_enabled and
855 * state reported by regulator_is_enabled. This can occur when
856 * the PI is forcibly turn off by the controller. Call
857 * regulator_disable on that case to fix the counters state.
858 */
859 if (psec->pcdev->pi[psec->id].admin_state_enabled &&
860 !regulator_is_enabled(regulator: psec->ps)) {
861 err = regulator_disable(regulator: psec->ps);
862 if (err)
863 break;
864 }
865 if (!psec->pcdev->pi[psec->id].admin_state_enabled)
866 err = regulator_enable(regulator: psec->ps);
867 break;
868 case ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED:
869 if (psec->pcdev->pi[psec->id].admin_state_enabled)
870 err = regulator_disable(regulator: psec->ps);
871 break;
872 default:
873 err = -EOPNOTSUPP;
874 }
875
876 return err;
877}
878
879static int pse_ethtool_podl_set_config(struct pse_control *psec,
880 const struct pse_control_config *config)
881{
882 int err = 0;
883
884 /* Look at admin_state_enabled status to not call regulator_enable
885 * or regulator_disable twice creating a regulator counter mismatch
886 */
887 switch (config->podl_admin_control) {
888 case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED:
889 if (!psec->pcdev->pi[psec->id].admin_state_enabled)
890 err = regulator_enable(regulator: psec->ps);
891 break;
892 case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED:
893 if (psec->pcdev->pi[psec->id].admin_state_enabled)
894 err = regulator_disable(regulator: psec->ps);
895 break;
896 default:
897 err = -EOPNOTSUPP;
898 }
899
900 return err;
901}
902
903/**
904 * pse_ethtool_set_config - set PSE control configuration
905 * @psec: PSE control pointer
906 * @extack: extack for reporting useful error messages
907 * @config: Configuration of the test to run
908 *
909 * Return: 0 on success and failure value on error
910 */
911int pse_ethtool_set_config(struct pse_control *psec,
912 struct netlink_ext_ack *extack,
913 const struct pse_control_config *config)
914{
915 int err = 0;
916
917 if (pse_has_c33(psec) && config->c33_admin_control) {
918 err = pse_ethtool_c33_set_config(psec, config);
919 if (err)
920 return err;
921 }
922
923 if (pse_has_podl(psec) && config->podl_admin_control)
924 err = pse_ethtool_podl_set_config(psec, config);
925
926 return err;
927}
928EXPORT_SYMBOL_GPL(pse_ethtool_set_config);
929
930/**
931 * pse_ethtool_set_pw_limit - set PSE control power limit
932 * @psec: PSE control pointer
933 * @extack: extack for reporting useful error messages
934 * @pw_limit: power limit value in mW
935 *
936 * Return: 0 on success and failure value on error
937 */
938int pse_ethtool_set_pw_limit(struct pse_control *psec,
939 struct netlink_ext_ack *extack,
940 const unsigned int pw_limit)
941{
942 int uV, uA, ret;
943 s64 tmp_64;
944
945 if (pw_limit > MAX_PI_PW)
946 return -ERANGE;
947
948 ret = regulator_get_voltage(regulator: psec->ps);
949 if (!ret) {
950 NL_SET_ERR_MSG(extack,
951 "Can't calculate the current, PSE voltage read is 0");
952 return -ERANGE;
953 }
954 if (ret < 0) {
955 NL_SET_ERR_MSG(extack,
956 "Error reading PSE voltage");
957 return ret;
958 }
959 uV = ret;
960
961 tmp_64 = pw_limit;
962 tmp_64 *= 1000000000ull;
963 /* uA = mW * 1000000000 / uV */
964 uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
965
966 return regulator_set_current_limit(regulator: psec->ps, min_uA: 0, max_uA: uA);
967}
968EXPORT_SYMBOL_GPL(pse_ethtool_set_pw_limit);
969
970bool pse_has_podl(struct pse_control *psec)
971{
972 return psec->pcdev->types & ETHTOOL_PSE_PODL;
973}
974EXPORT_SYMBOL_GPL(pse_has_podl);
975
976bool pse_has_c33(struct pse_control *psec)
977{
978 return psec->pcdev->types & ETHTOOL_PSE_C33;
979}
980EXPORT_SYMBOL_GPL(pse_has_c33);
981

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/net/pse-pd/pse_core.c