diff options
-rw-r--r-- | drivers/misc/mei/hw-me-regs.h | 4 | ||||
-rw-r--r-- | drivers/misc/mei/hw-me.c | 35 | ||||
-rw-r--r-- | drivers/misc/mei/hw-me.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/pci-me.c | 27 |
4 files changed, 33 insertions, 35 deletions
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 4c8f05ea3651..8793ccca12ad 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h | |||
@@ -166,6 +166,10 @@ | |||
166 | /* Host D0I3 Interrupt Status */ | 166 | /* Host D0I3 Interrupt Status */ |
167 | #define H_D0I3C_IS 0x00000040 | 167 | #define H_D0I3C_IS 0x00000040 |
168 | 168 | ||
169 | /* H_CSR masks */ | ||
170 | #define H_CSR_IE_MASK (H_IE | H_D0I3C_IE) | ||
171 | #define H_CSR_IS_MASK (H_IS | H_D0I3C_IS) | ||
172 | |||
169 | /* register bits of ME_CSR_HA (ME Control Status Host Access register) */ | 173 | /* register bits of ME_CSR_HA (ME Control Status Host Access register) */ |
170 | /* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only | 174 | /* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only |
171 | access to ME_CBD */ | 175 | access to ME_CBD */ |
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 17d6894b0fd2..910af88b3214 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c | |||
@@ -134,7 +134,7 @@ static inline void mei_hcsr_write(struct mei_device *dev, u32 reg) | |||
134 | */ | 134 | */ |
135 | static inline void mei_hcsr_set(struct mei_device *dev, u32 reg) | 135 | static inline void mei_hcsr_set(struct mei_device *dev, u32 reg) |
136 | { | 136 | { |
137 | reg &= ~H_IS; | 137 | reg &= ~H_CSR_IS_MASK; |
138 | mei_hcsr_write(dev, reg); | 138 | mei_hcsr_write(dev, reg); |
139 | } | 139 | } |
140 | 140 | ||
@@ -216,7 +216,7 @@ static void mei_me_intr_clear(struct mei_device *dev) | |||
216 | { | 216 | { |
217 | u32 hcsr = mei_hcsr_read(dev); | 217 | u32 hcsr = mei_hcsr_read(dev); |
218 | 218 | ||
219 | if ((hcsr & H_IS) == H_IS) | 219 | if (hcsr & H_CSR_IS_MASK) |
220 | mei_hcsr_write(dev, hcsr); | 220 | mei_hcsr_write(dev, hcsr); |
221 | } | 221 | } |
222 | /** | 222 | /** |
@@ -228,7 +228,7 @@ static void mei_me_intr_enable(struct mei_device *dev) | |||
228 | { | 228 | { |
229 | u32 hcsr = mei_hcsr_read(dev); | 229 | u32 hcsr = mei_hcsr_read(dev); |
230 | 230 | ||
231 | hcsr |= H_IE; | 231 | hcsr |= H_CSR_IE_MASK; |
232 | mei_hcsr_set(dev, hcsr); | 232 | mei_hcsr_set(dev, hcsr); |
233 | } | 233 | } |
234 | 234 | ||
@@ -241,7 +241,7 @@ static void mei_me_intr_disable(struct mei_device *dev) | |||
241 | { | 241 | { |
242 | u32 hcsr = mei_hcsr_read(dev); | 242 | u32 hcsr = mei_hcsr_read(dev); |
243 | 243 | ||
244 | hcsr &= ~H_IE; | 244 | hcsr &= ~H_CSR_IE_MASK; |
245 | mei_hcsr_set(dev, hcsr); | 245 | mei_hcsr_set(dev, hcsr); |
246 | } | 246 | } |
247 | 247 | ||
@@ -285,12 +285,12 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) | |||
285 | hcsr = mei_hcsr_read(dev); | 285 | hcsr = mei_hcsr_read(dev); |
286 | } | 286 | } |
287 | 287 | ||
288 | hcsr |= H_RST | H_IG | H_IS; | 288 | hcsr |= H_RST | H_IG | H_CSR_IS_MASK; |
289 | 289 | ||
290 | if (intr_enable) | 290 | if (intr_enable) |
291 | hcsr |= H_IE; | 291 | hcsr |= H_CSR_IE_MASK; |
292 | else | 292 | else |
293 | hcsr &= ~H_IE; | 293 | hcsr &= ~H_CSR_IE_MASK; |
294 | 294 | ||
295 | dev->recvd_hw_ready = false; | 295 | dev->recvd_hw_ready = false; |
296 | mei_hcsr_write(dev, hcsr); | 296 | mei_hcsr_write(dev, hcsr); |
@@ -322,7 +322,7 @@ static void mei_me_host_set_ready(struct mei_device *dev) | |||
322 | { | 322 | { |
323 | u32 hcsr = mei_hcsr_read(dev); | 323 | u32 hcsr = mei_hcsr_read(dev); |
324 | 324 | ||
325 | hcsr |= H_IE | H_IG | H_RDY; | 325 | hcsr |= H_CSR_IE_MASK | H_IG | H_RDY; |
326 | mei_hcsr_set(dev, hcsr); | 326 | mei_hcsr_set(dev, hcsr); |
327 | } | 327 | } |
328 | 328 | ||
@@ -767,16 +767,20 @@ static void mei_me_pg_intr(struct mei_device *dev) | |||
767 | * | 767 | * |
768 | * Return: irqreturn_t | 768 | * Return: irqreturn_t |
769 | */ | 769 | */ |
770 | |||
771 | irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) | 770 | irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) |
772 | { | 771 | { |
773 | struct mei_device *dev = (struct mei_device *) dev_id; | 772 | struct mei_device *dev = (struct mei_device *)dev_id; |
774 | u32 hcsr = mei_hcsr_read(dev); | 773 | struct mei_me_hw *hw = to_me_hw(dev); |
774 | u32 hcsr; | ||
775 | 775 | ||
776 | if ((hcsr & H_IS) != H_IS) | 776 | hcsr = mei_hcsr_read(dev); |
777 | if (!(hcsr & H_CSR_IS_MASK)) | ||
777 | return IRQ_NONE; | 778 | return IRQ_NONE; |
778 | 779 | ||
779 | /* clear H_IS bit in H_CSR */ | 780 | hw->intr_source = hcsr & H_CSR_IS_MASK; |
781 | dev_dbg(dev->dev, "interrupt source 0x%08X.\n", hw->intr_source); | ||
782 | |||
783 | /* clear H_IS and H_D0I3C_IS bits in H_CSR to clear the interrupts */ | ||
780 | mei_hcsr_write(dev, hcsr); | 784 | mei_hcsr_write(dev, hcsr); |
781 | 785 | ||
782 | return IRQ_WAKE_THREAD; | 786 | return IRQ_WAKE_THREAD; |
@@ -804,11 +808,6 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) | |||
804 | mutex_lock(&dev->device_lock); | 808 | mutex_lock(&dev->device_lock); |
805 | mei_io_list_init(&complete_list); | 809 | mei_io_list_init(&complete_list); |
806 | 810 | ||
807 | /* Ack the interrupt here | ||
808 | * In case of MSI we don't go through the quick handler */ | ||
809 | if (pci_dev_msi_enabled(to_pci_dev(dev->dev))) | ||
810 | mei_clear_interrupts(dev); | ||
811 | |||
812 | /* check if ME wants a reset */ | 811 | /* check if ME wants a reset */ |
813 | if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) { | 812 | if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) { |
814 | dev_warn(dev->dev, "FW not ready: resetting.\n"); | 813 | dev_warn(dev->dev, "FW not ready: resetting.\n"); |
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index cf64847a35b9..2ee14dc1b2ea 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h | |||
@@ -51,12 +51,14 @@ struct mei_cfg { | |||
51 | * | 51 | * |
52 | * @cfg: per device generation config and ops | 52 | * @cfg: per device generation config and ops |
53 | * @mem_addr: io memory address | 53 | * @mem_addr: io memory address |
54 | * @intr_source: interrupt source | ||
54 | * @pg_state: power gating state | 55 | * @pg_state: power gating state |
55 | * @d0i3_supported: di03 support | 56 | * @d0i3_supported: di03 support |
56 | */ | 57 | */ |
57 | struct mei_me_hw { | 58 | struct mei_me_hw { |
58 | const struct mei_cfg *cfg; | 59 | const struct mei_cfg *cfg; |
59 | void __iomem *mem_addr; | 60 | void __iomem *mem_addr; |
61 | u32 intr_source; | ||
60 | enum mei_pg_state pg_state; | 62 | enum mei_pg_state pg_state; |
61 | bool d0i3_supported; | 63 | bool d0i3_supported; |
62 | }; | 64 | }; |
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 23f71f5ce4fb..7fee74abbc21 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c | |||
@@ -128,6 +128,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
128 | const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data); | 128 | const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data); |
129 | struct mei_device *dev; | 129 | struct mei_device *dev; |
130 | struct mei_me_hw *hw; | 130 | struct mei_me_hw *hw; |
131 | unsigned int irqflags; | ||
131 | int err; | 132 | int err; |
132 | 133 | ||
133 | 134 | ||
@@ -180,17 +181,12 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
180 | pci_enable_msi(pdev); | 181 | pci_enable_msi(pdev); |
181 | 182 | ||
182 | /* request and enable interrupt */ | 183 | /* request and enable interrupt */ |
183 | if (pci_dev_msi_enabled(pdev)) | 184 | irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED; |
184 | err = request_threaded_irq(pdev->irq, | 185 | |
185 | NULL, | 186 | err = request_threaded_irq(pdev->irq, |
186 | mei_me_irq_thread_handler, | ||
187 | IRQF_ONESHOT, KBUILD_MODNAME, dev); | ||
188 | else | ||
189 | err = request_threaded_irq(pdev->irq, | ||
190 | mei_me_irq_quick_handler, | 187 | mei_me_irq_quick_handler, |
191 | mei_me_irq_thread_handler, | 188 | mei_me_irq_thread_handler, |
192 | IRQF_SHARED, KBUILD_MODNAME, dev); | 189 | irqflags, KBUILD_MODNAME, dev); |
193 | |||
194 | if (err) { | 190 | if (err) { |
195 | dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", | 191 | dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", |
196 | pdev->irq); | 192 | pdev->irq); |
@@ -319,6 +315,7 @@ static int mei_me_pci_resume(struct device *device) | |||
319 | { | 315 | { |
320 | struct pci_dev *pdev = to_pci_dev(device); | 316 | struct pci_dev *pdev = to_pci_dev(device); |
321 | struct mei_device *dev; | 317 | struct mei_device *dev; |
318 | unsigned int irqflags; | ||
322 | int err; | 319 | int err; |
323 | 320 | ||
324 | dev = pci_get_drvdata(pdev); | 321 | dev = pci_get_drvdata(pdev); |
@@ -327,17 +324,13 @@ static int mei_me_pci_resume(struct device *device) | |||
327 | 324 | ||
328 | pci_enable_msi(pdev); | 325 | pci_enable_msi(pdev); |
329 | 326 | ||
327 | irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED; | ||
328 | |||
330 | /* request and enable interrupt */ | 329 | /* request and enable interrupt */ |
331 | if (pci_dev_msi_enabled(pdev)) | 330 | err = request_threaded_irq(pdev->irq, |
332 | err = request_threaded_irq(pdev->irq, | ||
333 | NULL, | ||
334 | mei_me_irq_thread_handler, | ||
335 | IRQF_ONESHOT, KBUILD_MODNAME, dev); | ||
336 | else | ||
337 | err = request_threaded_irq(pdev->irq, | ||
338 | mei_me_irq_quick_handler, | 331 | mei_me_irq_quick_handler, |
339 | mei_me_irq_thread_handler, | 332 | mei_me_irq_thread_handler, |
340 | IRQF_SHARED, KBUILD_MODNAME, dev); | 333 | irqflags, KBUILD_MODNAME, dev); |
341 | 334 | ||
342 | if (err) { | 335 | if (err) { |
343 | dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n", | 336 | dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n", |