Skip to content

Commit 6687aeb

Browse files
Kuppuswamy Sathyanarayananandy-shev
authored andcommitted
platform/x86: intel_pmc_ipc: Use spin_lock to protect GCR updates
Currently, update_no_reboot_bit() function implemented in this driver uses mutex_lock() to protect its register updates. But this function is called with in atomic context in iTCO_wdt_start() and iTCO_wdt_stop() functions in iTCO_wdt.c driver, which in turn causes "sleeping into atomic context" issue. This patch fixes this issue by replacing the mutex_lock() with spin_lock() to protect the GCR read/write/update APIs. Fixes: 9d855d4 ("platform/x86: intel_pmc_ipc: Fix iTCO_wdt GCS memory mapping failure") Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]>
1 parent 83beee5 commit 6687aeb

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

drivers/platform/x86/intel_pmc_ipc.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <linux/suspend.h>
3434
#include <linux/acpi.h>
3535
#include <linux/io-64-nonatomic-lo-hi.h>
36+
#include <linux/spinlock.h>
3637

3738
#include <asm/intel_pmc_ipc.h>
3839

@@ -131,6 +132,7 @@ static struct intel_pmc_ipc_dev {
131132
/* gcr */
132133
void __iomem *gcr_mem_base;
133134
bool has_gcr_regs;
135+
spinlock_t gcr_lock;
134136

135137
/* punit */
136138
struct platform_device *punit_dev;
@@ -225,17 +227,17 @@ int intel_pmc_gcr_read(u32 offset, u32 *data)
225227
{
226228
int ret;
227229

228-
mutex_lock(&ipclock);
230+
spin_lock(&ipcdev.gcr_lock);
229231

230232
ret = is_gcr_valid(offset);
231233
if (ret < 0) {
232-
mutex_unlock(&ipclock);
234+
spin_unlock(&ipcdev.gcr_lock);
233235
return ret;
234236
}
235237

236238
*data = readl(ipcdev.gcr_mem_base + offset);
237239

238-
mutex_unlock(&ipclock);
240+
spin_unlock(&ipcdev.gcr_lock);
239241

240242
return 0;
241243
}
@@ -255,17 +257,17 @@ int intel_pmc_gcr_write(u32 offset, u32 data)
255257
{
256258
int ret;
257259

258-
mutex_lock(&ipclock);
260+
spin_lock(&ipcdev.gcr_lock);
259261

260262
ret = is_gcr_valid(offset);
261263
if (ret < 0) {
262-
mutex_unlock(&ipclock);
264+
spin_unlock(&ipcdev.gcr_lock);
263265
return ret;
264266
}
265267

266268
writel(data, ipcdev.gcr_mem_base + offset);
267269

268-
mutex_unlock(&ipclock);
270+
spin_unlock(&ipcdev.gcr_lock);
269271

270272
return 0;
271273
}
@@ -287,7 +289,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
287289
u32 new_val;
288290
int ret = 0;
289291

290-
mutex_lock(&ipclock);
292+
spin_lock(&ipcdev.gcr_lock);
291293

292294
ret = is_gcr_valid(offset);
293295
if (ret < 0)
@@ -309,7 +311,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
309311
}
310312

311313
gcr_ipc_unlock:
312-
mutex_unlock(&ipclock);
314+
spin_unlock(&ipcdev.gcr_lock);
313315
return ret;
314316
}
315317
EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
@@ -489,6 +491,8 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
489491

490492
pmc->irq_mode = IPC_TRIGGER_MODE_IRQ;
491493

494+
spin_lock_init(&ipcdev.gcr_lock);
495+
492496
ret = pcim_enable_device(pdev);
493497
if (ret)
494498
return ret;
@@ -903,6 +907,7 @@ static int ipc_plat_probe(struct platform_device *pdev)
903907
ipcdev.dev = &pdev->dev;
904908
ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
905909
init_completion(&ipcdev.cmd_complete);
910+
spin_lock_init(&ipcdev.gcr_lock);
906911

907912
ipcdev.irq = platform_get_irq(pdev, 0);
908913
if (ipcdev.irq < 0) {

0 commit comments

Comments
 (0)