summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>2017-04-09 18:00:18 -0400
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>2017-04-28 14:51:27 -0400
commitf583a884afecb16fcb8200ebb9956ea369aff57f (patch)
tree54e733c3e4e4c653b769f3963b37e64d0d95c777 /drivers/watchdog
parent496702068597ff29092e724301f77b91864454b3 (diff)
watchdog: iTCO_wdt: cleanup set/unset no_reboot_bit functions
iTCO_wdt no_reboot_bit set/unset functions has lot of common code between them. So merging these two functions into a single update function would remove these unnecessary code duplications. This patch fixes this issue by creating a no_reboot_bit update function to handle both set/unset functions. Also checking for iTCO version every time you make no_reboot_bit set/unset call is inefficient and makes the code look complex. This can be improved by performing this check once during device probe and selecting the appropriate no_reboot_bit update function. This patch fixes this issue by splitting the update function into multiple helper functions. Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/iTCO_wdt.c83
1 files changed, 50 insertions, 33 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 3d0abc0d59b4..a62993381c52 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -106,6 +106,8 @@ struct iTCO_wdt_private {
106 struct pci_dev *pci_dev; 106 struct pci_dev *pci_dev;
107 /* whether or not the watchdog has been suspended */ 107 /* whether or not the watchdog has been suspended */
108 bool suspended; 108 bool suspended;
109 /* no reboot update function pointer */
110 int (*update_no_reboot_bit)(void *p, bool set);
109}; 111};
110 112
111/* module parameters */ 113/* module parameters */
@@ -170,48 +172,61 @@ static inline u32 no_reboot_bit(struct iTCO_wdt_private *p)
170 return enable_bit; 172 return enable_bit;
171} 173}
172 174
173static void iTCO_wdt_set_NO_REBOOT_bit(struct iTCO_wdt_private *p) 175static int update_no_reboot_bit_def(void *priv, bool set)
174{ 176{
175 u32 val32; 177 return 0;
176
177 /* Set the NO_REBOOT bit: this disables reboots */
178 if (p->iTCO_version >= 2) {
179 val32 = readl(p->gcs_pmc);
180 val32 |= no_reboot_bit(p);
181 writel(val32, p->gcs_pmc);
182 } else if (p->iTCO_version == 1) {
183 pci_read_config_dword(p->pci_dev, 0xd4, &val32);
184 val32 |= no_reboot_bit(p);
185 pci_write_config_dword(p->pci_dev, 0xd4, val32);
186 }
187} 178}
188 179
189static int iTCO_wdt_unset_NO_REBOOT_bit(struct iTCO_wdt_private *p) 180static int update_no_reboot_bit_pci(void *priv, bool set)
190{ 181{
191 u32 enable_bit = no_reboot_bit(p); 182 struct iTCO_wdt_private *p = priv;
192 u32 val32 = 0; 183 u32 val32 = 0, newval32 = 0;
193 184
194 /* Unset the NO_REBOOT bit: this enables reboots */ 185 pci_read_config_dword(p->pci_dev, 0xd4, &val32);
195 if (p->iTCO_version >= 2) { 186 if (set)
196 val32 = readl(p->gcs_pmc); 187 val32 |= no_reboot_bit(p);
197 val32 &= ~enable_bit; 188 else
198 writel(val32, p->gcs_pmc); 189 val32 &= ~no_reboot_bit(p);
190 pci_write_config_dword(p->pci_dev, 0xd4, val32);
191 pci_read_config_dword(p->pci_dev, 0xd4, &newval32);
199 192
200 val32 = readl(p->gcs_pmc); 193 /* make sure the update is successful */
201 } else if (p->iTCO_version == 1) { 194 if (val32 != newval32)
202 pci_read_config_dword(p->pci_dev, 0xd4, &val32); 195 return -EIO;
203 val32 &= ~enable_bit;
204 pci_write_config_dword(p->pci_dev, 0xd4, val32);
205 196
206 pci_read_config_dword(p->pci_dev, 0xd4, &val32); 197 return 0;
207 } 198}
199
200static int update_no_reboot_bit_mem(void *priv, bool set)
201{
202 struct iTCO_wdt_private *p = priv;
203 u32 val32 = 0, newval32 = 0;
204
205 val32 = readl(p->gcs_pmc);
206 if (set)
207 val32 |= no_reboot_bit(p);
208 else
209 val32 &= ~no_reboot_bit(p);
210 writel(val32, p->gcs_pmc);
211 newval32 = readl(p->gcs_pmc);
208 212
209 if (val32 & enable_bit) 213 /* make sure the update is successful */
214 if (val32 != newval32)
210 return -EIO; 215 return -EIO;
211 216
212 return 0; 217 return 0;
213} 218}
214 219
220static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p)
221{
222 if (p->iTCO_version >= 2)
223 p->update_no_reboot_bit = update_no_reboot_bit_mem;
224 else if (p->iTCO_version == 1)
225 p->update_no_reboot_bit = update_no_reboot_bit_pci;
226 else
227 p->update_no_reboot_bit = update_no_reboot_bit_def;
228}
229
215static int iTCO_wdt_start(struct watchdog_device *wd_dev) 230static int iTCO_wdt_start(struct watchdog_device *wd_dev)
216{ 231{
217 struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); 232 struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev);
@@ -222,7 +237,7 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev)
222 iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout); 237 iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout);
223 238
224 /* disable chipset's NO_REBOOT bit */ 239 /* disable chipset's NO_REBOOT bit */
225 if (iTCO_wdt_unset_NO_REBOOT_bit(p)) { 240 if (p->update_no_reboot_bit(p, false)) {
226 spin_unlock(&p->io_lock); 241 spin_unlock(&p->io_lock);
227 pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); 242 pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n");
228 return -EIO; 243 return -EIO;
@@ -263,7 +278,7 @@ static int iTCO_wdt_stop(struct watchdog_device *wd_dev)
263 val = inw(TCO1_CNT(p)); 278 val = inw(TCO1_CNT(p));
264 279
265 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 280 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
266 iTCO_wdt_set_NO_REBOOT_bit(p); 281 p->update_no_reboot_bit(p, true);
267 282
268 spin_unlock(&p->io_lock); 283 spin_unlock(&p->io_lock);
269 284
@@ -428,6 +443,8 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
428 p->iTCO_version = pdata->version; 443 p->iTCO_version = pdata->version;
429 p->pci_dev = to_pci_dev(dev->parent); 444 p->pci_dev = to_pci_dev(dev->parent);
430 445
446 iTCO_wdt_no_reboot_bit_setup(p);
447
431 /* 448 /*
432 * Get the Memory-Mapped GCS or PMC register, we need it for the 449 * Get the Memory-Mapped GCS or PMC register, we need it for the
433 * NO_REBOOT flag (TCO v2 and v3). 450 * NO_REBOOT flag (TCO v2 and v3).
@@ -442,14 +459,14 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
442 } 459 }
443 460
444 /* Check chipset's NO_REBOOT bit */ 461 /* Check chipset's NO_REBOOT bit */
445 if (iTCO_wdt_unset_NO_REBOOT_bit(p) && 462 if (p->update_no_reboot_bit(p, false) &&
446 iTCO_vendor_check_noreboot_on()) { 463 iTCO_vendor_check_noreboot_on()) {
447 pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); 464 pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
448 return -ENODEV; /* Cannot reset NO_REBOOT bit */ 465 return -ENODEV; /* Cannot reset NO_REBOOT bit */
449 } 466 }
450 467
451 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 468 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
452 iTCO_wdt_set_NO_REBOOT_bit(p); 469 p->update_no_reboot_bit(p, true);
453 470
454 /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ 471 /* The TCO logic uses the TCO_EN bit in the SMI_EN register */
455 if (!devm_request_region(dev, p->smi_res->start, 472 if (!devm_request_region(dev, p->smi_res->start,