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
21 static struct class *framer_class;
22 static DEFINE_MUTEX(framer_provider_mutex);
23 static LIST_HEAD(framer_provider_list);
24 static DEFINE_IDA(framer_ida);
25
26 #define dev_to_framer(a) (container_of((a), struct framer, dev))
27
framer_pm_runtime_get(struct framer * framer)28 int 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 }
41 EXPORT_SYMBOL_GPL(framer_pm_runtime_get);
42
framer_pm_runtime_get_sync(struct framer * framer)43 int 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 }
56 EXPORT_SYMBOL_GPL(framer_pm_runtime_get_sync);
57
framer_pm_runtime_put(struct framer * framer)58 int 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 }
65 EXPORT_SYMBOL_GPL(framer_pm_runtime_put);
66
framer_pm_runtime_put_sync(struct framer * framer)67 int 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 }
74 EXPORT_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 */
framer_init(struct framer * framer)87 int 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
114 out:
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 }
130 EXPORT_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 */
framer_exit(struct framer * framer)138 int 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 }
164 EXPORT_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 */
framer_power_on(struct framer * framer)174 int 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
200 err_pwr_on:
201 mutex_unlock(&framer->mutex);
202 framer_pm_runtime_put_sync(framer);
203 err_pm_sync:
204 if (framer->pwr)
205 regulator_disable(framer->pwr);
206 return ret;
207 }
208 EXPORT_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 */
framer_power_off(struct framer * framer)218 int 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 }
240 EXPORT_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 */
framer_get_status(struct framer * framer,struct framer_status * status)252 int 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 }
268 EXPORT_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 */
framer_set_config(struct framer * framer,const struct framer_config * config)280 int 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 }
293 EXPORT_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 */
framer_get_config(struct framer * framer,struct framer_config * config)305 int 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 }
318 EXPORT_SYMBOL_GPL(framer_get_config);
319
framer_polling_work(struct work_struct * work)320 static 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
337 end:
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 */
framer_notifier_register(struct framer * framer,struct notifier_block * nb)353 int framer_notifier_register(struct framer *framer, struct notifier_block *nb)
354 {
355 return blocking_notifier_chain_register(&framer->notifier_list, nb);
356 }
357 EXPORT_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 */
framer_notifier_unregister(struct framer * framer,struct notifier_block * nb)369 int framer_notifier_unregister(struct framer *framer, struct notifier_block *nb)
370 {
371 return blocking_notifier_chain_unregister(&framer->notifier_list, nb);
372 }
373 EXPORT_SYMBOL_GPL(framer_notifier_unregister);
374
framer_provider_of_lookup(const struct device_node * node)375 static 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
framer_of_get_from_provider(struct of_phandle_args * args)387 static 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
403 end:
404 mutex_unlock(&framer_provider_mutex);
405
406 return framer;
407 }
408
framer_of_get_byphandle(struct device_node * np,const char * propname,int index)409 static 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
427 out_node_put:
428 of_node_put(args.np);
429
430 return framer;
431 }
432
framer_of_get_byparent(struct device_node * np,int index)433 static 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 */
framer_get(struct device * dev,const char * con_id)464 struct 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
496 err_module_put:
497 module_put(framer->ops->owner);
498 err_put_device:
499 put_device(&framer->dev);
500 return ERR_PTR(ret);
501 }
502 EXPORT_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 */
framer_put(struct device * dev,struct framer * framer)511 void 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 }
518 EXPORT_SYMBOL_GPL(framer_put);
519
devm_framer_put(struct device * dev,void * res)520 static 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 */
devm_framer_get(struct device * dev,const char * con_id)536 struct 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 }
555 EXPORT_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 */
devm_framer_optional_get(struct device * dev,const char * con_id)567 struct 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 }
576 EXPORT_SYMBOL_GPL(devm_framer_optional_get);
577
framer_notify_status_work(struct work_struct * work)578 static 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
framer_notify_status_change(struct framer * framer)585 void 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 }
592 EXPORT_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 */
framer_create(struct device * dev,struct device_node * node,const struct framer_ops * ops)602 struct 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
661 put_dev:
662 put_device(&framer->dev); /* calls framer_release() which frees resources */
663 return ERR_PTR(ret);
664
665 free_framer:
666 kfree(framer);
667 return ERR_PTR(ret);
668 }
669 EXPORT_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 */
framer_destroy(struct framer * framer)677 void 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 }
687 EXPORT_SYMBOL_GPL(framer_destroy);
688
devm_framer_destroy(struct device * dev,void * res)689 static 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 */
devm_framer_create(struct device * dev,struct device_node * node,const struct framer_ops * ops)707 struct 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 }
726 EXPORT_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 */
framer_provider_simple_of_xlate(struct device * dev,struct of_phandle_args * args)738 struct 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 }
756 EXPORT_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 */
768 struct framer_provider *
__framer_provider_of_register(struct device * dev,struct module * owner,struct framer * (* of_xlate)(struct device * dev,struct of_phandle_args * args))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 }
791 EXPORT_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 */
framer_provider_of_unregister(struct framer_provider * framer_provider)799 void 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 }
808 EXPORT_SYMBOL_GPL(framer_provider_of_unregister);
809
devm_framer_provider_of_unregister(struct device * dev,void * res)810 static 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 */
830 struct framer_provider *
__devm_framer_provider_of_register(struct device * dev,struct module * owner,struct framer * (* of_xlate)(struct device * dev,struct of_phandle_args * args))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 }
851 EXPORT_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 */
framer_release(struct device * dev)860 static 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
framer_core_init(void)870 static 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 }
882 device_initcall(framer_core_init);
883