aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-02-06 07:06:41 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-06 14:23:47 -0500
commit827eef51f8dd9a4ab62b4ad270c15472f46938f2 (patch)
tree15798db67af269512bdb4ae54f36e0a26d178d4a
parent52c34561415b420301f1580413a9d1891d079494 (diff)
mei: separate compilation of the ME hardware specifics
We add struct mei_hw_ops to virtualize access to hw specific configurations. This allows us to separate the compilation of the ME interface from the ME hardware specifics Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mei/Kconfig17
-rw-r--r--drivers/misc/mei/Makefile6
-rw-r--r--drivers/misc/mei/amthif.c6
-rw-r--r--drivers/misc/mei/hw-me.c87
-rw-r--r--drivers/misc/mei/hw-me.h19
-rw-r--r--drivers/misc/mei/init.c2
-rw-r--r--drivers/misc/mei/interrupt.c10
-rw-r--r--drivers/misc/mei/main.c5
-rw-r--r--drivers/misc/mei/mei_dev.h132
9 files changed, 210 insertions, 74 deletions
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 5a79ccde2fdf..fa5c24982c88 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -1,11 +1,22 @@
1config INTEL_MEI 1config INTEL_MEI
2 tristate "Intel Management Engine Interface (Intel MEI)" 2 tristate "Intel Management Engine Interface"
3 depends on X86 && PCI && WATCHDOG_CORE 3 depends on X86 && PCI
4 help 4 help
5 The Intel Management Engine (Intel ME) provides Manageability, 5 The Intel Management Engine (Intel ME) provides Manageability,
6 Security and Media services for system containing Intel chipsets. 6 Security and Media services for system containing Intel chipsets.
7 if selected /dev/mei misc device will be created. 7 if selected /dev/mei misc device will be created.
8 8
9 For more information see
10 <http://software.intel.com/en-us/manageability/>
11
12config INTEL_MEI_ME
13 bool "ME Enabled Intel Chipsets"
14 depends on INTEL_MEI
15 depends on X86 && PCI && WATCHDOG_CORE
16 default y
17 help
18 MEI support for ME Enabled Intel chipsets.
19
9 Supported Chipsets are: 20 Supported Chipsets are:
10 7 Series Chipset Family 21 7 Series Chipset Family
11 6 Series Chipset Family 22 6 Series Chipset Family
@@ -24,5 +35,3 @@ config INTEL_MEI
24 82Q33 Express 35 82Q33 Express
25 82X38/X48 Express 36 82X38/X48 Express
26 37
27 For more information see
28 <http://software.intel.com/en-us/manageability/>
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 068f55354811..040af6c7b147 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -6,9 +6,9 @@ obj-$(CONFIG_INTEL_MEI) += mei.o
6mei-objs := init.o 6mei-objs := init.o
7mei-objs += hbm.o 7mei-objs += hbm.o
8mei-objs += interrupt.o 8mei-objs += interrupt.o
9mei-objs += hw-me.o 9mei-objs += client.o
10mei-objs += main.o 10mei-objs += main.o
11mei-objs += amthif.o 11mei-objs += amthif.o
12mei-objs += wd.o 12mei-objs += wd.o
13mei-objs += client.o 13mei-$(CONFIG_INTEL_MEI_ME) += pci-me.o
14mei-objs += pci-me.o 14mei-$(CONFIG_INTEL_MEI_ME) += hw-me.o
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 263ed4ccd6f2..a7c483850083 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -300,8 +300,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
300 if (ret && dev->mei_host_buffer_is_empty) { 300 if (ret && dev->mei_host_buffer_is_empty) {
301 ret = 0; 301 ret = 0;
302 dev->mei_host_buffer_is_empty = false; 302 dev->mei_host_buffer_is_empty = false;
303 if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { 303 if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
304 mei_hdr.length = mei_hbuf_max_data(dev); 304 mei_hdr.length = mei_hbuf_max_len(dev);
305 mei_hdr.msg_complete = 0; 305 mei_hdr.msg_complete = 0;
306 } else { 306 } else {
307 mei_hdr.length = cb->request_buffer.size; 307 mei_hdr.length = cb->request_buffer.size;
@@ -583,7 +583,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
583 dev->iamthif_msg_buf_index = 0; 583 dev->iamthif_msg_buf_index = 0;
584 dev->iamthif_msg_buf_size = 0; 584 dev->iamthif_msg_buf_size = 0;
585 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; 585 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
586 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 586 dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev);
587 return 0; 587 return 0;
588} 588}
589 589
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 3bdf22848a91..6300943497ae 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -56,7 +56,7 @@ static inline void mei_reg_write(const struct mei_me_hw *hw,
56 * 56 *
57 * returns ME_CB_RW register value (u32) 57 * returns ME_CB_RW register value (u32)
58 */ 58 */
59u32 mei_mecbrw_read(const struct mei_device *dev) 59static u32 mei_me_mecbrw_read(const struct mei_device *dev)
60{ 60{
61 return mei_reg_read(to_me_hw(dev), ME_CB_RW); 61 return mei_reg_read(to_me_hw(dev), ME_CB_RW);
62} 62}
@@ -102,7 +102,7 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr)
102 * 102 *
103 * @dev: mei device 103 * @dev: mei device
104 */ 104 */
105void mei_hw_config(struct mei_device *dev) 105static void mei_me_hw_config(struct mei_device *dev)
106{ 106{
107 u32 hcsr = mei_hcsr_read(to_me_hw(dev)); 107 u32 hcsr = mei_hcsr_read(to_me_hw(dev));
108 /* Doesn't change in runtime */ 108 /* Doesn't change in runtime */
@@ -113,20 +113,19 @@ void mei_hw_config(struct mei_device *dev)
113 * 113 *
114 * @dev: the device structure 114 * @dev: the device structure
115 */ 115 */
116void mei_clear_interrupts(struct mei_device *dev) 116static void mei_me_intr_clear(struct mei_device *dev)
117{ 117{
118 struct mei_me_hw *hw = to_me_hw(dev); 118 struct mei_me_hw *hw = to_me_hw(dev);
119 u32 hcsr = mei_hcsr_read(hw); 119 u32 hcsr = mei_hcsr_read(hw);
120 if ((hcsr & H_IS) == H_IS) 120 if ((hcsr & H_IS) == H_IS)
121 mei_reg_write(hw, H_CSR, hcsr); 121 mei_reg_write(hw, H_CSR, hcsr);
122} 122}
123
124/** 123/**
125 * mei_enable_interrupts - enables mei device interrupts 124 * mei_me_intr_enable - enables mei device interrupts
126 * 125 *
127 * @dev: the device structure 126 * @dev: the device structure
128 */ 127 */
129void mei_enable_interrupts(struct mei_device *dev) 128static void mei_me_intr_enable(struct mei_device *dev)
130{ 129{
131 struct mei_me_hw *hw = to_me_hw(dev); 130 struct mei_me_hw *hw = to_me_hw(dev);
132 u32 hcsr = mei_hcsr_read(hw); 131 u32 hcsr = mei_hcsr_read(hw);
@@ -139,7 +138,7 @@ void mei_enable_interrupts(struct mei_device *dev)
139 * 138 *
140 * @dev: the device structure 139 * @dev: the device structure
141 */ 140 */
142void mei_disable_interrupts(struct mei_device *dev) 141static void mei_me_intr_disable(struct mei_device *dev)
143{ 142{
144 struct mei_me_hw *hw = to_me_hw(dev); 143 struct mei_me_hw *hw = to_me_hw(dev);
145 u32 hcsr = mei_hcsr_read(hw); 144 u32 hcsr = mei_hcsr_read(hw);
@@ -148,12 +147,12 @@ void mei_disable_interrupts(struct mei_device *dev)
148} 147}
149 148
150/** 149/**
151 * mei_hw_reset - resets fw via mei csr register. 150 * mei_me_hw_reset - resets fw via mei csr register.
152 * 151 *
153 * @dev: the device structure 152 * @dev: the device structure
154 * @interrupts_enabled: if interrupt should be enabled after reset. 153 * @interrupts_enabled: if interrupt should be enabled after reset.
155 */ 154 */
156void mei_hw_reset(struct mei_device *dev, bool intr_enable) 155static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
157{ 156{
158 struct mei_me_hw *hw = to_me_hw(dev); 157 struct mei_me_hw *hw = to_me_hw(dev);
159 u32 hcsr = mei_hcsr_read(hw); 158 u32 hcsr = mei_hcsr_read(hw);
@@ -180,25 +179,25 @@ void mei_hw_reset(struct mei_device *dev, bool intr_enable)
180} 179}
181 180
182/** 181/**
183 * mei_host_set_ready - enable device 182 * mei_me_host_set_ready - enable device
184 * 183 *
185 * @dev - mei device 184 * @dev - mei device
186 * returns bool 185 * returns bool
187 */ 186 */
188 187
189void mei_host_set_ready(struct mei_device *dev) 188static void mei_me_host_set_ready(struct mei_device *dev)
190{ 189{
191 struct mei_me_hw *hw = to_me_hw(dev); 190 struct mei_me_hw *hw = to_me_hw(dev);
192 hw->host_hw_state |= H_IE | H_IG | H_RDY; 191 hw->host_hw_state |= H_IE | H_IG | H_RDY;
193 mei_hcsr_set(hw, hw->host_hw_state); 192 mei_hcsr_set(hw, hw->host_hw_state);
194} 193}
195/** 194/**
196 * mei_host_is_ready - check whether the host has turned ready 195 * mei_me_host_is_ready - check whether the host has turned ready
197 * 196 *
198 * @dev - mei device 197 * @dev - mei device
199 * returns bool 198 * returns bool
200 */ 199 */
201bool mei_host_is_ready(struct mei_device *dev) 200static bool mei_me_host_is_ready(struct mei_device *dev)
202{ 201{
203 struct mei_me_hw *hw = to_me_hw(dev); 202 struct mei_me_hw *hw = to_me_hw(dev);
204 hw->host_hw_state = mei_hcsr_read(hw); 203 hw->host_hw_state = mei_hcsr_read(hw);
@@ -206,12 +205,12 @@ bool mei_host_is_ready(struct mei_device *dev)
206} 205}
207 206
208/** 207/**
209 * mei_me_is_ready - check whether the me has turned ready 208 * mei_me_hw_is_ready - check whether the me(hw) has turned ready
210 * 209 *
211 * @dev - mei device 210 * @dev - mei device
212 * returns bool 211 * returns bool
213 */ 212 */
214bool mei_me_is_ready(struct mei_device *dev) 213static bool mei_me_hw_is_ready(struct mei_device *dev)
215{ 214{
216 struct mei_me_hw *hw = to_me_hw(dev); 215 struct mei_me_hw *hw = to_me_hw(dev);
217 hw->me_hw_state = mei_mecsr_read(hw); 216 hw->me_hw_state = mei_mecsr_read(hw);
@@ -268,19 +267,19 @@ static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
268 * 267 *
269 * returns true if empty, false - otherwise. 268 * returns true if empty, false - otherwise.
270 */ 269 */
271bool mei_hbuf_is_empty(struct mei_device *dev) 270static bool mei_me_hbuf_is_empty(struct mei_device *dev)
272{ 271{
273 return mei_hbuf_filled_slots(dev) == 0; 272 return mei_hbuf_filled_slots(dev) == 0;
274} 273}
275 274
276/** 275/**
277 * mei_hbuf_empty_slots - counts write empty slots. 276 * mei_me_hbuf_empty_slots - counts write empty slots.
278 * 277 *
279 * @dev: the device structure 278 * @dev: the device structure
280 * 279 *
281 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count 280 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
282 */ 281 */
283int mei_hbuf_empty_slots(struct mei_device *dev) 282static int mei_me_hbuf_empty_slots(struct mei_device *dev)
284{ 283{
285 unsigned char filled_slots, empty_slots; 284 unsigned char filled_slots, empty_slots;
286 285
@@ -294,6 +293,12 @@ int mei_hbuf_empty_slots(struct mei_device *dev)
294 return empty_slots; 293 return empty_slots;
295} 294}
296 295
296static size_t mei_me_hbuf_max_len(const struct mei_device *dev)
297{
298 return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
299}
300
301
297/** 302/**
298 * mei_write_message - writes a message to mei device. 303 * mei_write_message - writes a message to mei device.
299 * 304 *
@@ -303,8 +308,9 @@ int mei_hbuf_empty_slots(struct mei_device *dev)
303 * 308 *
304 * This function returns -EIO if write has failed 309 * This function returns -EIO if write has failed
305 */ 310 */
306int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, 311static int mei_me_write_message(struct mei_device *dev,
307 unsigned char *buf) 312 struct mei_msg_hdr *header,
313 unsigned char *buf)
308{ 314{
309 struct mei_me_hw *hw = to_me_hw(dev); 315 struct mei_me_hw *hw = to_me_hw(dev);
310 unsigned long rem, dw_cnt; 316 unsigned long rem, dw_cnt;
@@ -337,20 +343,20 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
337 343
338 hcsr = mei_hcsr_read(hw) | H_IG; 344 hcsr = mei_hcsr_read(hw) | H_IG;
339 mei_hcsr_set(hw, hcsr); 345 mei_hcsr_set(hw, hcsr);
340 if (!mei_me_is_ready(dev)) 346 if (!mei_me_hw_is_ready(dev))
341 return -EIO; 347 return -EIO;
342 348
343 return 0; 349 return 0;
344} 350}
345 351
346/** 352/**
347 * mei_count_full_read_slots - counts read full slots. 353 * mei_me_count_full_read_slots - counts read full slots.
348 * 354 *
349 * @dev: the device structure 355 * @dev: the device structure
350 * 356 *
351 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count 357 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
352 */ 358 */
353int mei_count_full_read_slots(struct mei_device *dev) 359static int mei_me_count_full_read_slots(struct mei_device *dev)
354{ 360{
355 struct mei_me_hw *hw = to_me_hw(dev); 361 struct mei_me_hw *hw = to_me_hw(dev);
356 char read_ptr, write_ptr; 362 char read_ptr, write_ptr;
@@ -371,13 +377,13 @@ int mei_count_full_read_slots(struct mei_device *dev)
371} 377}
372 378
373/** 379/**
374 * mei_read_slots - reads a message from mei device. 380 * mei_me_read_slots - reads a message from mei device.
375 * 381 *
376 * @dev: the device structure 382 * @dev: the device structure
377 * @buffer: message buffer will be written 383 * @buffer: message buffer will be written
378 * @buffer_length: message size will be read 384 * @buffer_length: message size will be read
379 */ 385 */
380void mei_read_slots(struct mei_device *dev, unsigned char *buffer, 386static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer,
381 unsigned long buffer_length) 387 unsigned long buffer_length)
382{ 388{
383 struct mei_me_hw *hw = to_me_hw(dev); 389 struct mei_me_hw *hw = to_me_hw(dev);
@@ -385,17 +391,42 @@ void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
385 u32 hcsr; 391 u32 hcsr;
386 392
387 for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) 393 for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32))
388 *reg_buf++ = mei_mecbrw_read(dev); 394 *reg_buf++ = mei_me_mecbrw_read(dev);
389 395
390 if (buffer_length > 0) { 396 if (buffer_length > 0) {
391 u32 reg = mei_mecbrw_read(dev); 397 u32 reg = mei_me_mecbrw_read(dev);
392 memcpy(reg_buf, &reg, buffer_length); 398 memcpy(reg_buf, &reg, buffer_length);
393 } 399 }
394 400
395 hcsr = mei_hcsr_read(hw) | H_IG; 401 hcsr = mei_hcsr_read(hw) | H_IG;
396 mei_hcsr_set(hw, hcsr); 402 mei_hcsr_set(hw, hcsr);
403 return 0;
397} 404}
398 405
406static const struct mei_hw_ops mei_me_hw_ops = {
407
408 .host_set_ready = mei_me_host_set_ready,
409 .host_is_ready = mei_me_host_is_ready,
410
411 .hw_is_ready = mei_me_hw_is_ready,
412 .hw_reset = mei_me_hw_reset,
413 .hw_config = mei_me_hw_config,
414
415 .intr_clear = mei_me_intr_clear,
416 .intr_enable = mei_me_intr_enable,
417 .intr_disable = mei_me_intr_disable,
418
419 .hbuf_free_slots = mei_me_hbuf_empty_slots,
420 .hbuf_is_ready = mei_me_hbuf_is_empty,
421 .hbuf_max_len = mei_me_hbuf_max_len,
422
423 .write = mei_me_write_message,
424
425 .rdbuf_full_slots = mei_me_count_full_read_slots,
426 .read_hdr = mei_me_mecbrw_read,
427 .read = mei_me_read_slots
428};
429
399/** 430/**
400 * init_mei_device - allocates and initializes the mei device structure 431 * init_mei_device - allocates and initializes the mei device structure
401 * 432 *
@@ -422,6 +453,8 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev)
422 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 453 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
423 INIT_WORK(&dev->init_work, mei_host_client_init); 454 INIT_WORK(&dev->init_work, mei_host_client_init);
424 455
456 dev->ops = &mei_me_hw_ops;
457
425 dev->pdev = pdev; 458 dev->pdev = pdev;
426 return dev; 459 return dev;
427} 460}
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 53bcc0087e26..9a3aaab9bcf0 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -36,29 +36,10 @@ struct mei_me_hw {
36 36
37struct mei_device *mei_me_dev_init(struct pci_dev *pdev); 37struct mei_device *mei_me_dev_init(struct pci_dev *pdev);
38 38
39void mei_read_slots(struct mei_device *dev,
40 unsigned char *buffer,
41 unsigned long buffer_length);
42
43int mei_write_message(struct mei_device *dev,
44 struct mei_msg_hdr *header,
45 unsigned char *buf);
46
47bool mei_hbuf_is_empty(struct mei_device *dev);
48
49int mei_hbuf_empty_slots(struct mei_device *dev);
50
51static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
52{
53 return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
54}
55
56/* get slots (dwords) from a message length + header (bytes) */ 39/* get slots (dwords) from a message length + header (bytes) */
57static inline unsigned char mei_data2slots(size_t length) 40static inline unsigned char mei_data2slots(size_t length)
58{ 41{
59 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); 42 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
60} 43}
61 44
62int mei_count_full_read_slots(struct mei_device *dev);
63
64#endif /* _MEI_INTERFACE_H_ */ 45#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 1e1876ff25b1..51a005e80952 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -104,7 +104,7 @@ int mei_hw_init(struct mei_device *dev)
104 goto err; 104 goto err;
105 } 105 }
106 106
107 if (!mei_me_is_ready(dev)) { 107 if (!mei_hw_is_ready(dev)) {
108 dev_err(&dev->pdev->dev, "ME is not ready.\n"); 108 dev_err(&dev->pdev->dev, "ME is not ready.\n");
109 goto err; 109 goto err;
110 } 110 }
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index b04ed9bdf758..431aa91fd002 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -329,7 +329,7 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
329 int ret = 0; 329 int ret = 0;
330 330
331 if (!dev->rd_msg_hdr) { 331 if (!dev->rd_msg_hdr) {
332 dev->rd_msg_hdr = mei_mecbrw_read(dev); 332 dev->rd_msg_hdr = mei_read_hdr(dev);
333 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 333 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
334 (*slots)--; 334 (*slots)--;
335 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 335 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
@@ -430,7 +430,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
430 s32 slots; 430 s32 slots;
431 int ret; 431 int ret;
432 432
433 if (!mei_hbuf_is_empty(dev)) { 433 if (!mei_hbuf_is_ready(dev)) {
434 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 434 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
435 return 0; 435 return 0;
436 } 436 }
@@ -698,7 +698,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
698 mei_clear_interrupts(dev); 698 mei_clear_interrupts(dev);
699 699
700 /* check if ME wants a reset */ 700 /* check if ME wants a reset */
701 if (!mei_me_is_ready(dev) && 701 if (!mei_hw_is_ready(dev) &&
702 dev->dev_state != MEI_DEV_RESETING && 702 dev->dev_state != MEI_DEV_RESETING &&
703 dev->dev_state != MEI_DEV_INITIALIZING) { 703 dev->dev_state != MEI_DEV_INITIALIZING) {
704 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 704 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
@@ -709,7 +709,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
709 709
710 /* check if we need to start the dev */ 710 /* check if we need to start the dev */
711 if (!mei_host_is_ready(dev)) { 711 if (!mei_host_is_ready(dev)) {
712 if (mei_me_is_ready(dev)) { 712 if (mei_hw_is_ready(dev)) {
713 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 713 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
714 714
715 mei_host_set_ready(dev); 715 mei_host_set_ready(dev);
@@ -743,7 +743,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
743 rets = mei_irq_thread_write_handler(dev, &complete_list); 743 rets = mei_irq_thread_write_handler(dev, &complete_list);
744end: 744end:
745 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 745 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
746 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 746 dev->mei_host_buffer_is_empty = mei_hbuf_is_ready(dev);
747 747
748 bus_message_received = false; 748 bus_message_received = false;
749 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { 749 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 018623c9a8e1..843ae2febc70 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -462,8 +462,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
462 } 462 }
463 463
464 dev->mei_host_buffer_is_empty = false; 464 dev->mei_host_buffer_is_empty = false;
465 if (length > mei_hbuf_max_data(dev)) { 465 if (length > mei_hbuf_max_len(dev)) {
466 mei_hdr.length = mei_hbuf_max_data(dev); 466 mei_hdr.length = mei_hbuf_max_len(dev);
467 mei_hdr.msg_complete = 0; 467 mei_hdr.msg_complete = 0;
468 } else { 468 } else {
469 mei_hdr.length = length; 469 mei_hdr.length = length;
@@ -765,4 +765,5 @@ void mei_deregister(void)
765 mei_misc_device.parent = NULL; 765 mei_misc_device.parent = NULL;
766} 766}
767 767
768MODULE_LICENSE("GPL v2");
768 769
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index bb759fd9ee4a..c974292f16d6 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -211,6 +211,58 @@ struct mei_cl {
211 struct mei_cl_cb *read_cb; 211 struct mei_cl_cb *read_cb;
212}; 212};
213 213
214/** struct mei_hw_ops
215 *
216 * @host_set_ready - notify FW that host side is ready
217 * @host_is_ready - query for host readiness
218
219 * @hw_is_ready - query if hw is ready
220 * @hw_reset - reset hw
221 * @hw_config - configure hw
222
223 * @intr_clear - clear pending interrupts
224 * @intr_enable - enable interrupts
225 * @intr_disable - disable interrupts
226
227 * @hbuf_free_slots - query for write buffer empty slots
228 * @hbuf_is_ready - query if write buffer is empty
229 * @hbuf_max_len - query for write buffer max len
230
231 * @write - write a message to FW
232
233 * @rdbuf_full_slots - query how many slots are filled
234
235 * @read_hdr - get first 4 bytes (header)
236 * @read - read a buffer from the FW
237 */
238struct mei_hw_ops {
239
240 void (*host_set_ready) (struct mei_device *dev);
241 bool (*host_is_ready) (struct mei_device *dev);
242
243 bool (*hw_is_ready) (struct mei_device *dev);
244 void (*hw_reset) (struct mei_device *dev, bool enable);
245 void (*hw_config) (struct mei_device *dev);
246
247 void (*intr_clear) (struct mei_device *dev);
248 void (*intr_enable) (struct mei_device *dev);
249 void (*intr_disable) (struct mei_device *dev);
250
251 int (*hbuf_free_slots) (struct mei_device *dev);
252 bool (*hbuf_is_ready) (struct mei_device *dev);
253 size_t (*hbuf_max_len) (const struct mei_device *dev);
254
255 int (*write)(struct mei_device *dev,
256 struct mei_msg_hdr *hdr,
257 unsigned char *buf);
258
259 int (*rdbuf_full_slots)(struct mei_device *dev);
260
261 u32 (*read_hdr)(const struct mei_device *dev);
262 int (*read) (struct mei_device *dev,
263 unsigned char *buf, unsigned long len);
264};
265
214/** 266/**
215 * struct mei_device - MEI private device struct 267 * struct mei_device - MEI private device struct
216 * @mem_addr - mem mapped base register address 268 * @mem_addr - mem mapped base register address
@@ -306,6 +358,8 @@ struct mei_device {
306 bool iamthif_canceled; 358 bool iamthif_canceled;
307 359
308 struct work_struct init_work; 360 struct work_struct init_work;
361
362 const struct mei_hw_ops *ops;
309 char hw[0] __aligned(sizeof(void *)); 363 char hw[0] __aligned(sizeof(void *));
310}; 364};
311 365
@@ -376,26 +430,84 @@ void mei_watchdog_register(struct mei_device *dev);
376 */ 430 */
377void mei_watchdog_unregister(struct mei_device *dev); 431void mei_watchdog_unregister(struct mei_device *dev);
378 432
379
380/* 433/*
381 * Register Access Function 434 * Register Access Function
382 */ 435 */
383 436
384void mei_hw_config(struct mei_device *dev); 437static inline void mei_hw_config(struct mei_device *dev)
385void mei_hw_reset(struct mei_device *dev, bool intr_enable); 438{
386u32 mei_mecbrw_read(const struct mei_device *dev); 439 dev->ops->hw_config(dev);
440}
441static inline void mei_hw_reset(struct mei_device *dev, bool enable)
442{
443 dev->ops->hw_reset(dev, enable);
444}
445
446static inline void mei_clear_interrupts(struct mei_device *dev)
447{
448 dev->ops->intr_clear(dev);
449}
450
451static inline void mei_enable_interrupts(struct mei_device *dev)
452{
453 dev->ops->intr_enable(dev);
454}
387 455
456static inline void mei_disable_interrupts(struct mei_device *dev)
457{
458 dev->ops->intr_disable(dev);
459}
388 460
461static inline void mei_host_set_ready(struct mei_device *dev)
462{
463 dev->ops->host_set_ready(dev);
464}
465static inline bool mei_host_is_ready(struct mei_device *dev)
466{
467 return dev->ops->host_is_ready(dev);
468}
469static inline bool mei_hw_is_ready(struct mei_device *dev)
470{
471 return dev->ops->hw_is_ready(dev);
472}
389 473
390void mei_clear_interrupts(struct mei_device *dev); 474static inline bool mei_hbuf_is_ready(struct mei_device *dev)
391void mei_enable_interrupts(struct mei_device *dev); 475{
392void mei_disable_interrupts(struct mei_device *dev); 476 return dev->ops->hbuf_is_ready(dev);
477}
393 478
394void mei_host_set_ready(struct mei_device *dev); 479static inline int mei_hbuf_empty_slots(struct mei_device *dev)
395bool mei_host_is_ready(struct mei_device *dev); 480{
396bool mei_me_is_ready(struct mei_device *dev); 481 return dev->ops->hbuf_free_slots(dev);
482}
397 483
484static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
485{
486 return dev->ops->hbuf_max_len(dev);
487}
398 488
489static inline int mei_write_message(struct mei_device *dev,
490 struct mei_msg_hdr *hdr,
491 unsigned char *buf)
492{
493 return dev->ops->write(dev, hdr, buf);
494}
495
496static inline u32 mei_read_hdr(const struct mei_device *dev)
497{
498 return dev->ops->read_hdr(dev);
499}
500
501static inline void mei_read_slots(struct mei_device *dev,
502 unsigned char *buf, unsigned long len)
503{
504 dev->ops->read(dev, buf, len);
505}
506
507static inline int mei_count_full_read_slots(struct mei_device *dev)
508{
509 return dev->ops->rdbuf_full_slots(dev);
510}
399 511
400int mei_register(struct device *dev); 512int mei_register(struct device *dev);
401void mei_deregister(void); 513void mei_deregister(void);