Skip to content

Commit 140c91b

Browse files
Kuppuswamy Sathyanarayananandy-shev
authored andcommitted
watchdog: iTCO_wdt: Add PMC specific noreboot update api
In some SoCs, setting noreboot bit needs modification to PMC GC registers. But not all PMC drivers allow other drivers to memory map their GC region. This could create mem request conflict in watchdog driver. So this patch adds facility to allow PMC drivers to pass noreboot update function to watchdog drivers via platform data. Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Acked-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
1 parent f583a88 commit 140c91b

2 files changed

Lines changed: 22 additions & 7 deletions

File tree

drivers/watchdog/iTCO_wdt.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ struct iTCO_wdt_private {
106106
struct pci_dev *pci_dev;
107107
/* whether or not the watchdog has been suspended */
108108
bool suspended;
109+
/* no reboot API private data */
110+
void *no_reboot_priv;
109111
/* no reboot update function pointer */
110112
int (*update_no_reboot_bit)(void *p, bool set);
111113
};
@@ -217,14 +219,23 @@ static int update_no_reboot_bit_mem(void *priv, bool set)
217219
return 0;
218220
}
219221

220-
static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p)
222+
static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
223+
struct itco_wdt_platform_data *pdata)
221224
{
225+
if (pdata->update_no_reboot_bit) {
226+
p->update_no_reboot_bit = pdata->update_no_reboot_bit;
227+
p->no_reboot_priv = pdata->no_reboot_priv;
228+
return;
229+
}
230+
222231
if (p->iTCO_version >= 2)
223232
p->update_no_reboot_bit = update_no_reboot_bit_mem;
224233
else if (p->iTCO_version == 1)
225234
p->update_no_reboot_bit = update_no_reboot_bit_pci;
226235
else
227236
p->update_no_reboot_bit = update_no_reboot_bit_def;
237+
238+
p->no_reboot_priv = p;
228239
}
229240

230241
static int iTCO_wdt_start(struct watchdog_device *wd_dev)
@@ -237,7 +248,7 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev)
237248
iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout);
238249

239250
/* disable chipset's NO_REBOOT bit */
240-
if (p->update_no_reboot_bit(p, false)) {
251+
if (p->update_no_reboot_bit(p->no_reboot_priv, false)) {
241252
spin_unlock(&p->io_lock);
242253
pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n");
243254
return -EIO;
@@ -278,7 +289,7 @@ static int iTCO_wdt_stop(struct watchdog_device *wd_dev)
278289
val = inw(TCO1_CNT(p));
279290

280291
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
281-
p->update_no_reboot_bit(p, true);
292+
p->update_no_reboot_bit(p->no_reboot_priv, true);
282293

283294
spin_unlock(&p->io_lock);
284295

@@ -443,13 +454,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
443454
p->iTCO_version = pdata->version;
444455
p->pci_dev = to_pci_dev(dev->parent);
445456

446-
iTCO_wdt_no_reboot_bit_setup(p);
457+
iTCO_wdt_no_reboot_bit_setup(p, pdata);
447458

448459
/*
449460
* Get the Memory-Mapped GCS or PMC register, we need it for the
450461
* NO_REBOOT flag (TCO v2 and v3).
451462
*/
452-
if (p->iTCO_version >= 2) {
463+
if (p->iTCO_version >= 2 && !pdata->update_no_reboot_bit) {
453464
p->gcs_pmc_res = platform_get_resource(pdev,
454465
IORESOURCE_MEM,
455466
ICH_RES_MEM_GCS_PMC);
@@ -459,14 +470,14 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
459470
}
460471

461472
/* Check chipset's NO_REBOOT bit */
462-
if (p->update_no_reboot_bit(p, false) &&
473+
if (p->update_no_reboot_bit(p->no_reboot_priv, false) &&
463474
iTCO_vendor_check_noreboot_on()) {
464475
pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
465476
return -ENODEV; /* Cannot reset NO_REBOOT bit */
466477
}
467478

468479
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
469-
p->update_no_reboot_bit(p, true);
480+
p->update_no_reboot_bit(p->no_reboot_priv, true);
470481

471482
/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
472483
if (!devm_request_region(dev, p->smi_res->start,

include/linux/platform_data/itco_wdt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
struct itco_wdt_platform_data {
1515
char name[32];
1616
unsigned int version;
17+
/* private data to be passed to update_no_reboot_bit API */
18+
void *no_reboot_priv;
19+
/* pointer for platform specific no reboot update function */
20+
int (*update_no_reboot_bit)(void *priv, bool set);
1721
};
1822

1923
#endif /* _ITCO_WDT_H_ */

0 commit comments

Comments
 (0)