Loading...
Note: File does not exist in v3.1.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Generic Framer framework.
4 *
5 * Copyright 2023 CS GROUP France
6 *
7 * Author: Herve Codina <herve.codina@bootlin.com>
8 */
9
10#include <linux/device.h>
11#include <linux/framer/framer.h>
12#include <linux/framer/framer-provider.h>
13#include <linux/idr.h>
14#include <linux/module.h>
15#include <linux/notifier.h>
16#include <linux/of.h>
17#include <linux/pm_runtime.h>
18#include <linux/regulator/consumer.h>
19#include <linux/slab.h>
20
21static struct class *framer_class;
22static DEFINE_MUTEX(framer_provider_mutex);
23static LIST_HEAD(framer_provider_list);
24static DEFINE_IDA(framer_ida);
25
26#define dev_to_framer(a) (container_of((a), struct framer, dev))
27
28int framer_pm_runtime_get(struct framer *framer)
29{
30 int ret;
31
32 if (!pm_runtime_enabled(&framer->dev))
33 return -EOPNOTSUPP;
34
35 ret = pm_runtime_get(&framer->dev);
36 if (ret < 0 && ret != -EINPROGRESS)
37 pm_runtime_put_noidle(&framer->dev);
38
39 return ret;
40}
41EXPORT_SYMBOL_GPL(framer_pm_runtime_get);
42
43int framer_pm_runtime_get_sync(struct framer *framer)
44{
45 int ret;
46
47 if (!pm_runtime_enabled(&framer->dev))
48 return -EOPNOTSUPP;
49
50 ret = pm_runtime_get_sync(&framer->dev);
51 if (ret < 0)
52 pm_runtime_put_sync(&framer->dev);
53
54 return ret;
55}
56EXPORT_SYMBOL_GPL(framer_pm_runtime_get_sync);
57
58int framer_pm_runtime_put(struct framer *framer)
59{
60 if (!pm_runtime_enabled(&framer->dev))
61 return -EOPNOTSUPP;
62
63 return pm_runtime_put(&framer->dev);
64}
65EXPORT_SYMBOL_GPL(framer_pm_runtime_put);
66
67int framer_pm_runtime_put_sync(struct framer *framer)
68{
69 if (!pm_runtime_enabled(&framer->dev))
70 return -EOPNOTSUPP;
71
72 return pm_runtime_put_sync(&framer->dev);
73}
74EXPORT_SYMBOL_GPL(framer_pm_runtime_put_sync);
75
76/**
77 * framer_init - framer internal initialization before framer operation
78 * @framer: the framer returned by framer_get()
79 *
80 * Used to allow framer's driver to perform framer internal initialization,
81 * such as PLL block powering, clock initialization or anything that's
82 * is required by the framer to perform the start of operation.
83 * Must be called before framer_power_on().
84 *
85 * Return: %0 if successful, a negative error code otherwise
86 */
87int framer_init(struct framer *framer)
88{
89 bool start_polling = false;
90 int ret;
91
92 ret = framer_pm_runtime_get_sync(framer);
93 if (ret < 0 && ret != -EOPNOTSUPP)
94 return ret;
95 ret = 0; /* Override possible ret == -EOPNOTSUPP */
96
97 mutex_lock(&framer->mutex);
98 if (framer->power_count > framer->init_count)
99 dev_warn(&framer->dev, "framer_power_on was called before framer init\n");
100
101 if (framer->init_count == 0) {
102 if (framer->ops->init) {
103 ret = framer->ops->init(framer);
104 if (ret < 0) {
105 dev_err(&framer->dev, "framer init failed --> %d\n", ret);
106 goto out;
107 }
108 }
109 if (framer->ops->flags & FRAMER_FLAG_POLL_STATUS)
110 start_polling = true;
111 }
112 ++framer->init_count;
113
114out:
115 mutex_unlock(&framer->mutex);
116
117 if (!ret && start_polling) {
118 ret = framer_get_status(framer, &framer->prev_status);
119 if (ret < 0) {
120 dev_warn(&framer->dev, "framer get status failed --> %d\n", ret);
121 /* Will be retried on polling_work */
122 ret = 0;
123 }
124 queue_delayed_work(system_power_efficient_wq, &framer->polling_work, 1 * HZ);
125 }
126
127 framer_pm_runtime_put(framer);
128 return ret;
129}
130EXPORT_SYMBOL_GPL(framer_init);
131
132/**
133 * framer_exit - Framer internal un-initialization
134 * @framer: the framer returned by framer_get()
135 *
136 * Must be called after framer_power_off().
137 */
138int framer_exit(struct framer *framer)
139{
140 int ret;
141
142 ret = framer_pm_runtime_get_sync(framer);
143 if (ret < 0 && ret != -EOPNOTSUPP)
144 return ret;
145 ret = 0; /* Override possible ret == -EOPNOTSUPP */
146
147 mutex_lock(&framer->mutex);
148 --framer->init_count;
149 if (framer->init_count == 0) {
150 if (framer->ops->flags & FRAMER_FLAG_POLL_STATUS) {
151 mutex_unlock(&framer->mutex);
152 cancel_delayed_work_sync(&framer->polling_work);
153 mutex_lock(&framer->mutex);
154 }
155
156 if (framer->ops->exit)
157 framer->ops->exit(framer);
158 }
159
160 mutex_unlock(&framer->mutex);
161 framer_pm_runtime_put(framer);
162 return ret;
163}
164EXPORT_SYMBOL_GPL(framer_exit);
165
166/**
167 * framer_power_on - Enable the framer and enter proper operation
168 * @framer: the framer returned by framer_get()
169 *
170 * Must be called after framer_init().
171 *
172 * Return: %0 if successful, a negative error code otherwise
173 */
174int framer_power_on(struct framer *framer)
175{
176 int ret;
177
178 if (framer->pwr) {
179 ret = regulator_enable(framer->pwr);
180 if (ret)
181 return ret;
182 }
183
184 ret = framer_pm_runtime_get_sync(framer);
185 if (ret < 0 && ret != -EOPNOTSUPP)
186 goto err_pm_sync;
187
188 mutex_lock(&framer->mutex);
189 if (framer->power_count == 0 && framer->ops->power_on) {
190 ret = framer->ops->power_on(framer);
191 if (ret < 0) {
192 dev_err(&framer->dev, "framer poweron failed --> %d\n", ret);
193 goto err_pwr_on;
194 }
195 }
196 ++framer->power_count;
197 mutex_unlock(&framer->mutex);
198 return 0;
199
200err_pwr_on:
201 mutex_unlock(&framer->mutex);
202 framer_pm_runtime_put_sync(framer);
203err_pm_sync:
204 if (framer->pwr)
205 regulator_disable(framer->pwr);
206 return ret;
207}
208EXPORT_SYMBOL_GPL(framer_power_on);
209
210/**
211 * framer_power_off - Disable the framer.
212 * @framer: the framer returned by framer_get()
213 *
214 * Must be called before framer_exit().
215 *
216 * Return: %0 if successful, a negative error code otherwise
217 */
218int framer_power_off(struct framer *framer)
219{
220 int ret;
221
222 mutex_lock(&framer->mutex);
223 if (framer->power_count == 1 && framer->ops->power_off) {
224 ret = framer->ops->power_off(framer);
225 if (ret < 0) {
226 dev_err(&framer->dev, "framer poweroff failed --> %d\n", ret);
227 mutex_unlock(&framer->mutex);
228 return ret;
229 }
230 }
231 --framer->power_count;
232 mutex_unlock(&framer->mutex);
233 framer_pm_runtime_put(framer);
234
235 if (framer->pwr)
236 regulator_disable(framer->pwr);
237
238 return 0;
239}
240EXPORT_SYMBOL_GPL(framer_power_off);
241
242/**
243 * framer_get_status() - Gets the framer status
244 * @framer: the framer returned by framer_get()
245 * @status: the status to retrieve
246 *
247 * Used to get the framer status. framer_init() must have been called
248 * on the framer.
249 *
250 * Return: %0 if successful, a negative error code otherwise
251 */
252int framer_get_status(struct framer *framer, struct framer_status *status)
253{
254 int ret;
255
256 if (!framer->ops->get_status)
257 return -EOPNOTSUPP;
258
259 /* Be sure to have known values (struct padding and future extensions) */
260 memset(status, 0, sizeof(*status));
261
262 mutex_lock(&framer->mutex);
263 ret = framer->ops->get_status(framer, status);
264 mutex_unlock(&framer->mutex);
265
266 return ret;
267}
268EXPORT_SYMBOL_GPL(framer_get_status);
269
270/**
271 * framer_set_config() - Sets the framer configuration
272 * @framer: the framer returned by framer_get()
273 * @config: the configuration to set
274 *
275 * Used to set the framer configuration. framer_init() must have been called
276 * on the framer.
277 *
278 * Return: %0 if successful, a negative error code otherwise
279 */
280int framer_set_config(struct framer *framer, const struct framer_config *config)
281{
282 int ret;
283
284 if (!framer->ops->set_config)
285 return -EOPNOTSUPP;
286
287 mutex_lock(&framer->mutex);
288 ret = framer->ops->set_config(framer, config);
289 mutex_unlock(&framer->mutex);
290
291 return ret;
292}
293EXPORT_SYMBOL_GPL(framer_set_config);
294
295/**
296 * framer_get_config() - Gets the framer configuration
297 * @framer: the framer returned by framer_get()
298 * @config: the configuration to retrieve
299 *
300 * Used to get the framer configuration. framer_init() must have been called
301 * on the framer.
302 *
303 * Return: %0 if successful, a negative error code otherwise
304 */
305int framer_get_config(struct framer *framer, struct framer_config *config)
306{
307 int ret;
308
309 if (!framer->ops->get_config)
310 return -EOPNOTSUPP;
311
312 mutex_lock(&framer->mutex);
313 ret = framer->ops->get_config(framer, config);
314 mutex_unlock(&framer->mutex);
315
316 return ret;
317}
318EXPORT_SYMBOL_GPL(framer_get_config);
319
320static void framer_polling_work(struct work_struct *work)
321{
322 struct framer *framer = container_of(work, struct framer, polling_work.work);
323 struct framer_status status;
324 int ret;
325
326 ret = framer_get_status(framer, &status);
327 if (ret) {
328 dev_err(&framer->dev, "polling, get status failed (%d)\n", ret);
329 goto end;
330 }
331 if (memcmp(&framer->prev_status, &status, sizeof(status))) {
332 blocking_notifier_call_chain(&framer->notifier_list,
333 FRAMER_EVENT_STATUS, NULL);
334 memcpy(&framer->prev_status, &status, sizeof(status));
335 }
336
337end:
338 /* Re-schedule task in 1 sec */
339 queue_delayed_work(system_power_efficient_wq, &framer->polling_work, 1 * HZ);
340}
341
342/**
343 * framer_notifier_register() - Registers a notifier
344 * @framer: the framer returned by framer_get()
345 * @nb: the notifier block to register
346 *
347 * Used to register a notifier block on framer events. framer_init() must have
348 * been called on the framer.
349 * The available framer events are present in enum framer_events.
350 *
351 * Return: %0 if successful, a negative error code otherwise
352 */
353int framer_notifier_register(struct framer *framer, struct notifier_block *nb)
354{
355 return blocking_notifier_chain_register(&framer->notifier_list, nb);
356}
357EXPORT_SYMBOL_GPL(framer_notifier_register);
358
359/**
360 * framer_notifier_unregister() - Unregisters a notifier
361 * @framer: the framer returned by framer_get()
362 * @nb: the notifier block to unregister
363 *
364 * Used to unregister a notifier block. framer_init() must have
365 * been called on the framer.
366 *
367 * Return: %0 if successful, a negative error code otherwise
368 */
369int framer_notifier_unregister(struct framer *framer, struct notifier_block *nb)
370{
371 return blocking_notifier_chain_unregister(&framer->notifier_list, nb);
372}
373EXPORT_SYMBOL_GPL(framer_notifier_unregister);
374
375static struct framer_provider *framer_provider_of_lookup(const struct device_node *node)
376{
377 struct framer_provider *framer_provider;
378
379 list_for_each_entry(framer_provider, &framer_provider_list, list) {
380 if (device_match_of_node(framer_provider->dev, node))
381 return framer_provider;
382 }
383
384 return ERR_PTR(-EPROBE_DEFER);
385}
386
387static struct framer *framer_of_get_from_provider(struct of_phandle_args *args)
388{
389 struct framer_provider *framer_provider;
390 struct framer *framer;
391
392 mutex_lock(&framer_provider_mutex);
393 framer_provider = framer_provider_of_lookup(args->np);
394 if (IS_ERR(framer_provider) || !try_module_get(framer_provider->owner)) {
395 framer = ERR_PTR(-EPROBE_DEFER);
396 goto end;
397 }
398
399 framer = framer_provider->of_xlate(framer_provider->dev, args);
400
401 module_put(framer_provider->owner);
402
403end:
404 mutex_unlock(&framer_provider_mutex);
405
406 return framer;
407}
408
409static struct framer *framer_of_get_byphandle(struct device_node *np, const char *propname,
410 int index)
411{
412 struct of_phandle_args args;
413 struct framer *framer;
414 int ret;
415
416 ret = of_parse_phandle_with_optional_args(np, propname, "#framer-cells", index, &args);
417 if (ret)
418 return ERR_PTR(-ENODEV);
419
420 if (!of_device_is_available(args.np)) {
421 framer = ERR_PTR(-ENODEV);
422 goto out_node_put;
423 }
424
425 framer = framer_of_get_from_provider(&args);
426
427out_node_put:
428 of_node_put(args.np);
429
430 return framer;
431}
432
433static struct framer *framer_of_get_byparent(struct device_node *np, int index)
434{
435 struct of_phandle_args args;
436 struct framer *framer;
437
438 args.np = of_get_parent(np);
439 args.args_count = 1;
440 args.args[0] = index;
441
442 while (args.np) {
443 framer = framer_of_get_from_provider(&args);
444 if (IS_ERR(framer) && PTR_ERR(framer) != -EPROBE_DEFER) {
445 args.np = of_get_next_parent(args.np);
446 continue;
447 }
448 of_node_put(args.np);
449 return framer;
450 }
451
452 return ERR_PTR(-ENODEV);
453}
454
455/**
456 * framer_get() - lookup and obtain a reference to a framer.
457 * @dev: device that requests the framer
458 * @con_id: name of the framer from device's point of view
459 *
460 * Returns the framer driver, after getting a refcount to it; or
461 * -ENODEV if there is no such framer. The caller is responsible for
462 * calling framer_put() to release that count.
463 */
464struct framer *framer_get(struct device *dev, const char *con_id)
465{
466 struct framer *framer = ERR_PTR(-ENODEV);
467 struct device_link *link;
468 int ret;
469
470 if (dev->of_node) {
471 if (con_id)
472 framer = framer_of_get_byphandle(dev->of_node, con_id, 0);
473 else
474 framer = framer_of_get_byparent(dev->of_node, 0);
475 }
476
477 if (IS_ERR(framer))
478 return framer;
479
480 get_device(&framer->dev);
481
482 if (!try_module_get(framer->ops->owner)) {
483 ret = -EPROBE_DEFER;
484 goto err_put_device;
485 }
486
487 link = device_link_add(dev, &framer->dev, DL_FLAG_STATELESS);
488 if (!link) {
489 dev_err(dev, "failed to create device_link to %s\n", dev_name(&framer->dev));
490 ret = -EPROBE_DEFER;
491 goto err_module_put;
492 }
493
494 return framer;
495
496err_module_put:
497 module_put(framer->ops->owner);
498err_put_device:
499 put_device(&framer->dev);
500 return ERR_PTR(ret);
501}
502EXPORT_SYMBOL_GPL(framer_get);
503
504/**
505 * framer_put() - release the framer
506 * @dev: device that wants to release this framer
507 * @framer: the framer returned by framer_get()
508 *
509 * Releases a refcount the caller received from framer_get().
510 */
511void framer_put(struct device *dev, struct framer *framer)
512{
513 device_link_remove(dev, &framer->dev);
514
515 module_put(framer->ops->owner);
516 put_device(&framer->dev);
517}
518EXPORT_SYMBOL_GPL(framer_put);
519
520static void devm_framer_put(struct device *dev, void *res)
521{
522 struct framer *framer = *(struct framer **)res;
523
524 framer_put(dev, framer);
525}
526
527/**
528 * devm_framer_get() - lookup and obtain a reference to a framer.
529 * @dev: device that requests this framer
530 * @con_id: name of the framer from device's point of view
531 *
532 * Gets the framer using framer_get(), and associates a device with it using
533 * devres. On driver detach, framer_put() function is invoked on the devres
534 * data, then, devres data is freed.
535 */
536struct framer *devm_framer_get(struct device *dev, const char *con_id)
537{
538 struct framer **ptr, *framer;
539
540 ptr = devres_alloc(devm_framer_put, sizeof(*ptr), GFP_KERNEL);
541 if (!ptr)
542 return ERR_PTR(-ENOMEM);
543
544 framer = framer_get(dev, con_id);
545 if (!IS_ERR(framer)) {
546 *ptr = framer;
547 devres_add(dev, ptr);
548 } else {
549 devres_free(ptr);
550 return framer;
551 }
552
553 return framer;
554}
555EXPORT_SYMBOL_GPL(devm_framer_get);
556
557/**
558 * devm_framer_optional_get() - lookup and obtain a reference to an optional
559 * framer.
560 * @dev: device that requests this framer
561 * @con_id: name of the framer from device's point of view
562 *
563 * Same as devm_framer_get() except that if the framer does not exist, it is not
564 * considered an error and -ENODEV will not be returned. Instead the NULL framer
565 * is returned.
566 */
567struct framer *devm_framer_optional_get(struct device *dev, const char *con_id)
568{
569 struct framer *framer = devm_framer_get(dev, con_id);
570
571 if (PTR_ERR(framer) == -ENODEV)
572 framer = NULL;
573
574 return framer;
575}
576EXPORT_SYMBOL_GPL(devm_framer_optional_get);
577
578static void framer_notify_status_work(struct work_struct *work)
579{
580 struct framer *framer = container_of(work, struct framer, notify_status_work);
581
582 blocking_notifier_call_chain(&framer->notifier_list, FRAMER_EVENT_STATUS, NULL);
583}
584
585void framer_notify_status_change(struct framer *framer)
586{
587 /* Can be called from atomic context -> just schedule a task to call
588 * blocking notifiers
589 */
590 queue_work(system_power_efficient_wq, &framer->notify_status_work);
591}
592EXPORT_SYMBOL_GPL(framer_notify_status_change);
593
594/**
595 * framer_create() - create a new framer
596 * @dev: device that is creating the new framer
597 * @node: device node of the framer. default to dev->of_node.
598 * @ops: function pointers for performing framer operations
599 *
600 * Called to create a framer using framer framework.
601 */
602struct framer *framer_create(struct device *dev, struct device_node *node,
603 const struct framer_ops *ops)
604{
605 struct framer *framer;
606 int ret;
607 int id;
608
609 /* get_status() is mandatory if the provider ask for polling status */
610 if (WARN_ON((ops->flags & FRAMER_FLAG_POLL_STATUS) && !ops->get_status))
611 return ERR_PTR(-EINVAL);
612
613 framer = kzalloc(sizeof(*framer), GFP_KERNEL);
614 if (!framer)
615 return ERR_PTR(-ENOMEM);
616
617 id = ida_alloc(&framer_ida, GFP_KERNEL);
618 if (id < 0) {
619 dev_err(dev, "unable to get id\n");
620 ret = id;
621 goto free_framer;
622 }
623
624 device_initialize(&framer->dev);
625 mutex_init(&framer->mutex);
626 INIT_WORK(&framer->notify_status_work, framer_notify_status_work);
627 INIT_DELAYED_WORK(&framer->polling_work, framer_polling_work);
628 BLOCKING_INIT_NOTIFIER_HEAD(&framer->notifier_list);
629
630 framer->dev.class = framer_class;
631 framer->dev.parent = dev;
632 framer->dev.of_node = node ? node : dev->of_node;
633 framer->id = id;
634 framer->ops = ops;
635
636 ret = dev_set_name(&framer->dev, "framer-%s.%d", dev_name(dev), id);
637 if (ret)
638 goto put_dev;
639
640 /* framer-supply */
641 framer->pwr = regulator_get_optional(&framer->dev, "framer");
642 if (IS_ERR(framer->pwr)) {
643 ret = PTR_ERR(framer->pwr);
644 if (ret == -EPROBE_DEFER)
645 goto put_dev;
646
647 framer->pwr = NULL;
648 }
649
650 ret = device_add(&framer->dev);
651 if (ret)
652 goto put_dev;
653
654 if (pm_runtime_enabled(dev)) {
655 pm_runtime_enable(&framer->dev);
656 pm_runtime_no_callbacks(&framer->dev);
657 }
658
659 return framer;
660
661put_dev:
662 put_device(&framer->dev); /* calls framer_release() which frees resources */
663 return ERR_PTR(ret);
664
665free_framer:
666 kfree(framer);
667 return ERR_PTR(ret);
668}
669EXPORT_SYMBOL_GPL(framer_create);
670
671/**
672 * framer_destroy() - destroy the framer
673 * @framer: the framer to be destroyed
674 *
675 * Called to destroy the framer.
676 */
677void framer_destroy(struct framer *framer)
678{
679 /* polling_work should already be stopped but if framer_exit() was not
680 * called (bug), here it's the last time to do that ...
681 */
682 cancel_delayed_work_sync(&framer->polling_work);
683 cancel_work_sync(&framer->notify_status_work);
684 pm_runtime_disable(&framer->dev);
685 device_unregister(&framer->dev); /* calls framer_release() which frees resources */
686}
687EXPORT_SYMBOL_GPL(framer_destroy);
688
689static void devm_framer_destroy(struct device *dev, void *res)
690{
691 struct framer *framer = *(struct framer **)res;
692
693 framer_destroy(framer);
694}
695
696/**
697 * devm_framer_create() - create a new framer
698 * @dev: device that is creating the new framer
699 * @node: device node of the framer
700 * @ops: function pointers for performing framer operations
701 *
702 * Creates a new framer device adding it to the framer class.
703 * While at that, it also associates the device with the framer using devres.
704 * On driver detach, release function is invoked on the devres data,
705 * then, devres data is freed.
706 */
707struct framer *devm_framer_create(struct device *dev, struct device_node *node,
708 const struct framer_ops *ops)
709{
710 struct framer **ptr, *framer;
711
712 ptr = devres_alloc(devm_framer_destroy, sizeof(*ptr), GFP_KERNEL);
713 if (!ptr)
714 return ERR_PTR(-ENOMEM);
715
716 framer = framer_create(dev, node, ops);
717 if (!IS_ERR(framer)) {
718 *ptr = framer;
719 devres_add(dev, ptr);
720 } else {
721 devres_free(ptr);
722 }
723
724 return framer;
725}
726EXPORT_SYMBOL_GPL(devm_framer_create);
727
728/**
729 * framer_provider_simple_of_xlate() - returns the framer instance from framer provider
730 * @dev: the framer provider device
731 * @args: of_phandle_args (not used here)
732 *
733 * Intended to be used by framer provider for the common case where #framer-cells is
734 * 0. For other cases where #framer-cells is greater than '0', the framer provider
735 * should provide a custom of_xlate function that reads the *args* and returns
736 * the appropriate framer.
737 */
738struct framer *framer_provider_simple_of_xlate(struct device *dev, struct of_phandle_args *args)
739{
740 struct class_dev_iter iter;
741 struct framer *framer;
742
743 class_dev_iter_init(&iter, framer_class, NULL, NULL);
744 while ((dev = class_dev_iter_next(&iter))) {
745 framer = dev_to_framer(dev);
746 if (args->np != framer->dev.of_node)
747 continue;
748
749 class_dev_iter_exit(&iter);
750 return framer;
751 }
752
753 class_dev_iter_exit(&iter);
754 return ERR_PTR(-ENODEV);
755}
756EXPORT_SYMBOL_GPL(framer_provider_simple_of_xlate);
757
758/**
759 * __framer_provider_of_register() - create/register framer provider with the framework
760 * @dev: struct device of the framer provider
761 * @owner: the module owner containing of_xlate
762 * @of_xlate: function pointer to obtain framer instance from framer provider
763 *
764 * Creates struct framer_provider from dev and of_xlate function pointer.
765 * This is used in the case of dt boot for finding the framer instance from
766 * framer provider.
767 */
768struct framer_provider *
769__framer_provider_of_register(struct device *dev, struct module *owner,
770 struct framer *(*of_xlate)(struct device *dev,
771 struct of_phandle_args *args))
772{
773 struct framer_provider *framer_provider;
774
775 framer_provider = kzalloc(sizeof(*framer_provider), GFP_KERNEL);
776 if (!framer_provider)
777 return ERR_PTR(-ENOMEM);
778
779 framer_provider->dev = dev;
780 framer_provider->owner = owner;
781 framer_provider->of_xlate = of_xlate;
782
783 of_node_get(framer_provider->dev->of_node);
784
785 mutex_lock(&framer_provider_mutex);
786 list_add_tail(&framer_provider->list, &framer_provider_list);
787 mutex_unlock(&framer_provider_mutex);
788
789 return framer_provider;
790}
791EXPORT_SYMBOL_GPL(__framer_provider_of_register);
792
793/**
794 * framer_provider_of_unregister() - unregister framer provider from the framework
795 * @framer_provider: framer provider returned by framer_provider_of_register()
796 *
797 * Removes the framer_provider created using framer_provider_of_register().
798 */
799void framer_provider_of_unregister(struct framer_provider *framer_provider)
800{
801 mutex_lock(&framer_provider_mutex);
802 list_del(&framer_provider->list);
803 mutex_unlock(&framer_provider_mutex);
804
805 of_node_put(framer_provider->dev->of_node);
806 kfree(framer_provider);
807}
808EXPORT_SYMBOL_GPL(framer_provider_of_unregister);
809
810static void devm_framer_provider_of_unregister(struct device *dev, void *res)
811{
812 struct framer_provider *framer_provider = *(struct framer_provider **)res;
813
814 framer_provider_of_unregister(framer_provider);
815}
816
817/**
818 * __devm_framer_provider_of_register() - create/register framer provider with
819 * the framework
820 * @dev: struct device of the framer provider
821 * @owner: the module owner containing of_xlate
822 * @of_xlate: function pointer to obtain framer instance from framer provider
823 *
824 * Creates struct framer_provider from dev and of_xlate function pointer.
825 * This is used in the case of dt boot for finding the framer instance from
826 * framer provider. While at that, it also associates the device with the
827 * framer provider using devres. On driver detach, release function is invoked
828 * on the devres data, then, devres data is freed.
829 */
830struct framer_provider *
831__devm_framer_provider_of_register(struct device *dev, struct module *owner,
832 struct framer *(*of_xlate)(struct device *dev,
833 struct of_phandle_args *args))
834{
835 struct framer_provider **ptr, *framer_provider;
836
837 ptr = devres_alloc(devm_framer_provider_of_unregister, sizeof(*ptr), GFP_KERNEL);
838 if (!ptr)
839 return ERR_PTR(-ENOMEM);
840
841 framer_provider = __framer_provider_of_register(dev, owner, of_xlate);
842 if (!IS_ERR(framer_provider)) {
843 *ptr = framer_provider;
844 devres_add(dev, ptr);
845 } else {
846 devres_free(ptr);
847 }
848
849 return framer_provider;
850}
851EXPORT_SYMBOL_GPL(__devm_framer_provider_of_register);
852
853/**
854 * framer_release() - release the framer
855 * @dev: the dev member within framer
856 *
857 * When the last reference to the device is removed, it is called
858 * from the embedded kobject as release method.
859 */
860static void framer_release(struct device *dev)
861{
862 struct framer *framer;
863
864 framer = dev_to_framer(dev);
865 regulator_put(framer->pwr);
866 ida_free(&framer_ida, framer->id);
867 kfree(framer);
868}
869
870static int __init framer_core_init(void)
871{
872 framer_class = class_create("framer");
873 if (IS_ERR(framer_class)) {
874 pr_err("failed to create framer class (%pe)\n", framer_class);
875 return PTR_ERR(framer_class);
876 }
877
878 framer_class->dev_release = framer_release;
879
880 return 0;
881}
882device_initcall(framer_core_init);