aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/client.c1
-rw-r--r--drivers/misc/mei/init.c10
-rw-r--r--drivers/misc/mei/mei_dev.h7
3 files changed, 18 insertions, 0 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 4f268a377720..1ee2b9492a82 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -370,6 +370,7 @@ void mei_host_client_init(struct work_struct *work)
370 } 370 }
371 371
372 dev->dev_state = MEI_DEV_ENABLED; 372 dev->dev_state = MEI_DEV_ENABLED;
373 dev->reset_count = 0;
373 374
374 mutex_unlock(&dev->device_lock); 375 mutex_unlock(&dev->device_lock);
375} 376}
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 059133d8caca..cdd31c2a2a2b 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -89,6 +89,13 @@ int mei_reset(struct mei_device *dev)
89 interrupts_enabled = state != MEI_DEV_POWER_DOWN; 89 interrupts_enabled = state != MEI_DEV_POWER_DOWN;
90 dev->dev_state = MEI_DEV_RESETTING; 90 dev->dev_state = MEI_DEV_RESETTING;
91 91
92 dev->reset_count++;
93 if (dev->reset_count > MEI_MAX_CONSEC_RESET) {
94 dev_err(&dev->pdev->dev, "reset: reached maximal consecutive resets: disabling the device\n");
95 dev->dev_state = MEI_DEV_DISABLED;
96 return -ENODEV;
97 }
98
92 ret = mei_hw_reset(dev, interrupts_enabled); 99 ret = mei_hw_reset(dev, interrupts_enabled);
93 /* fall through and remove the sw state even if hw reset has failed */ 100 /* fall through and remove the sw state even if hw reset has failed */
94 101
@@ -169,6 +176,7 @@ int mei_start(struct mei_device *dev)
169 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); 176 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
170 177
171 dev->dev_state = MEI_DEV_INITIALIZING; 178 dev->dev_state = MEI_DEV_INITIALIZING;
179 dev->reset_count = 0;
172 mei_reset(dev); 180 mei_reset(dev);
173 181
174 if (dev->dev_state == MEI_DEV_DISABLED) { 182 if (dev->dev_state == MEI_DEV_DISABLED) {
@@ -224,6 +232,7 @@ int mei_restart(struct mei_device *dev)
224 mei_clear_interrupts(dev); 232 mei_clear_interrupts(dev);
225 233
226 dev->dev_state = MEI_DEV_POWER_UP; 234 dev->dev_state = MEI_DEV_POWER_UP;
235 dev->reset_count = 0;
227 236
228 err = mei_reset(dev); 237 err = mei_reset(dev);
229 238
@@ -285,6 +294,7 @@ void mei_device_init(struct mei_device *dev)
285 init_waitqueue_head(&dev->wait_recvd_msg); 294 init_waitqueue_head(&dev->wait_recvd_msg);
286 init_waitqueue_head(&dev->wait_stop_wd); 295 init_waitqueue_head(&dev->wait_stop_wd);
287 dev->dev_state = MEI_DEV_INITIALIZING; 296 dev->dev_state = MEI_DEV_INITIALIZING;
297 dev->reset_count = 0;
288 298
289 mei_io_list_init(&dev->read_list); 299 mei_io_list_init(&dev->read_list);
290 mei_io_list_init(&dev->write_list); 300 mei_io_list_init(&dev->write_list);
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index a617c8494b70..f7de95b4cdd9 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -61,6 +61,11 @@ extern const uuid_le mei_wd_guid;
61#define MEI_CLIENTS_MAX 256 61#define MEI_CLIENTS_MAX 256
62 62
63/* 63/*
64 * maximum number of consecutive resets
65 */
66#define MEI_MAX_CONSEC_RESET 3
67
68/*
64 * Number of File descriptors/handles 69 * Number of File descriptors/handles
65 * that can be opened to the driver. 70 * that can be opened to the driver.
66 * 71 *
@@ -327,6 +332,7 @@ struct mei_cl_device {
327/** 332/**
328 * struct mei_device - MEI private device struct 333 * struct mei_device - MEI private device struct
329 334
335 * @reset_count - limits the number of consecutive resets
330 * @hbm_state - state of host bus message protocol 336 * @hbm_state - state of host bus message protocol
331 * @mem_addr - mem mapped base register address 337 * @mem_addr - mem mapped base register address
332 338
@@ -370,6 +376,7 @@ struct mei_device {
370 /* 376 /*
371 * mei device states 377 * mei device states
372 */ 378 */
379 unsigned long reset_count;
373 enum mei_dev_state dev_state; 380 enum mei_dev_state dev_state;
374 enum mei_hbm_state hbm_state; 381 enum mei_hbm_state hbm_state;
375 u16 init_clients_timer; 382 u16 init_clients_timer;