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

Quelle  thead,th1520-aon.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Alibaba Group Holding Limited.
 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
 * Author: Michal Wilczynski <m.wilczynski@samsung.com>
 */


#include <linux/device.h>
#include <linux/firmware/thead/thead,th1520-aon.h>
#include <linux/mailbox_client.h>
#include <linux/mailbox_controller.h>
#include <linux/slab.h>

#define MAX_RX_TIMEOUT (msecs_to_jiffies(3000))
#define MAX_TX_TIMEOUT 500

struct th1520_aon_chan {
 struct mbox_chan *ch;
 struct th1520_aon_rpc_ack_common ack_msg;
 struct mbox_client cl;
 struct completion done;

 /* make sure only one RPC is performed at a time */
 struct mutex transaction_lock;
};

struct th1520_aon_msg_req_set_resource_power_mode {
 struct th1520_aon_rpc_msg_hdr hdr;
 u16 resource;
 u16 mode;
 u16 reserved[10];
} __packed __aligned(1);

/*
 * This type is used to indicate error response for most functions.
 */

enum th1520_aon_error_codes {
 LIGHT_AON_ERR_NONE = 0, /* Success */
 LIGHT_AON_ERR_VERSION = 1, /* Incompatible API version */
 LIGHT_AON_ERR_CONFIG = 2, /* Configuration error */
 LIGHT_AON_ERR_PARM = 3, /* Bad parameter */
 LIGHT_AON_ERR_NOACCESS = 4, /* Permission error (no access) */
 LIGHT_AON_ERR_LOCKED = 5, /* Permission error (locked) */
 LIGHT_AON_ERR_UNAVAILABLE = 6, /* Unavailable (out of resources) */
 LIGHT_AON_ERR_NOTFOUND = 7, /* Not found */
 LIGHT_AON_ERR_NOPOWER = 8, /* No power */
 LIGHT_AON_ERR_IPC = 9, /* Generic IPC error */
 LIGHT_AON_ERR_BUSY = 10, /* Resource is currently busy/active */
 LIGHT_AON_ERR_FAIL = 11, /* General I/O failure */
 LIGHT_AON_ERR_LAST
};

static int th1520_aon_linux_errmap[LIGHT_AON_ERR_LAST] = {
 0, /* LIGHT_AON_ERR_NONE */
 -EINVAL, /* LIGHT_AON_ERR_VERSION */
 -EINVAL, /* LIGHT_AON_ERR_CONFIG */
 -EINVAL, /* LIGHT_AON_ERR_PARM */
 -EACCES, /* LIGHT_AON_ERR_NOACCESS */
 -EACCES, /* LIGHT_AON_ERR_LOCKED */
 -ERANGE, /* LIGHT_AON_ERR_UNAVAILABLE */
 -EEXIST, /* LIGHT_AON_ERR_NOTFOUND */
 -EPERM, /* LIGHT_AON_ERR_NOPOWER */
 -EPIPE, /* LIGHT_AON_ERR_IPC */
 -EBUSY, /* LIGHT_AON_ERR_BUSY */
 -EIO, /* LIGHT_AON_ERR_FAIL */
};

static inline int th1520_aon_to_linux_errno(int errno)
{
 if (errno >= LIGHT_AON_ERR_NONE && errno < LIGHT_AON_ERR_LAST)
  return th1520_aon_linux_errmap[errno];

 return -EIO;
}

static void th1520_aon_rx_callback(struct mbox_client *c, void *rx_msg)
{
 struct th1520_aon_chan *aon_chan =
  container_of(c, struct th1520_aon_chan, cl);
 struct th1520_aon_rpc_msg_hdr *hdr =
  (struct th1520_aon_rpc_msg_hdr *)rx_msg;
 u8 recv_size = sizeof(struct th1520_aon_rpc_msg_hdr) + hdr->size;

 if (recv_size != sizeof(struct th1520_aon_rpc_ack_common)) {
  dev_err(c->dev, "Invalid ack size, not completing\n");
  return;
 }

 memcpy(&aon_chan->ack_msg, rx_msg, recv_size);
 complete(&aon_chan->done);
}

/**
 * th1520_aon_call_rpc() - Send an RPC request to the TH1520 AON subsystem
 * @aon_chan: Pointer to the AON channel structure
 * @msg: Pointer to the message (RPC payload) that will be sent
 *
 * This function sends an RPC message to the TH1520 AON subsystem via mailbox.
 * It takes the provided @msg buffer, formats it with version and service flags,
 * then blocks until the RPC completes or times out. The completion is signaled
 * by the `aon_chan->done` completion, which is waited upon for a duration
 * defined by `MAX_RX_TIMEOUT`.
 *
 * Return:
 * * 0 on success
 * * -ETIMEDOUT if the RPC call times out
 * * A negative error code if the mailbox send fails or if AON responds with
 *   a non-zero error code (converted via th1520_aon_to_linux_errno()).
 */

