root/drivers/mmc/core/pwrseq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mmc_pwrseq_alloc
  2. mmc_pwrseq_pre_power_on
  3. mmc_pwrseq_post_power_on
  4. mmc_pwrseq_power_off
  5. mmc_pwrseq_reset
  6. mmc_pwrseq_free
  7. mmc_pwrseq_register
  8. mmc_pwrseq_unregister

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Copyright (C) 2014 Linaro Ltd
   4  *
   5  * Author: Ulf Hansson <ulf.hansson@linaro.org>
   6  *
   7  *  MMC power sequence management
   8  */
   9 #include <linux/kernel.h>
  10 #include <linux/err.h>
  11 #include <linux/module.h>
  12 #include <linux/of.h>
  13 
  14 #include <linux/mmc/host.h>
  15 
  16 #include "pwrseq.h"
  17 
  18 static DEFINE_MUTEX(pwrseq_list_mutex);
  19 static LIST_HEAD(pwrseq_list);
  20 
  21 int mmc_pwrseq_alloc(struct mmc_host *host)
  22 {
  23         struct device_node *np;
  24         struct mmc_pwrseq *p;
  25 
  26         np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0);
  27         if (!np)
  28                 return 0;
  29 
  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))
  34                                 dev_err(host->parent,
  35                                         "increasing module refcount failed\n");
  36                         else
  37                                 host->pwrseq = p;
  38 
  39                         break;
  40                 }
  41         }
  42 
  43         of_node_put(np);
  44         mutex_unlock(&pwrseq_list_mutex);
  45 
  46         if (!host->pwrseq)
  47                 return -EPROBE_DEFER;
  48 
  49         dev_info(host->parent, "allocated mmc-pwrseq\n");
  50 
  51         return 0;
  52 }
  53 
  54 void mmc_pwrseq_pre_power_on(struct mmc_host *host)
  55 {
  56         struct mmc_pwrseq *pwrseq = host->pwrseq;
  57 
  58         if (pwrseq && pwrseq->ops->pre_power_on)
  59                 pwrseq->ops->pre_power_on(host);
  60 }
  61 
  62 void mmc_pwrseq_post_power_on(struct mmc_host *host)
  63 {
  64         struct mmc_pwrseq *pwrseq = host->pwrseq;
  65 
  66         if (pwrseq && pwrseq->ops->post_power_on)
  67                 pwrseq->ops->post_power_on(host);
  68 }
  69 
  70 void mmc_pwrseq_power_off(struct mmc_host *host)
  71 {
  72         struct mmc_pwrseq *pwrseq = host->pwrseq;
  73 
  74         if (pwrseq && pwrseq->ops->power_off)
  75                 pwrseq->ops->power_off(host);
  76 }
  77 
  78 void mmc_pwrseq_reset(struct mmc_host *host)
  79 {
  80         struct mmc_pwrseq *pwrseq = host->pwrseq;
  81 
  82         if (pwrseq && pwrseq->ops->reset)
  83                 pwrseq->ops->reset(host);
  84 }
  85 
  86 void mmc_pwrseq_free(struct mmc_host *host)
  87 {
  88         struct mmc_pwrseq *pwrseq = host->pwrseq;
  89 
  90         if (pwrseq) {
  91                 module_put(pwrseq->owner);
  92                 host->pwrseq = NULL;
  93         }
  94 }
  95 
  96 int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
  97 {
  98         if (!pwrseq || !pwrseq->ops || !pwrseq->dev)
  99                 return -EINVAL;
 100 
 101         mutex_lock(&pwrseq_list_mutex);
 102         list_add(&pwrseq->pwrseq_node, &pwrseq_list);
 103         mutex_unlock(&pwrseq_list_mutex);
 104 
 105         return 0;
 106 }
 107 EXPORT_SYMBOL_GPL(mmc_pwrseq_register);
 108 
 109 void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq)
 110 {
 111         if (pwrseq) {
 112                 mutex_lock(&pwrseq_list_mutex);
 113                 list_del(&pwrseq->pwrseq_node);
 114                 mutex_unlock(&pwrseq_list_mutex);
 115         }
 116 }
 117 EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister);

/* [<][>][^][v][top][bottom][index][help] */