diff options
Diffstat (limited to 'drivers/misc/mei/init.c')
-rw-r--r-- | drivers/misc/mei/init.c | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 4460975c0eef..006929222481 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 |
@@ -118,8 +122,8 @@ int mei_reset(struct mei_device *dev) | |||
118 | mei_amthif_reset_params(dev); | 122 | mei_amthif_reset_params(dev); |
119 | } | 123 | } |
120 | 124 | ||
125 | mei_hbm_reset(dev); | ||
121 | 126 | ||
122 | dev->me_clients_num = 0; | ||
123 | dev->rd_msg_hdr = 0; | 127 | dev->rd_msg_hdr = 0; |
124 | dev->wd_pending = false; | 128 | dev->wd_pending = false; |
125 | 129 | ||
@@ -303,15 +307,58 @@ void mei_stop(struct mei_device *dev) | |||
303 | } | 307 | } |
304 | EXPORT_SYMBOL_GPL(mei_stop); | 308 | EXPORT_SYMBOL_GPL(mei_stop); |
305 | 309 | ||
310 | /** | ||
311 | * mei_write_is_idle - check if the write queues are idle | ||
312 | * | ||
313 | * @dev: the device structure | ||
314 | * | ||
315 | * returns true of there is no pending write | ||
316 | */ | ||
317 | bool mei_write_is_idle(struct mei_device *dev) | ||
318 | { | ||
319 | bool idle = (dev->dev_state == MEI_DEV_ENABLED && | ||
320 | list_empty(&dev->ctrl_wr_list.list) && | ||
321 | list_empty(&dev->write_list.list)); | ||
306 | 322 | ||
323 | dev_dbg(&dev->pdev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d\n", | ||
324 | idle, | ||
325 | mei_dev_state_str(dev->dev_state), | ||
326 | list_empty(&dev->ctrl_wr_list.list), | ||
327 | list_empty(&dev->write_list.list)); | ||
307 | 328 | ||
308 | void mei_device_init(struct mei_device *dev) | 329 | return idle; |
330 | } | ||
331 | EXPORT_SYMBOL_GPL(mei_write_is_idle); | ||
332 | |||
333 | int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) | ||
334 | { | ||
335 | int i; | ||
336 | const struct mei_fw_status *fw_src = &dev->cfg->fw_status; | ||
337 | |||
338 | if (!fw_status) | ||
339 | return -EINVAL; | ||
340 | |||
341 | fw_status->count = fw_src->count; | ||
342 | for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) { | ||
343 | int ret; | ||
344 | ret = pci_read_config_dword(dev->pdev, | ||
345 | fw_src->status[i], &fw_status->status[i]); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | EXPORT_SYMBOL_GPL(mei_fw_status); | ||
353 | |||
354 | void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg) | ||
309 | { | 355 | { |
310 | /* setup our list array */ | 356 | /* setup our list array */ |
311 | INIT_LIST_HEAD(&dev->file_list); | 357 | INIT_LIST_HEAD(&dev->file_list); |
312 | INIT_LIST_HEAD(&dev->device_list); | 358 | INIT_LIST_HEAD(&dev->device_list); |
313 | mutex_init(&dev->device_lock); | 359 | mutex_init(&dev->device_lock); |
314 | init_waitqueue_head(&dev->wait_hw_ready); | 360 | init_waitqueue_head(&dev->wait_hw_ready); |
361 | init_waitqueue_head(&dev->wait_pg); | ||
315 | init_waitqueue_head(&dev->wait_recvd_msg); | 362 | init_waitqueue_head(&dev->wait_recvd_msg); |
316 | init_waitqueue_head(&dev->wait_stop_wd); | 363 | init_waitqueue_head(&dev->wait_stop_wd); |
317 | dev->dev_state = MEI_DEV_INITIALIZING; | 364 | dev->dev_state = MEI_DEV_INITIALIZING; |
@@ -340,6 +387,9 @@ void mei_device_init(struct mei_device *dev) | |||
340 | * 0: Reserved for MEI Bus Message communications | 387 | * 0: Reserved for MEI Bus Message communications |
341 | */ | 388 | */ |
342 | bitmap_set(dev->host_clients_map, 0, 1); | 389 | bitmap_set(dev->host_clients_map, 0, 1); |
390 | |||
391 | dev->pg_event = MEI_PG_EVENT_IDLE; | ||
392 | dev->cfg = cfg; | ||
343 | } | 393 | } |
344 | EXPORT_SYMBOL_GPL(mei_device_init); | 394 | EXPORT_SYMBOL_GPL(mei_device_init); |
345 | 395 | ||