aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/hw-me.c55
-rw-r--r--drivers/misc/mei/hw-txe-regs.h2
-rw-r--r--drivers/misc/mei/hw-txe.c37
-rw-r--r--drivers/misc/mei/init.c10
-rw-r--r--drivers/misc/mei/mei_dev.h28
5 files changed, 127 insertions, 5 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 4b048b67a248..a31bc4c36cca 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -696,10 +696,65 @@ end:
696 mutex_unlock(&dev->device_lock); 696 mutex_unlock(&dev->device_lock);
697 return IRQ_HANDLED; 697 return IRQ_HANDLED;
698} 698}
699
700/**
701 * mei_me_fw_status - retrieve fw status from the pci config space
702 *
703 * @dev: the device structure
704 * @fw_status: fw status registers storage
705 *
706 * returns 0 on success an error code otherwise
707 */
708static int mei_me_fw_status(struct mei_device *dev,
709 struct mei_fw_status *fw_status)
710{
711 const u32 pci_cfg_reg[] = {PCI_CFG_HFS_1, PCI_CFG_HFS_2};
712 int i;
713
714 if (!fw_status)
715 return -EINVAL;
716
717 switch (dev->pdev->device) {
718 case MEI_DEV_ID_IBXPK_1:
719 case MEI_DEV_ID_IBXPK_2:
720 case MEI_DEV_ID_CPT_1:
721 case MEI_DEV_ID_PBG_1:
722 case MEI_DEV_ID_PPT_1:
723 case MEI_DEV_ID_PPT_2:
724 case MEI_DEV_ID_PPT_3:
725 case MEI_DEV_ID_LPT_H:
726 case MEI_DEV_ID_LPT_W:
727 case MEI_DEV_ID_LPT_LP:
728 case MEI_DEV_ID_LPT_HR:
729 case MEI_DEV_ID_WPT_LP:
730 fw_status->count = 2;
731 break;
732 case MEI_DEV_ID_ICH10_1:
733 case MEI_DEV_ID_ICH10_2:
734 case MEI_DEV_ID_ICH10_3:
735 case MEI_DEV_ID_ICH10_4:
736 fw_status->count = 1;
737 break;
738 default:
739 fw_status->count = 0;
740 break;
741 }
742
743 for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
744 int ret;
745 ret = pci_read_config_dword(dev->pdev,
746 pci_cfg_reg[i], &fw_status->status[i]);
747 if (ret)
748 return ret;
749 }
750 return 0;
751}
752
699static const struct mei_hw_ops mei_me_hw_ops = { 753static const struct mei_hw_ops mei_me_hw_ops = {
700 754
701 .pg_state = mei_me_pg_state, 755 .pg_state = mei_me_pg_state,
702 756
757 .fw_status = mei_me_fw_status,
703 .host_is_ready = mei_me_host_is_ready, 758 .host_is_ready = mei_me_host_is_ready,
704 759
705 .hw_is_ready = mei_me_hw_is_ready, 760 .hw_is_ready = mei_me_hw_is_ready,
diff --git a/drivers/misc/mei/hw-txe-regs.h b/drivers/misc/mei/hw-txe-regs.h
index 7283c24c1af1..f19229c4e655 100644
--- a/drivers/misc/mei/hw-txe-regs.h
+++ b/drivers/misc/mei/hw-txe-regs.h
@@ -89,7 +89,7 @@ enum {
89# define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000 89# define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000
90# define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000 90# define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000
91# define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000 91# define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000
92 92#define PCI_CFG_TXE_FW_STS1 0x48
93 93
94#define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */ 94#define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */
95 95
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 4a6f567f4f80..455a6a56b82b 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -620,7 +620,10 @@ static int mei_txe_write(struct mei_device *dev,
620 mei_txe_input_ready_interrupt_enable(dev); 620 mei_txe_input_ready_interrupt_enable(dev);
621 621
622 if (!mei_txe_is_input_ready(dev)) { 622 if (!mei_txe_is_input_ready(dev)) {
623 dev_err(&dev->pdev->dev, "Input is not ready"); 623 struct mei_fw_status fw_status;
624 mei_fw_status(dev, &fw_status);
625 dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n",
626 FW_STS_PRM(fw_status));
624 return -EAGAIN; 627 return -EAGAIN;
625 } 628 }
626 629
@@ -1039,8 +1042,40 @@ end:
1039 return IRQ_HANDLED; 1042 return IRQ_HANDLED;
1040} 1043}
1041 1044
1045
1046/**
1047 * mei_txe_fw_status - retrieve fw status from the pci config space
1048 *
1049 * @dev: the device structure
1050 * @fw_status: fw status registers storage
1051 *
1052 * returns: 0 on success an error code otherwise
1053 */
1054static int mei_txe_fw_status(struct mei_device *dev,
1055 struct mei_fw_status *fw_status)
1056{
1057 const u32 pci_cfg_reg[] = {PCI_CFG_TXE_FW_STS0, PCI_CFG_TXE_FW_STS1};
1058 int i;
1059
1060 if (!fw_status)
1061 return -EINVAL;
1062
1063 fw_status->count = 2;
1064
1065 for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
1066 int ret;
1067 ret = pci_read_config_dword(dev->pdev,
1068 pci_cfg_reg[i], &fw_status->status[i]);
1069 if (ret)
1070 return ret;
1071 }
1072
1073 return 0;
1074}
1075
1042static const struct mei_hw_ops mei_txe_hw_ops = { 1076static const struct mei_hw_ops mei_txe_hw_ops = {
1043 1077
1078 .fw_status = mei_txe_fw_status,
1044 .host_is_ready = mei_txe_host_is_ready, 1079 .host_is_ready = mei_txe_host_is_ready,
1045 1080
1046 .pg_state = mei_txe_pg_state, 1081 .pg_state = mei_txe_pg_state,
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index abc5ea053bf7..b3f70eb17934 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -74,9 +74,13 @@ int mei_reset(struct mei_device *dev)
74 if (state != MEI_DEV_INITIALIZING && 74 if (state != MEI_DEV_INITIALIZING &&
75 state != MEI_DEV_DISABLED && 75 state != MEI_DEV_DISABLED &&
76 state != MEI_DEV_POWER_DOWN && 76 state != MEI_DEV_POWER_DOWN &&
77 state != MEI_DEV_POWER_UP) 77 state != MEI_DEV_POWER_UP) {
78 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 78 struct mei_fw_status fw_status;
79 mei_dev_state_str(state)); 79 mei_fw_status(dev, &fw_status);
80 dev_warn(&dev->pdev->dev,
81 "unexpected reset: dev_state = %s " FW_STS_FMT "\n",
82 mei_dev_state_str(state), FW_STS_PRM(fw_status));
83 }
80 84
81 /* we're already in reset, cancel the init timer 85 /* we're already in reset, cancel the init timer
82 * if the reset was called due the hbm protocol error 86 * if the reset was called due the hbm protocol error
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index beff9ef319f8..1aaaf0b6681c 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -153,6 +153,20 @@ struct mei_msg_data {
153 unsigned char *data; 153 unsigned char *data;
154}; 154};
155 155
156/* Maximum number of processed FW status registers */
157#define MEI_FW_STATUS_MAX 2
158
159/*
160 * struct mei_fw_status - storage of FW status data
161 *
162 * @count - number of actually available elements in array
163 * @status - FW status registers
164 */
165struct mei_fw_status {
166 int count;
167 u32 status[MEI_FW_STATUS_MAX];
168};
169
156/** 170/**
157 * struct mei_me_client - representation of me (fw) client 171 * struct mei_me_client - representation of me (fw) client
158 * 172 *
@@ -213,6 +227,7 @@ struct mei_cl {
213 227
214/** struct mei_hw_ops 228/** struct mei_hw_ops
215 * 229 *
230 * @fw_status - read FW status from PCI config space
216 * @host_is_ready - query for host readiness 231 * @host_is_ready - query for host readiness
217 232
218 * @hw_is_ready - query if hw is ready 233 * @hw_is_ready - query if hw is ready
@@ -240,6 +255,8 @@ struct mei_cl {
240 */ 255 */
241struct mei_hw_ops { 256struct mei_hw_ops {
242 257
258 int (*fw_status)(struct mei_device *dev,
259 struct mei_fw_status *fw_status);
243 bool (*host_is_ready)(struct mei_device *dev); 260 bool (*host_is_ready)(struct mei_device *dev);
244 261
245 bool (*hw_is_ready)(struct mei_device *dev); 262 bool (*hw_is_ready)(struct mei_device *dev);
@@ -681,6 +698,17 @@ static inline int mei_count_full_read_slots(struct mei_device *dev)
681 return dev->ops->rdbuf_full_slots(dev); 698 return dev->ops->rdbuf_full_slots(dev);
682} 699}
683 700
701static inline int mei_fw_status(struct mei_device *dev,
702 struct mei_fw_status *fw_status)
703{
704 return dev->ops->fw_status(dev, fw_status);
705}
706
707#define FW_STS_FMT "%08X %08X"
708#define FW_STS_PRM(fw_status) \
709 (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \
710 (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF
711
684bool mei_hbuf_acquire(struct mei_device *dev); 712bool mei_hbuf_acquire(struct mei_device *dev);
685 713
686bool mei_write_is_idle(struct mei_device *dev); 714bool mei_write_is_idle(struct mei_device *dev);