Linux Audio

Check our new training course

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);