diff options
| author | Tomas Winkler <tomas.winkler@intel.com> | 2013-02-06 07:06:41 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-02-06 14:23:47 -0500 |
| commit | 827eef51f8dd9a4ab62b4ad270c15472f46938f2 (patch) | |
| tree | 15798db67af269512bdb4ae54f36e0a26d178d4a | |
| parent | 52c34561415b420301f1580413a9d1891d079494 (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/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/misc/mei/Makefile | 6 | ||||
| -rw-r--r-- | drivers/misc/mei/amthif.c | 6 | ||||
| -rw-r--r-- | drivers/misc/mei/hw-me.c | 87 | ||||
| -rw-r--r-- | drivers/misc/mei/hw-me.h | 19 | ||||
| -rw-r--r-- | drivers/misc/mei/init.c | 2 | ||||
| -rw-r--r-- | drivers/misc/mei/interrupt.c | 10 | ||||
| -rw-r--r-- | drivers/misc/mei/main.c | 5 | ||||
| -rw-r--r-- | drivers/misc/mei/mei_dev.h | 132 |
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 @@ | |||
| 1 | config INTEL_MEI | 1 | config 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 | |||
| 12 | config 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 | |||
| 6 | mei-objs := init.o | 6 | mei-objs := init.o |
| 7 | mei-objs += hbm.o | 7 | mei-objs += hbm.o |
| 8 | mei-objs += interrupt.o | 8 | mei-objs += interrupt.o |
| 9 | mei-objs += hw-me.o | 9 | mei-objs += client.o |
| 10 | mei-objs += main.o | 10 | mei-objs += main.o |
| 11 | mei-objs += amthif.o | 11 | mei-objs += amthif.o |
| 12 | mei-objs += wd.o | 12 | mei-objs += wd.o |
| 13 | mei-objs += client.o | 13 | mei-$(CONFIG_INTEL_MEI_ME) += pci-me.o |
| 14 | mei-objs += pci-me.o | 14 | mei-$(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 | */ |
| 59 | u32 mei_mecbrw_read(const struct mei_device *dev) | 59 | static 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 | */ |
| 105 | void mei_hw_config(struct mei_device *dev) | 105 | static 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 | */ |
| 116 | void mei_clear_interrupts(struct mei_device *dev) | 116 | static 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 | */ |
| 129 | void mei_enable_interrupts(struct mei_device *dev) | 128 | static 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 | */ |
| 142 | void mei_disable_interrupts(struct mei_device *dev) | 141 | static 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 | */ |
| 156 | void mei_hw_reset(struct mei_device *dev, bool intr_enable) | 155 | static 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 | ||
| 189 | void mei_host_set_ready(struct mei_device *dev) | 188 | static 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 | */ |
| 201 | bool mei_host_is_ready(struct mei_device *dev) | 200 | static 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 | */ |
| 214 | bool mei_me_is_ready(struct mei_device *dev) | 213 | static 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 | */ |
| 271 | bool mei_hbuf_is_empty(struct mei_device *dev) | 270 | static 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 | */ |
| 283 | int mei_hbuf_empty_slots(struct mei_device *dev) | 282 | static 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 | ||
| 296 | static 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 | */ |
| 306 | int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, | 311 | static 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 | */ |
| 353 | int mei_count_full_read_slots(struct mei_device *dev) | 359 | static 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 | */ |
| 380 | void mei_read_slots(struct mei_device *dev, unsigned char *buffer, | 386 | static 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, ®, buffer_length); | 398 | memcpy(reg_buf, ®, 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 | ||
| 406 | static 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 | ||
| 37 | struct mei_device *mei_me_dev_init(struct pci_dev *pdev); | 37 | struct mei_device *mei_me_dev_init(struct pci_dev *pdev); |
| 38 | 38 | ||
| 39 | void mei_read_slots(struct mei_device *dev, | ||
| 40 | unsigned char *buffer, | ||
| 41 | unsigned long buffer_length); | ||
| 42 | |||
| 43 | int mei_write_message(struct mei_device *dev, | ||
| 44 | struct mei_msg_hdr *header, | ||
| 45 | unsigned char *buf); | ||
| 46 | |||
| 47 | bool mei_hbuf_is_empty(struct mei_device *dev); | ||
| 48 | |||
| 49 | int mei_hbuf_empty_slots(struct mei_device *dev); | ||
| 50 | |||
| 51 | static 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) */ |
| 57 | static inline unsigned char mei_data2slots(size_t length) | 40 | static 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 | ||
| 62 | int 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); |
| 744 | end: | 744 | end: |
| 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 | ||
| 768 | MODULE_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 | */ | ||
| 238 | struct 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 | */ |
| 377 | void mei_watchdog_unregister(struct mei_device *dev); | 431 | void mei_watchdog_unregister(struct mei_device *dev); |
| 378 | 432 | ||
| 379 | |||
| 380 | /* | 433 | /* |
| 381 | * Register Access Function | 434 | * Register Access Function |
| 382 | */ | 435 | */ |
| 383 | 436 | ||
| 384 | void mei_hw_config(struct mei_device *dev); | 437 | static inline void mei_hw_config(struct mei_device *dev) |
| 385 | void mei_hw_reset(struct mei_device *dev, bool intr_enable); | 438 | { |
| 386 | u32 mei_mecbrw_read(const struct mei_device *dev); | 439 | dev->ops->hw_config(dev); |
| 440 | } | ||
| 441 | static inline void mei_hw_reset(struct mei_device *dev, bool enable) | ||
| 442 | { | ||
| 443 | dev->ops->hw_reset(dev, enable); | ||
| 444 | } | ||
| 445 | |||
| 446 | static inline void mei_clear_interrupts(struct mei_device *dev) | ||
| 447 | { | ||
| 448 | dev->ops->intr_clear(dev); | ||
| 449 | } | ||
| 450 | |||
| 451 | static inline void mei_enable_interrupts(struct mei_device *dev) | ||
| 452 | { | ||
| 453 | dev->ops->intr_enable(dev); | ||
| 454 | } | ||
| 387 | 455 | ||
| 456 | static inline void mei_disable_interrupts(struct mei_device *dev) | ||
| 457 | { | ||
| 458 | dev->ops->intr_disable(dev); | ||
| 459 | } | ||
| 388 | 460 | ||
| 461 | static inline void mei_host_set_ready(struct mei_device *dev) | ||
| 462 | { | ||
| 463 | dev->ops->host_set_ready(dev); | ||
| 464 | } | ||
| 465 | static inline bool mei_host_is_ready(struct mei_device *dev) | ||
| 466 | { | ||
| 467 | return dev->ops->host_is_ready(dev); | ||
| 468 | } | ||
| 469 | static inline bool mei_hw_is_ready(struct mei_device *dev) | ||
| 470 | { | ||
| 471 | return dev->ops->hw_is_ready(dev); | ||
| 472 | } | ||
| 389 | 473 | ||
| 390 | void mei_clear_interrupts(struct mei_device *dev); | 474 | static inline bool mei_hbuf_is_ready(struct mei_device *dev) |
| 391 | void mei_enable_interrupts(struct mei_device *dev); | 475 | { |
| 392 | void mei_disable_interrupts(struct mei_device *dev); | 476 | return dev->ops->hbuf_is_ready(dev); |
| 477 | } | ||
| 393 | 478 | ||
| 394 | void mei_host_set_ready(struct mei_device *dev); | 479 | static inline int mei_hbuf_empty_slots(struct mei_device *dev) |
| 395 | bool mei_host_is_ready(struct mei_device *dev); | 480 | { |
| 396 | bool mei_me_is_ready(struct mei_device *dev); | 481 | return dev->ops->hbuf_free_slots(dev); |
| 482 | } | ||
| 397 | 483 | ||
| 484 | static inline size_t mei_hbuf_max_len(const struct mei_device *dev) | ||
| 485 | { | ||
| 486 | return dev->ops->hbuf_max_len(dev); | ||
| 487 | } | ||
| 398 | 488 | ||
| 489 | static 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 | |||
| 496 | static inline u32 mei_read_hdr(const struct mei_device *dev) | ||
| 497 | { | ||
| 498 | return dev->ops->read_hdr(dev); | ||
| 499 | } | ||
| 500 | |||
| 501 | static 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 | |||
| 507 | static inline int mei_count_full_read_slots(struct mei_device *dev) | ||
| 508 | { | ||
| 509 | return dev->ops->rdbuf_full_slots(dev); | ||
| 510 | } | ||
| 399 | 511 | ||
| 400 | int mei_register(struct device *dev); | 512 | int mei_register(struct device *dev); |
| 401 | void mei_deregister(void); | 513 | void mei_deregister(void); |
