summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/hw-me-regs.h4
-rw-r--r--drivers/misc/mei/hw-me.c35
-rw-r--r--drivers/misc/mei/hw-me.h2
-rw-r--r--drivers/misc/mei/pci-me.c27
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
171access to ME_CBD */ 175access 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 */
135static inline void mei_hcsr_set(struct mei_device *dev, u32 reg) 135static 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
771irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) 770irqreturn_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 */
57struct mei_me_hw { 58struct 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",