1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014 Linaro Ltd
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
7 * MMC power sequence management
9 #include <linux/kernel.h>
10 #include <linux/err.h>
11 #include <linux/module.h>
14 #include <linux/mmc/host.h>
18 static DEFINE_MUTEX(pwrseq_list_mutex
);
19 static LIST_HEAD(pwrseq_list
);
21 int mmc_pwrseq_alloc(struct mmc_host
*host
)
23 struct device_node
*np
;
26 np
= of_parse_phandle(host
->parent
->of_node
, "mmc-pwrseq", 0);
30 mutex_lock(&pwrseq_list_mutex
);
31 list_for_each_entry(p
, &pwrseq_list
, pwrseq_node
) {
32 if (p
->dev
->of_node
== np
) {
33 if (!try_module_get(p
->owner
))
35 "increasing module refcount failed\n");
44 mutex_unlock(&pwrseq_list_mutex
);
49 dev_info(host
->parent
, "allocated mmc-pwrseq\n");
54 void mmc_pwrseq_pre_power_on(struct mmc_host
*host
)
56 struct mmc_pwrseq
*pwrseq
= host
->pwrseq
;
58 if (pwrseq
&& pwrseq
->ops
->pre_power_on
)
59 pwrseq
->ops
->pre_power_on(host
);
62 void mmc_pwrseq_post_power_on(struct mmc_host
*host
)
64 struct mmc_pwrseq
*pwrseq
= host
->pwrseq
;
66 if (pwrseq
&& pwrseq
->ops
->post_power_on
)
67 pwrseq
->ops
->post_power_on(host
);
70 void mmc_pwrseq_power_off(struct mmc_host
*host
)
72 struct mmc_pwrseq
*pwrseq
= host
->pwrseq
;
74 if (pwrseq
&& pwrseq
->ops
->power_off
)
75 pwrseq
->ops
->power_off(host
);
78 void mmc_pwrseq_reset(struct mmc_host
*host
)
80 struct mmc_pwrseq
*pwrseq
= host
->pwrseq
;
82 if (pwrseq
&& pwrseq
->ops
->reset
)
83 pwrseq
->ops
->reset(host
);
86 void mmc_pwrseq_free(struct mmc_host
*host
)
88 struct mmc_pwrseq
*pwrseq
= host
->pwrseq
;
91 module_put(pwrseq
->owner
);
96 int mmc_pwrseq_register(struct mmc_pwrseq
*pwrseq
)
98 if (!pwrseq
|| !pwrseq
->ops
|| !pwrseq
->dev
)
101 mutex_lock(&pwrseq_list_mutex
);
102 list_add(&pwrseq
->pwrseq_node
, &pwrseq_list
);
103 mutex_unlock(&pwrseq_list_mutex
);
107 EXPORT_SYMBOL_GPL(mmc_pwrseq_register
);
109 void mmc_pwrseq_unregister(struct mmc_pwrseq
*pwrseq
)
112 mutex_lock(&pwrseq_list_mutex
);
113 list_del(&pwrseq
->pwrseq_node
);
114 mutex_unlock(&pwrseq_list_mutex
);
117 EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister
);