cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pwrseq.c (2366B)


      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
     18static DEFINE_MUTEX(pwrseq_list_mutex);
     19static LIST_HEAD(pwrseq_list);
     20
     21int 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
     54void 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
     62void 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
     70void 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
     78void 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
     86void 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
     96int 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}
    107EXPORT_SYMBOL_GPL(mmc_pwrseq_register);
    108
    109void 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}
    117EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister);