Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/bus/mhi/ep/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  sm.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022 Linaro Ltd.
 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 */


#include <linux/errno.h>
#include <linux/mhi_ep.h>
#include "internal.h"

bool __must_check mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl,
      enum mhi_state cur_mhi_state,
      enum mhi_state mhi_state)
{
 if (mhi_state == MHI_STATE_SYS_ERR)
  return true;    /* Allowed in any state */

 if (mhi_state == MHI_STATE_READY)
  return cur_mhi_state == MHI_STATE_RESET;

 if (mhi_state == MHI_STATE_M0)
  return cur_mhi_state == MHI_STATE_M3 || cur_mhi_state == MHI_STATE_READY;

 if (mhi_state == MHI_STATE_M3)
  return cur_mhi_state == MHI_STATE_M0;

 return false;
}

int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state)
{
 struct device *dev = &mhi_cntrl->mhi_dev->dev;

 if (!mhi_ep_check_mhi_state(mhi_cntrl, mhi_cntrl->mhi_state, mhi_state)) {
  dev_err(dev, "MHI state change to %s from %s is not allowed!\n",
   mhi_state_str(mhi_state),
   mhi_state_str(mhi_cntrl->mhi_state));
  return -EACCES;
 }

 /* TODO: Add support for M1 and M2 states */
 if (mhi_state == MHI_STATE_M1 || mhi_state == MHI_STATE_M2) {
  dev_err(dev, "MHI state (%s) not supported\n", mhi_state_str(mhi_state));
  return -EOPNOTSUPP;
 }

 mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_MHISTATE_MASK, mhi_state);
 mhi_cntrl->mhi_state = mhi_state;

 if (mhi_state == MHI_STATE_READY)
  mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_READY_MASK, 1);

 if (mhi_state == MHI_STATE_SYS_ERR)
  mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_SYSERR_MASK, 1);

 return 0;
}

int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl)
{
 struct device *dev = &mhi_cntrl->mhi_dev->dev;
 enum mhi_state old_state;
 int ret;

 /* If MHI is in M3, resume suspended channels */
 mutex_lock(&mhi_cntrl->state_lock);

 old_state = mhi_cntrl->mhi_state;
 if (old_state == MHI_STATE_M3)
  mhi_ep_resume_channels(mhi_cntrl);

 ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0);
 if (ret) {
  mhi_ep_handle_syserr(mhi_cntrl);
  goto err_unlock;
 }

 /* Signal host that the device moved to M0 */
 ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M0);
 if (ret) {
  dev_err(dev, "Failed sending M0 state change event\n");
  goto err_unlock;
 }

 if (old_state == MHI_STATE_READY) {
  /* Send AMSS EE event to host */
  ret = mhi_ep_send_ee_event(mhi_cntrl, MHI_EE_AMSS);
  if (ret) {
   dev_err(dev, "Failed sending AMSS EE event\n");
   goto err_unlock;
  }
 }

err_unlock:
 mutex_unlock(&mhi_cntrl->state_lock);

 return ret;
}

int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl)
{
 struct device *dev = &mhi_cntrl->mhi_dev->dev;
 int ret;

 mutex_lock(&mhi_cntrl->state_lock);

 ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3);
 if (ret) {
  mhi_ep_handle_syserr(mhi_cntrl);
  goto err_unlock;
 }

 mhi_ep_suspend_channels(mhi_cntrl);

 /* Signal host that the device moved to M3 */
 ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3);
 if (ret) {
  dev_err(dev, "Failed sending M3 state change event\n");
  goto err_unlock;
 }

err_unlock:
 mutex_unlock(&mhi_cntrl->state_lock);

 return ret;
}

int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl)
{
 struct device *dev = &mhi_cntrl->mhi_dev->dev;
 enum mhi_state mhi_state;
 int ret, is_ready;

 mutex_lock(&mhi_cntrl->state_lock);

 /* Ensure that the MHISTATUS is set to RESET by host */
 mhi_state = mhi_ep_mmio_masked_read(mhi_cntrl, EP_MHISTATUS, MHISTATUS_MHISTATE_MASK);
 is_ready = mhi_ep_mmio_masked_read(mhi_cntrl, EP_MHISTATUS, MHISTATUS_READY_MASK);

 if (mhi_state != MHI_STATE_RESET || is_ready) {
  dev_err(dev, "READY state transition failed. MHI host not in RESET state\n");
  ret = -EIO;
  goto err_unlock;
 }

 ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_READY);
 if (ret)
  mhi_ep_handle_syserr(mhi_cntrl);

err_unlock:
 mutex_unlock(&mhi_cntrl->state_lock);

 return ret;
}

Messung V0.5
C=95 H=80 G=87

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.