int th1520_aon_call_rpc(struct th1520_aon_chan *aon_chan, void *msg)
{
 struct th1520_aon_rpc_msg_hdr *hdr = msg;
 int ret;

 mutex_lock(&aon_chan->transaction_lock);
 reinit_completion(&aon_chan->done);

 RPC_SET_VER(hdr, TH1520_AON_RPC_VERSION);
 RPC_SET_SVC_ID(hdr, hdr->svc);
 RPC_SET_SVC_FLAG_MSG_TYPE(hdr, RPC_SVC_MSG_TYPE_DATA);
 RPC_SET_SVC_FLAG_ACK_TYPE(hdr, RPC_SVC_MSG_NEED_ACK);

 ret = mbox_send_message(aon_chan->ch, msg);
 if (ret < 0) {
  dev_err(aon_chan->cl.dev, "RPC send msg failed: %d\n", ret);
  goto out;
 }

 if (!wait_for_completion_timeout(&aon_chan->done, MAX_RX_TIMEOUT)) {
  dev_err(aon_chan->cl.dev, "RPC send msg timeout\n");
  mutex_unlock(&aon_chan->transaction_lock);
  return -ETIMEDOUT;
 }

 ret = aon_chan->ack_msg.err_code;

out:
 mutex_unlock(&aon_chan->transaction_lock);

 return th1520_aon_to_linux_errno(ret);
}
EXPORT_SYMBOL_GPL(th1520_aon_call_rpc);

/**
 * th1520_aon_power_update() - Change power state of a resource via TH1520 AON
 * @aon_chan: Pointer to the AON channel structure
 * @rsrc: Resource ID whose power state needs to be updated
 * @power_on: Boolean indicating whether the resource should be powered on (true)
 *            or powered off (false)
 *
 * This function requests the TH1520 AON subsystem to set the power mode of the
 * given resource (@rsrc) to either on or off. It constructs the message in
 * `struct th1520_aon_msg_req_set_resource_power_mode` and then invokes
 * th1520_aon_call_rpc() to make the request. If the AON call fails, an error
 * message is logged along with the specific return code.
 *
 * Return:
 * * 0 on success
 * * A negative error code in case of failures (propagated from
 *   th1520_aon_call_rpc()).
 */

int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc,
       bool power_on)
{
 struct th1520_aon_msg_req_set_resource_power_mode msg = {};
 struct th1520_aon_rpc_msg_hdr *hdr = &msg.hdr;
 int ret;

 hdr->svc = TH1520_AON_RPC_SVC_PM;
 hdr->func = TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE;
 hdr->size = TH1520_AON_RPC_MSG_NUM;

 RPC_SET_BE16(&msg.resource, 0, rsrc);
 RPC_SET_BE16(&msg.resource, 2,
       (power_on ? TH1520_AON_PM_PW_MODE_ON :
     TH1520_AON_PM_PW_MODE_OFF));

 ret = th1520_aon_call_rpc(aon_chan, &msg);
 if (ret)
  dev_err(aon_chan->cl.dev, "failed to power %s resource %d ret %d\n",
   power_on ? "up" : "off", rsrc, ret);

 return ret;
}
EXPORT_SYMBOL_GPL(th1520_aon_power_update);

/**
 * th1520_aon_init() - Initialize TH1520 AON firmware protocol interface
 * @dev: Device pointer for the AON subsystem
 *
 * This function initializes the TH1520 AON firmware protocol interface by:
 * - Allocating and initializing the AON channel structure
 * - Setting up the mailbox client
 * - Requesting the AON mailbox channel
 * - Initializing synchronization primitives
 *
 * Return:
 * * Valid pointer to th1520_aon_chan structure on success
 * * ERR_PTR(-ENOMEM) if memory allocation fails
 * * ERR_PTR() with other negative error codes from mailbox operations
 */

struct th1520_aon_chan *th1520_aon_init(struct device *dev)
{
 struct th1520_aon_chan *aon_chan;
 struct mbox_client *cl;
 int ret;

 aon_chan = kzalloc(sizeof(*aon_chan), GFP_KERNEL);
 if (!aon_chan)
  return ERR_PTR(-ENOMEM);

 cl = &aon_chan->cl;
 cl->dev = dev;
 cl->tx_block = true;
 cl->tx_tout = MAX_TX_TIMEOUT;
 cl->rx_callback = th1520_aon_rx_callback;

 aon_chan->ch = mbox_request_channel_byname(cl, "aon");
 if (IS_ERR(aon_chan->ch)) {
  dev_err(dev, "Failed to request aon mbox chan\n");
  ret = PTR_ERR(aon_chan->ch);
  kfree(aon_chan);
  return ERR_PTR(ret);
 }

 mutex_init(&aon_chan->transaction_lock);
 init_completion(&aon_chan->done);

 return aon_chan;
}
EXPORT_SYMBOL_GPL(th1520_aon_init);

/**
 * th1520_aon_deinit() - Clean up TH1520 AON firmware protocol interface
 * @aon_chan: Pointer to the AON channel structure to clean up
 *
 * This function cleans up resources allocated by th1520_aon_init():
 * - Frees the mailbox channel
 * - Frees the AON channel
 */

void th1520_aon_deinit(struct th1520_aon_chan *aon_chan)
{
 mbox_free_channel(aon_chan->ch);
 kfree(aon_chan);
}
EXPORT_SYMBOL_GPL(th1520_aon_deinit);

MODULE_AUTHOR("Michal Wilczynski ");
MODULE_DESCRIPTION("T-HEAD TH1520 Always-On firmware protocol library");
MODULE_LICENSE("GPL");

Messung V0.5
C=89 H=97 G=93

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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.