diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2014-03-31 10:59:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-03 19:21:22 -0400 |
commit | 04dd36619564c3fcf590c2bf2619b14c09cd0749 (patch) | |
tree | 990d48b852f6eba87eb1450d509edcb80481f192 | |
parent | 61a1aea7c7cb40de071e202cfaa31fa2c1fca8ba (diff) |
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>
-rw-r--r-- | drivers/misc/mei/hw-me.c | 55 | ||||
-rw-r--r-- | drivers/misc/mei/hw-txe-regs.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/hw-txe.c | 37 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 10 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 28 |
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 | */ | ||
708 | static 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 | |||
699 | static const struct mei_hw_ops mei_me_hw_ops = { | 753 | static 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 | */ | ||
1054 | static 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 | |||
1042 | static const struct mei_hw_ops mei_txe_hw_ops = { | 1076 | static 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 | */ | ||
165 | struct 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 | */ |
241 | struct mei_hw_ops { | 256 | struct 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 | ||
701 | static 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 | |||
684 | bool mei_hbuf_acquire(struct mei_device *dev); | 712 | bool mei_hbuf_acquire(struct mei_device *dev); |
685 | 713 | ||
686 | bool mei_write_is_idle(struct mei_device *dev); | 714 | bool mei_write_is_idle(struct mei_device *dev); |