diff options
Diffstat (limited to 'kernel/drivers/misc/mei')
-rw-r--r-- | kernel/drivers/misc/mei/amthif.c | 4 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/bus-fixup.c | 2 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/bus.c | 28 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/client.c | 6 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/hbm.c | 3 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/hw-me-regs.h | 4 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/hw-me.c | 10 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/hw-txe.c | 6 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/interrupt.c | 6 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/main.c | 2 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/mei_dev.h | 2 | ||||
-rw-r--r-- | kernel/drivers/misc/mei/pci-me.c | 7 |
12 files changed, 58 insertions, 22 deletions
diff --git a/kernel/drivers/misc/mei/amthif.c b/kernel/drivers/misc/mei/amthif.c index cd0403f09..e79c0371e 100644 --- a/kernel/drivers/misc/mei/amthif.c +++ b/kernel/drivers/misc/mei/amthif.c @@ -417,8 +417,10 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl, dev = cl->dev; - if (dev->iamthif_state != MEI_IAMTHIF_READING) + if (dev->iamthif_state != MEI_IAMTHIF_READING) { + mei_irq_discard_msg(dev, mei_hdr); return 0; + } ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list); if (ret) diff --git a/kernel/drivers/misc/mei/bus-fixup.c b/kernel/drivers/misc/mei/bus-fixup.c index 020de5919..bdc7fcd80 100644 --- a/kernel/drivers/misc/mei/bus-fixup.c +++ b/kernel/drivers/misc/mei/bus-fixup.c @@ -151,7 +151,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret = 0; bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); - if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { + if (bytes_recv < if_version_length) { dev_err(bus->dev, "Could not read IF version\n"); ret = -EIO; goto err; diff --git a/kernel/drivers/misc/mei/bus.c b/kernel/drivers/misc/mei/bus.c index 0b05aa938..be74a2570 100644 --- a/kernel/drivers/misc/mei/bus.c +++ b/kernel/drivers/misc/mei/bus.c @@ -53,6 +53,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bus = cl->dev; mutex_lock(&bus->device_lock); + if (bus->dev_state != MEI_DEV_ENABLED) { + rets = -ENODEV; + goto out; + } + if (!mei_cl_is_connected(cl)) { rets = -ENODEV; goto out; @@ -109,6 +114,10 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) bus = cl->dev; mutex_lock(&bus->device_lock); + if (bus->dev_state != MEI_DEV_ENABLED) { + rets = -ENODEV; + goto out; + } cb = mei_cl_read_cb(cl, NULL); if (cb) @@ -135,7 +144,7 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) mutex_lock(&bus->device_lock); if (!mei_cl_is_connected(cl)) { - rets = -EBUSY; + rets = -ENODEV; goto out; } } @@ -213,17 +222,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv); static void mei_cl_bus_event_work(struct work_struct *work) { struct mei_cl_device *cldev; + struct mei_device *bus; cldev = container_of(work, struct mei_cl_device, event_work); + bus = cldev->bus; + if (cldev->event_cb) cldev->event_cb(cldev, cldev->events, cldev->event_context); cldev->events = 0; /* Prepare for the next read */ - if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) + if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { + mutex_lock(&bus->device_lock); mei_cl_read_start(cldev->cl, 0, NULL); + mutex_unlock(&bus->device_lock); + } } /** @@ -287,6 +302,7 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev, unsigned long events_mask, mei_cldev_event_cb_t event_cb, void *context) { + struct mei_device *bus = cldev->bus; int ret; if (cldev->event_cb) @@ -299,15 +315,17 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev, INIT_WORK(&cldev->event_work, mei_cl_bus_event_work); if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { + mutex_lock(&bus->device_lock); ret = mei_cl_read_start(cldev->cl, 0, NULL); + mutex_unlock(&bus->device_lock); if (ret && ret != -EBUSY) return ret; } if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) { - mutex_lock(&cldev->cl->dev->device_lock); + mutex_lock(&bus->device_lock); ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0); - mutex_unlock(&cldev->cl->dev->device_lock); + mutex_unlock(&bus->device_lock); if (ret) return ret; } @@ -381,7 +399,7 @@ bool mei_cldev_enabled(struct mei_cl_device *cldev) EXPORT_SYMBOL_GPL(mei_cldev_enabled); /** - * mei_cldev_enable_device - enable me client device + * mei_cldev_enable - enable me client device * create connection with me client * * @cldev: me client device diff --git a/kernel/drivers/misc/mei/client.c b/kernel/drivers/misc/mei/client.c index a6c87c713..2ff39fbc7 100644 --- a/kernel/drivers/misc/mei/client.c +++ b/kernel/drivers/misc/mei/client.c @@ -698,7 +698,7 @@ void mei_host_client_init(struct work_struct *work) pm_runtime_mark_last_busy(dev->dev); dev_dbg(dev->dev, "rpm: autosuspend\n"); - pm_runtime_autosuspend(dev->dev); + pm_request_autosuspend(dev->dev); } /** @@ -1735,6 +1735,10 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) wake_up(&cl->wait); break; + case MEI_FOP_DISCONNECT_RSP: + mei_io_cb_free(cb); + mei_cl_set_disconnected(cl); + break; default: BUG_ON(0); } diff --git a/kernel/drivers/misc/mei/hbm.c b/kernel/drivers/misc/mei/hbm.c index e7b7aad09..fd8a9f057 100644 --- a/kernel/drivers/misc/mei/hbm.c +++ b/kernel/drivers/misc/mei/hbm.c @@ -873,8 +873,7 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL); if (!cb) return -ENOMEM; - cl_dbg(dev, cl, "add disconnect response as first\n"); - list_add(&cb->list, &dev->ctrl_wr_list.list); + list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } return 0; } diff --git a/kernel/drivers/misc/mei/hw-me-regs.h b/kernel/drivers/misc/mei/hw-me-regs.h index a8a68acd3..a2661381d 100644 --- a/kernel/drivers/misc/mei/hw-me-regs.h +++ b/kernel/drivers/misc/mei/hw-me-regs.h @@ -121,6 +121,10 @@ #define MEI_DEV_ID_SPT_2 0x9D3B /* Sunrise Point 2 */ #define MEI_DEV_ID_SPT_H 0xA13A /* Sunrise Point H */ #define MEI_DEV_ID_SPT_H_2 0xA13B /* Sunrise Point H 2 */ + +#define MEI_DEV_ID_KBP 0xA2BA /* Kaby Point */ +#define MEI_DEV_ID_KBP_2 0xA2BB /* Kaby Point 2 */ + /* * MEI HW Section */ diff --git a/kernel/drivers/misc/mei/hw-me.c b/kernel/drivers/misc/mei/hw-me.c index 25b1997a6..36333750c 100644 --- a/kernel/drivers/misc/mei/hw-me.c +++ b/kernel/drivers/misc/mei/hw-me.c @@ -1258,8 +1258,14 @@ static bool mei_me_fw_type_nm(struct pci_dev *pdev) static bool mei_me_fw_type_sps(struct pci_dev *pdev) { u32 reg; - /* Read ME FW Status check for SPS Firmware */ - pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); + unsigned int devfn; + + /* + * Read ME FW Status register to check for SPS Firmware + * The SPS FW is only signaled in pci function 0 + */ + devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); + pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, ®); /* if bits [19:16] = 15, running SPS Firmware */ return (reg & 0xf0000) == 0xf0000; } diff --git a/kernel/drivers/misc/mei/hw-txe.c b/kernel/drivers/misc/mei/hw-txe.c index bae680c64..396d75d9f 100644 --- a/kernel/drivers/misc/mei/hw-txe.c +++ b/kernel/drivers/misc/mei/hw-txe.c @@ -972,11 +972,13 @@ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack) hisr = mei_txe_br_reg_read(hw, HISR_REG); aliveness = mei_txe_aliveness_get(dev); - if (hhisr & IPC_HHIER_SEC && aliveness) + if (hhisr & IPC_HHIER_SEC && aliveness) { ipc_isr = mei_txe_sec_reg_read_silent(hw, SEC_IPC_HOST_INT_STATUS_REG); - else + } else { ipc_isr = 0; + hhisr &= ~IPC_HHIER_SEC; + } generated = generated || (hisr & HISR_INT_STS_MSK) || diff --git a/kernel/drivers/misc/mei/interrupt.c b/kernel/drivers/misc/mei/interrupt.c index 64b568a02..d1df797c7 100644 --- a/kernel/drivers/misc/mei/interrupt.c +++ b/kernel/drivers/misc/mei/interrupt.c @@ -76,7 +76,6 @@ static inline int mei_cl_hbm_equal(struct mei_cl *cl, * @dev: mei device * @hdr: message header */ -static inline void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr) { /* @@ -184,10 +183,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, return -EMSGSIZE; ret = mei_hbm_cl_disconnect_rsp(dev, cl); - mei_cl_set_disconnected(cl); - mei_io_cb_free(cb); - mei_me_cl_put(cl->me_cl); - cl->me_cl = NULL; + list_move_tail(&cb->list, &cmpl_list->list); return ret; } diff --git a/kernel/drivers/misc/mei/main.c b/kernel/drivers/misc/mei/main.c index 80f9afcb1..4ef189a7a 100644 --- a/kernel/drivers/misc/mei/main.c +++ b/kernel/drivers/misc/mei/main.c @@ -207,7 +207,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, mutex_lock(&dev->device_lock); if (!mei_cl_is_connected(cl)) { - rets = -EBUSY; + rets = -ENODEV; goto out; } } diff --git a/kernel/drivers/misc/mei/mei_dev.h b/kernel/drivers/misc/mei/mei_dev.h index 4250555d5..1b06e2fd6 100644 --- a/kernel/drivers/misc/mei/mei_dev.h +++ b/kernel/drivers/misc/mei/mei_dev.h @@ -782,6 +782,8 @@ bool mei_hbuf_acquire(struct mei_device *dev); bool mei_write_is_idle(struct mei_device *dev); +void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr); + #if IS_ENABLED(CONFIG_DEBUG_FS) int mei_dbgfs_register(struct mei_device *dev, const char *name); void mei_dbgfs_deregister(struct mei_device *dev); diff --git a/kernel/drivers/misc/mei/pci-me.c b/kernel/drivers/misc/mei/pci-me.c index 27678d815..01e20384a 100644 --- a/kernel/drivers/misc/mei/pci-me.c +++ b/kernel/drivers/misc/mei/pci-me.c @@ -84,8 +84,11 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, mei_me_pch8_cfg)}, /* required last entry */ {0, } |