mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
mutex_lock() is called from MEC1322_IRQ_ACPIEC0_IBF interrupt context, causing deadlock and assertion in __wait_evt(). In the interrupt context it now checks for mutex lock first. If the mutex is already locked,, it will disable ACPI interrupts and defer the memmap mutex lock. Added LPC interrupt disable/enable functions as needed. Increased deferred function count where needed. BRANCH=None BUG=chrome-os-partner:40820 TEST=Test for suspend-resume, cold, warm reboots and other general stability. Change-Id: I3dda0d4635a6b6281faf200c8c7b6fcba8877254 Signed-off-by: Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com> Reviewed-on: https://chromium-review.googlesource.com/280418 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org> Commit-Queue: Divya Jyothi <divya.jyothi@intel.com> Tested-by: Divya Jyothi <divya.jyothi@intel.com>
269 lines
7.2 KiB
C
269 lines
7.2 KiB
C
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
/* Host command module for Chrome EC */
|
|
|
|
#ifndef __CROS_EC_HOST_COMMAND_H
|
|
#define __CROS_EC_HOST_COMMAND_H
|
|
|
|
#include "common.h"
|
|
#include "ec_commands.h"
|
|
|
|
/* Args for host command handler */
|
|
struct host_cmd_handler_args {
|
|
/*
|
|
* The driver that receives the command sets up the send_response()
|
|
* handler. Once the command is processed this handler is called to
|
|
* send the response back to the host.
|
|
*/
|
|
void (*send_response)(struct host_cmd_handler_args *args);
|
|
uint16_t command; /* Command (e.g., EC_CMD_FLASH_GET_INFO) */
|
|
uint8_t version; /* Version of command (0-31) */
|
|
|
|
const void *params; /* Input parameters */
|
|
uint16_t params_size; /* Size of input parameters in bytes */
|
|
|
|
/*
|
|
* Pointer to output response data buffer. On input to the handler,
|
|
* points to a buffer of size response_max.
|
|
*/
|
|
void *response;
|
|
|
|
/* Maximum size of response buffer provided to command handler */
|
|
uint16_t response_max;
|
|
|
|
/*
|
|
* Size of data pointed to by response. Defaults to 0, so commands
|
|
* which do not produce response data do not need to set this.
|
|
*/
|
|
uint16_t response_size;
|
|
|
|
/*
|
|
* This is the result returned by command and therefore the status to
|
|
* be reported from the command execution to the host. The driver
|
|
* should set this to EC_RES_SUCCESS on receipt of a valid command.
|
|
* It is then passed back to the driver via send_response() when
|
|
* command execution is complete. The driver may still override this
|
|
* when sending the response back to the host if it detects an error
|
|
* in the response or in its own operation.
|
|
*/
|
|
enum ec_status result;
|
|
};
|
|
|
|
/* Args for host packet handler */
|
|
struct host_packet {
|
|
/*
|
|
* The driver that receives the command sets up the send_response()
|
|
* handler. Once the command is processed this handler is called to
|
|
* send the response back to the host.
|
|
*/
|
|
void (*send_response)(struct host_packet *pkt);
|
|
|
|
/* Input request data */
|
|
const void *request;
|
|
|
|
/*
|
|
* Input request temp buffer. If this is non-null, the data has not
|
|
* been copied from here into the request buffer yet. The host command
|
|
* handler should do so while verifying the command. The interface
|
|
* can't do it, because it doesn't know how much to copy.
|
|
*/
|
|
void *request_temp;
|
|
|
|
/*
|
|
* Maximum size of request the interface can handle, in bytes. The
|
|
* buffers pointed to by *request and *request_temp must be at least
|
|
* this big.
|
|
*/
|
|
uint16_t request_max;
|
|
|
|
/* Size of input request data, in bytes */
|
|
uint16_t request_size;
|
|
|
|
/* Pointer to output response data buffer */
|
|
void *response;
|
|
|
|
/* Maximum size of response buffer provided to command handler */
|
|
uint16_t response_max;
|
|
|
|
/* Size of output response data, in bytes */
|
|
uint16_t response_size;
|
|
|
|
/*
|
|
* Error from driver; if this is non-zero, host command handler will
|
|
* return a properly formatted error response packet rather than
|
|
* calling a command handler.
|
|
*/
|
|
enum ec_status driver_result;
|
|
};
|
|
|
|
/* Host command */
|
|
struct host_command {
|
|
/*
|
|
* Handler for the command. Args points to context for handler.
|
|
* Returns result status (EC_RES_*).
|
|
*/
|
|
int (*handler)(struct host_cmd_handler_args *args);
|
|
/* Command code */
|
|
int command;
|
|
/* Mask of supported versions */
|
|
int version_mask;
|
|
};
|
|
|
|
/**
|
|
* Return a pointer to the memory-mapped buffer.
|
|
*
|
|
* This buffer is EC_MEMMAP_SIZE bytes long, is writable at any time, and the
|
|
* host can read it at any time.
|
|
*
|
|
* @param offset Offset within the range to return
|
|
* @return pointer to the buffer at that offset
|
|
*/
|
|
uint8_t *host_get_memmap(int offset);
|
|
|
|
/**
|
|
* Grab the memmap write mutex. This function should be called before
|
|
* multi-byte variable reads from ACPI, and before updating multi-byte
|
|
* memmap variables anywhere else.
|
|
*/
|
|
void host_lock_memmap(void);
|
|
|
|
/*
|
|
* Returns status of host memmap lock.
|
|
*/
|
|
int host_memmap_is_locked(void);
|
|
|
|
/**
|
|
* Release the memmap write mutex. This function should be called once
|
|
* a multi-byte variable read from ACPI is done, and when updating multi-byte
|
|
* memmap variables is done.
|
|
*/
|
|
void host_unlock_memmap(void);
|
|
|
|
/**
|
|
* Process a host command and return its response
|
|
*
|
|
* @param args Command handler args
|
|
* @return resulting status
|
|
*/
|
|
enum ec_status host_command_process(struct host_cmd_handler_args *args);
|
|
|
|
/**
|
|
* Set one or more host event bits.
|
|
*
|
|
* @param mask Event bits to set (use EC_HOST_EVENT_MASK()).
|
|
*/
|
|
void host_set_events(uint32_t mask);
|
|
|
|
/**
|
|
* Set a single host event.
|
|
*
|
|
* @param event Event to set (EC_HOST_EVENT_*).
|
|
*/
|
|
static inline void host_set_single_event(int event)
|
|
{
|
|
host_set_events(EC_HOST_EVENT_MASK(event));
|
|
}
|
|
|
|
/**
|
|
* Clear one or more host event bits.
|
|
*
|
|
* @param mask Event bits to clear (use EC_HOST_EVENT_MASK()).
|
|
* Write 1 to a bit to clear it.
|
|
*/
|
|
void host_clear_events(uint32_t mask);
|
|
|
|
/**
|
|
* Return the raw event state.
|
|
*/
|
|
uint32_t host_get_events(void);
|
|
|
|
/**
|
|
* Send a response to the relevent driver for transmission
|
|
*
|
|
* Once command processing is complete, this is used to send a response
|
|
* back to the host.
|
|
*
|
|
* @param args Contains response to send
|
|
*/
|
|
void host_send_response(struct host_cmd_handler_args *args);
|
|
|
|
/**
|
|
* Called by host interface module when a command is received.
|
|
*/
|
|
void host_command_received(struct host_cmd_handler_args *args);
|
|
|
|
/**
|
|
* Return the expected host packet size given its header.
|
|
*
|
|
* Also does some sanity checking on the host request.
|
|
*
|
|
* @param r Host request header
|
|
* @return The expected packet size, or 0 if error.
|
|
*/
|
|
int host_request_expected_size(const struct ec_host_request *r);
|
|
|
|
/**
|
|
* Handle a received host packet.
|
|
*
|
|
* @param packet Host packet args
|
|
*/
|
|
void host_packet_receive(struct host_packet *pkt);
|
|
|
|
/* Register a host command handler */
|
|
#define DECLARE_HOST_COMMAND(command, routine, version_mask) \
|
|
const struct host_command __keep __host_cmd_##command \
|
|
__attribute__((section(".rodata.hcmds"))) \
|
|
= {routine, command, version_mask}
|
|
|
|
|
|
/**
|
|
* Politely ask the CPU to enable/disable its own throttling.
|
|
*
|
|
* @param throttle Enable (!=0) or disable(0) throttling
|
|
*/
|
|
void host_throttle_cpu(int throttle);
|
|
|
|
|
|
/**
|
|
* Signal host command task to send status to PD MCU.
|
|
*
|
|
* @new_chg_state PD MCU charge state
|
|
*/
|
|
void host_command_pd_send_status(enum pd_charge_state new_chg_state);
|
|
|
|
/**
|
|
* Get the active charge port from the PD
|
|
*
|
|
* @return -1 == none/unknown, 0 == left, 1 == right.
|
|
*/
|
|
int pd_get_active_charge_port(void);
|
|
|
|
/**
|
|
* Send host command to PD MCU.
|
|
*
|
|
* @param command Host command number
|
|
* @param version Version of host command
|
|
* @param outdata Pointer to buffer of out data
|
|
* @param outsize Size of buffer to out data
|
|
* @param indata Pointer to buffer to store response
|
|
* @param insize Size of buffer to store response
|
|
*/
|
|
int pd_host_command(int command, int version,
|
|
const void *outdata, int outsize,
|
|
void *indata, int insize);
|
|
|
|
|
|
/**
|
|
* EC: Get verify boot mode
|
|
* @return vboot_mode as the following:
|
|
* VBOOT_MODE_NORMAL - normal mode
|
|
* VBOOT_MODE_DEVELOPER - developer mode
|
|
* VBOOT_MODE_RECOVERY - recovery mode
|
|
*/
|
|
int host_get_vboot_mode(void);
|
|
|
|
#endif /* __CROS_EC_HOST_COMMAND_H */
|