forked from Minki/linux
mei: extract fw status registers
Fetch FW status registers, as they are important in in understanding of FW reset reasons Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
61a1aea7c7
commit
04dd366195
@ -696,10 +696,65 @@ end:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_me_fw_status - retrieve fw status from the pci config space
|
||||
*
|
||||
* @dev: the device structure
|
||||
* @fw_status: fw status registers storage
|
||||
*
|
||||
* returns 0 on success an error code otherwise
|
||||
*/
|
||||
static int mei_me_fw_status(struct mei_device *dev,
|
||||
struct mei_fw_status *fw_status)
|
||||
{
|
||||
const u32 pci_cfg_reg[] = {PCI_CFG_HFS_1, PCI_CFG_HFS_2};
|
||||
int i;
|
||||
|
||||
if (!fw_status)
|
||||
return -EINVAL;
|
||||
|
||||
switch (dev->pdev->device) {
|
||||
case MEI_DEV_ID_IBXPK_1:
|
||||
case MEI_DEV_ID_IBXPK_2:
|
||||
case MEI_DEV_ID_CPT_1:
|
||||
case MEI_DEV_ID_PBG_1:
|
||||
case MEI_DEV_ID_PPT_1:
|
||||
case MEI_DEV_ID_PPT_2:
|
||||
case MEI_DEV_ID_PPT_3:
|
||||
case MEI_DEV_ID_LPT_H:
|
||||
case MEI_DEV_ID_LPT_W:
|
||||
case MEI_DEV_ID_LPT_LP:
|
||||
case MEI_DEV_ID_LPT_HR:
|
||||
case MEI_DEV_ID_WPT_LP:
|
||||
fw_status->count = 2;
|
||||
break;
|
||||
case MEI_DEV_ID_ICH10_1:
|
||||
case MEI_DEV_ID_ICH10_2:
|
||||
case MEI_DEV_ID_ICH10_3:
|
||||
case MEI_DEV_ID_ICH10_4:
|
||||
fw_status->count = 1;
|
||||
break;
|
||||
default:
|
||||
fw_status->count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
|
||||
int ret;
|
||||
ret = pci_read_config_dword(dev->pdev,
|
||||
pci_cfg_reg[i], &fw_status->status[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mei_hw_ops mei_me_hw_ops = {
|
||||
|
||||
.pg_state = mei_me_pg_state,
|
||||
|
||||
.fw_status = mei_me_fw_status,
|
||||
.host_is_ready = mei_me_host_is_ready,
|
||||
|
||||
.hw_is_ready = mei_me_hw_is_ready,
|
||||
|
@ -89,7 +89,7 @@ enum {
|
||||
# define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000
|
||||
# define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000
|
||||
# define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000
|
||||
|
||||
#define PCI_CFG_TXE_FW_STS1 0x48
|
||||
|
||||
#define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */
|
||||
|
||||
|
@ -620,7 +620,10 @@ static int mei_txe_write(struct mei_device *dev,
|
||||
mei_txe_input_ready_interrupt_enable(dev);
|
||||
|
||||
if (!mei_txe_is_input_ready(dev)) {
|
||||
dev_err(&dev->pdev->dev, "Input is not ready");
|
||||
struct mei_fw_status fw_status;
|
||||
mei_fw_status(dev, &fw_status);
|
||||
dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n",
|
||||
FW_STS_PRM(fw_status));
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
@ -1039,8 +1042,40 @@ end:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mei_txe_fw_status - retrieve fw status from the pci config space
|
||||
*
|
||||
* @dev: the device structure
|
||||
* @fw_status: fw status registers storage
|
||||
*
|
||||
* returns: 0 on success an error code otherwise
|
||||
*/
|
||||
static int mei_txe_fw_status(struct mei_device *dev,
|
||||
struct mei_fw_status *fw_status)
|
||||
{
|
||||
const u32 pci_cfg_reg[] = {PCI_CFG_TXE_FW_STS0, PCI_CFG_TXE_FW_STS1};
|
||||
int i;
|
||||
|
||||
if (!fw_status)
|
||||
return -EINVAL;
|
||||
|
||||
fw_status->count = 2;
|
||||
|
||||
for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
|
||||
int ret;
|
||||
ret = pci_read_config_dword(dev->pdev,
|
||||
pci_cfg_reg[i], &fw_status->status[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mei_hw_ops mei_txe_hw_ops = {
|
||||
|
||||
.fw_status = mei_txe_fw_status,
|
||||
.host_is_ready = mei_txe_host_is_ready,
|
||||
|
||||
.pg_state = mei_txe_pg_state,
|
||||
|
@ -74,9 +74,13 @@ int mei_reset(struct mei_device *dev)
|
||||
if (state != MEI_DEV_INITIALIZING &&
|
||||
state != MEI_DEV_DISABLED &&
|
||||
state != MEI_DEV_POWER_DOWN &&
|
||||
state != MEI_DEV_POWER_UP)
|
||||
dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
|
||||
mei_dev_state_str(state));
|
||||
state != MEI_DEV_POWER_UP) {
|
||||
struct mei_fw_status fw_status;
|
||||
mei_fw_status(dev, &fw_status);
|
||||
dev_warn(&dev->pdev->dev,
|
||||
"unexpected reset: dev_state = %s " FW_STS_FMT "\n",
|
||||
mei_dev_state_str(state), FW_STS_PRM(fw_status));
|
||||
}
|
||||
|
||||
/* we're already in reset, cancel the init timer
|
||||
* if the reset was called due the hbm protocol error
|
||||
|
@ -153,6 +153,20 @@ struct mei_msg_data {
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
/* Maximum number of processed FW status registers */
|
||||
#define MEI_FW_STATUS_MAX 2
|
||||
|
||||
/*
|
||||
* struct mei_fw_status - storage of FW status data
|
||||
*
|
||||
* @count - number of actually available elements in array
|
||||
* @status - FW status registers
|
||||
*/
|
||||
struct mei_fw_status {
|
||||
int count;
|
||||
u32 status[MEI_FW_STATUS_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mei_me_client - representation of me (fw) client
|
||||
*
|
||||
@ -213,6 +227,7 @@ struct mei_cl {
|
||||
|
||||
/** struct mei_hw_ops
|
||||
*
|
||||
* @fw_status - read FW status from PCI config space
|
||||
* @host_is_ready - query for host readiness
|
||||
|
||||
* @hw_is_ready - query if hw is ready
|
||||
@ -240,6 +255,8 @@ struct mei_cl {
|
||||
*/
|
||||
struct mei_hw_ops {
|
||||
|
||||
int (*fw_status)(struct mei_device *dev,
|
||||
struct mei_fw_status *fw_status);
|
||||
bool (*host_is_ready)(struct mei_device *dev);
|
||||
|
||||
bool (*hw_is_ready)(struct mei_device *dev);
|
||||
@ -681,6 +698,17 @@ static inline int mei_count_full_read_slots(struct mei_device *dev)
|
||||
return dev->ops->rdbuf_full_slots(dev);
|
||||
}
|
||||
|
||||
static inline int mei_fw_status(struct mei_device *dev,
|
||||
struct mei_fw_status *fw_status)
|
||||
{
|
||||
return dev->ops->fw_status(dev, fw_status);
|
||||
}
|
||||
|
||||
#define FW_STS_FMT "%08X %08X"
|
||||
#define FW_STS_PRM(fw_status) \
|
||||
(fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \
|
||||
(fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF
|
||||
|
||||
bool mei_hbuf_acquire(struct mei_device *dev);
|
||||
|
||||
bool mei_write_is_idle(struct mei_device *dev);
|
||||
|
Loading…
Reference in New Issue
Block a user