watchdog: pc87413_wdt: Cleanup pc87413 watchdog driver to use
Inspired by Nat Gurumoorthy's recent patches for cleaning up the it87 drivers to use request_muxed_region for accessing the SuperIO area on these chips, and the fact I have a GPIO driver for the pc8741x basically ready for submission, here is a patch to cleanup the pc87413 watchdog driver to use request_muxed_region for accessing the SuperIO area. It also pulls out the details about the SWC IO area on initial driver load, and properly does a request_region for that area - there's no requirement to touch the SuperIO area after doing the initial watchdog enable and IO base retrieval. While I have hardware with a pc87413 on it it is not wired in a way that allows the watchdog to reboot the machine, so I have not been able to fully test these changes - I have checked that the driver correctly initialises itself still and requests the SWC io region ok. Signed-Off-By: Jonathan McDowell <noodles@earth.li> Signed-Off-By: Wim Van Sebroeck <wim@iguana.be>
This commit is contained in:
parent
97b08a6221
commit
7ccdb9467b
|
@ -56,6 +56,7 @@
|
||||||
#define IO_DEFAULT 0x2E /* Address used on Portwell Boards */
|
#define IO_DEFAULT 0x2E /* Address used on Portwell Boards */
|
||||||
|
|
||||||
static int io = IO_DEFAULT;
|
static int io = IO_DEFAULT;
|
||||||
|
static int swc_base_addr = -1;
|
||||||
|
|
||||||
static int timeout = DEFAULT_TIMEOUT; /* timeout value */
|
static int timeout = DEFAULT_TIMEOUT; /* timeout value */
|
||||||
static unsigned long timer_enabled; /* is the timer enabled? */
|
static unsigned long timer_enabled; /* is the timer enabled? */
|
||||||
|
@ -116,9 +117,8 @@ static inline void pc87413_enable_swc(void)
|
||||||
|
|
||||||
/* Read SWC I/O base address */
|
/* Read SWC I/O base address */
|
||||||
|
|
||||||
static inline unsigned int pc87413_get_swc_base(void)
|
static void pc87413_get_swc_base_addr(void)
|
||||||
{
|
{
|
||||||
unsigned int swc_base_addr = 0;
|
|
||||||
unsigned char addr_l, addr_h = 0;
|
unsigned char addr_l, addr_h = 0;
|
||||||
|
|
||||||
/* Step 3: Read SWC I/O Base Address */
|
/* Step 3: Read SWC I/O Base Address */
|
||||||
|
@ -136,12 +136,11 @@ static inline unsigned int pc87413_get_swc_base(void)
|
||||||
"Read SWC I/O Base Address: low %d, high %d, res %d\n",
|
"Read SWC I/O Base Address: low %d, high %d, res %d\n",
|
||||||
addr_l, addr_h, swc_base_addr);
|
addr_l, addr_h, swc_base_addr);
|
||||||
#endif
|
#endif
|
||||||
return swc_base_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select Bank 3 of SWC */
|
/* Select Bank 3 of SWC */
|
||||||
|
|
||||||
static inline void pc87413_swc_bank3(unsigned int swc_base_addr)
|
static inline void pc87413_swc_bank3(void)
|
||||||
{
|
{
|
||||||
/* Step 4: Select Bank3 of SWC */
|
/* Step 4: Select Bank3 of SWC */
|
||||||
outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f);
|
outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f);
|
||||||
|
@ -152,8 +151,7 @@ static inline void pc87413_swc_bank3(unsigned int swc_base_addr)
|
||||||
|
|
||||||
/* Set watchdog timeout to x minutes */
|
/* Set watchdog timeout to x minutes */
|
||||||
|
|
||||||
static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
|
static inline void pc87413_programm_wdto(char pc87413_time)
|
||||||
char pc87413_time)
|
|
||||||
{
|
{
|
||||||
/* Step 5: Programm WDTO, Twd. */
|
/* Step 5: Programm WDTO, Twd. */
|
||||||
outb_p(pc87413_time, swc_base_addr + WDTO);
|
outb_p(pc87413_time, swc_base_addr + WDTO);
|
||||||
|
@ -164,7 +162,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
|
||||||
|
|
||||||
/* Enable WDEN */
|
/* Enable WDEN */
|
||||||
|
|
||||||
static inline void pc87413_enable_wden(unsigned int swc_base_addr)
|
static inline void pc87413_enable_wden(void)
|
||||||
{
|
{
|
||||||
/* Step 6: Enable WDEN */
|
/* Step 6: Enable WDEN */
|
||||||
outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
|
outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
|
||||||
|
@ -174,7 +172,7 @@ static inline void pc87413_enable_wden(unsigned int swc_base_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable SW_WD_TREN */
|
/* Enable SW_WD_TREN */
|
||||||
static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
|
static inline void pc87413_enable_sw_wd_tren(void)
|
||||||
{
|
{
|
||||||
/* Enable SW_WD_TREN */
|
/* Enable SW_WD_TREN */
|
||||||
outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
|
outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
|
||||||
|
@ -185,7 +183,7 @@ static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
|
||||||
|
|
||||||
/* Disable SW_WD_TREN */
|
/* Disable SW_WD_TREN */
|
||||||
|
|
||||||
static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
|
static inline void pc87413_disable_sw_wd_tren(void)
|
||||||
{
|
{
|
||||||
/* Disable SW_WD_TREN */
|
/* Disable SW_WD_TREN */
|
||||||
outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
|
outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
|
||||||
|
@ -196,7 +194,7 @@ static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
|
||||||
|
|
||||||
/* Enable SW_WD_TRG */
|
/* Enable SW_WD_TRG */
|
||||||
|
|
||||||
static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
|
static inline void pc87413_enable_sw_wd_trg(void)
|
||||||
{
|
{
|
||||||
/* Enable SW_WD_TRG */
|
/* Enable SW_WD_TRG */
|
||||||
outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
|
outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
|
||||||
|
@ -207,7 +205,7 @@ static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
|
||||||
|
|
||||||
/* Disable SW_WD_TRG */
|
/* Disable SW_WD_TRG */
|
||||||
|
|
||||||
static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr)
|
static inline void pc87413_disable_sw_wd_trg(void)
|
||||||
{
|
{
|
||||||
/* Disable SW_WD_TRG */
|
/* Disable SW_WD_TRG */
|
||||||
outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
|
outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
|
||||||
|
@ -222,18 +220,13 @@ static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr)
|
||||||
|
|
||||||
static void pc87413_enable(void)
|
static void pc87413_enable(void)
|
||||||
{
|
{
|
||||||
unsigned int swc_base_addr;
|
|
||||||
|
|
||||||
spin_lock(&io_lock);
|
spin_lock(&io_lock);
|
||||||
|
|
||||||
pc87413_select_wdt_out();
|
pc87413_swc_bank3();
|
||||||
pc87413_enable_swc();
|
pc87413_programm_wdto(timeout);
|
||||||
swc_base_addr = pc87413_get_swc_base();
|
pc87413_enable_wden();
|
||||||
pc87413_swc_bank3(swc_base_addr);
|
pc87413_enable_sw_wd_tren();
|
||||||
pc87413_programm_wdto(swc_base_addr, timeout);
|
pc87413_enable_sw_wd_trg();
|
||||||
pc87413_enable_wden(swc_base_addr);
|
|
||||||
pc87413_enable_sw_wd_tren(swc_base_addr);
|
|
||||||
pc87413_enable_sw_wd_trg(swc_base_addr);
|
|
||||||
|
|
||||||
spin_unlock(&io_lock);
|
spin_unlock(&io_lock);
|
||||||
}
|
}
|
||||||
|
@ -242,17 +235,12 @@ static void pc87413_enable(void)
|
||||||
|
|
||||||
static void pc87413_disable(void)
|
static void pc87413_disable(void)
|
||||||
{
|
{
|
||||||
unsigned int swc_base_addr;
|
|
||||||
|
|
||||||
spin_lock(&io_lock);
|
spin_lock(&io_lock);
|
||||||
|
|
||||||
pc87413_select_wdt_out();
|
pc87413_swc_bank3();
|
||||||
pc87413_enable_swc();
|
pc87413_disable_sw_wd_tren();
|
||||||
swc_base_addr = pc87413_get_swc_base();
|
pc87413_disable_sw_wd_trg();
|
||||||
pc87413_swc_bank3(swc_base_addr);
|
pc87413_programm_wdto(0);
|
||||||
pc87413_disable_sw_wd_tren(swc_base_addr);
|
|
||||||
pc87413_disable_sw_wd_trg(swc_base_addr);
|
|
||||||
pc87413_programm_wdto(swc_base_addr, 0);
|
|
||||||
|
|
||||||
spin_unlock(&io_lock);
|
spin_unlock(&io_lock);
|
||||||
}
|
}
|
||||||
|
@ -261,20 +249,15 @@ static void pc87413_disable(void)
|
||||||
|
|
||||||
static void pc87413_refresh(void)
|
static void pc87413_refresh(void)
|
||||||
{
|
{
|
||||||
unsigned int swc_base_addr;
|
|
||||||
|
|
||||||
spin_lock(&io_lock);
|
spin_lock(&io_lock);
|
||||||
|
|
||||||
pc87413_select_wdt_out();
|
pc87413_swc_bank3();
|
||||||
pc87413_enable_swc();
|
pc87413_disable_sw_wd_tren();
|
||||||
swc_base_addr = pc87413_get_swc_base();
|
pc87413_disable_sw_wd_trg();
|
||||||
pc87413_swc_bank3(swc_base_addr);
|
pc87413_programm_wdto(timeout);
|
||||||
pc87413_disable_sw_wd_tren(swc_base_addr);
|
pc87413_enable_wden();
|
||||||
pc87413_disable_sw_wd_trg(swc_base_addr);
|
pc87413_enable_sw_wd_tren();
|
||||||
pc87413_programm_wdto(swc_base_addr, timeout);
|
pc87413_enable_sw_wd_trg();
|
||||||
pc87413_enable_wden(swc_base_addr);
|
|
||||||
pc87413_enable_sw_wd_tren(swc_base_addr);
|
|
||||||
pc87413_enable_sw_wd_trg(swc_base_addr);
|
|
||||||
|
|
||||||
spin_unlock(&io_lock);
|
spin_unlock(&io_lock);
|
||||||
}
|
}
|
||||||
|
@ -528,7 +511,8 @@ static int __init pc87413_init(void)
|
||||||
printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n",
|
printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n",
|
||||||
WDT_INDEX_IO_PORT);
|
WDT_INDEX_IO_PORT);
|
||||||
|
|
||||||
/* request_region(io, 2, "pc87413"); */
|
if (!request_muxed_region(io, 2, MODNAME))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
ret = register_reboot_notifier(&pc87413_notifier);
|
ret = register_reboot_notifier(&pc87413_notifier);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -541,12 +525,32 @@ static int __init pc87413_init(void)
|
||||||
printk(KERN_ERR PFX
|
printk(KERN_ERR PFX
|
||||||
"cannot register miscdev on minor=%d (err=%d)\n",
|
"cannot register miscdev on minor=%d (err=%d)\n",
|
||||||
WATCHDOG_MINOR, ret);
|
WATCHDOG_MINOR, ret);
|
||||||
unregister_reboot_notifier(&pc87413_notifier);
|
goto reboot_unreg;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout);
|
printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout);
|
||||||
|
|
||||||
|
pc87413_select_wdt_out();
|
||||||
|
pc87413_enable_swc();
|
||||||
|
pc87413_get_swc_base_addr();
|
||||||
|
|
||||||
|
if (!request_region(swc_base_addr, 0x20, MODNAME)) {
|
||||||
|
printk(KERN_ERR PFX
|
||||||
|
"cannot request SWC region at 0x%x\n", swc_base_addr);
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto misc_unreg;
|
||||||
|
}
|
||||||
|
|
||||||
pc87413_enable();
|
pc87413_enable();
|
||||||
|
|
||||||
|
release_region(io, 2);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
misc_unreg:
|
||||||
|
misc_deregister(&pc87413_miscdev);
|
||||||
|
reboot_unreg:
|
||||||
|
unregister_reboot_notifier(&pc87413_notifier);
|
||||||
|
release_region(io, 2);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -569,7 +573,7 @@ static void __exit pc87413_exit(void)
|
||||||
|
|
||||||
misc_deregister(&pc87413_miscdev);
|
misc_deregister(&pc87413_miscdev);
|
||||||
unregister_reboot_notifier(&pc87413_notifier);
|
unregister_reboot_notifier(&pc87413_notifier);
|
||||||
/* release_region(io, 2); */
|
release_region(swc_base_addr, 0x20);
|
||||||
|
|
||||||
printk(KERN_INFO MODNAME " watchdog component driver removed.\n");
|
printk(KERN_INFO MODNAME " watchdog component driver removed.\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue