| 1 | The RDC321x MFD southbridge driver will pass a reference to the southbridge |
| 2 | PCI device which should be used by the watchdog driver for its operations. |
| 3 | This patch converts the watchdog driver to use the pci_dev pointer and make use |
| 4 | of the base register resource which is passed along with the platform device. |
| 5 | |
| 6 | Acked-by: Wim Van Sebroeck <wim@iguana.be> |
| 7 | Signed-off-by: Florian Fainelli <florian@openwrt.org> |
| 8 | --- |
| 9 | Changes from v2: |
| 10 | - replaced rdc321x_pci_{read,write} |
| 11 | - use the pci_dev pointer passed as platform_data |
| 12 | |
| 13 | --- a/drivers/watchdog/rdc321x_wdt.c |
| 14 | +++ b/drivers/watchdog/rdc321x_wdt.c |
| 15 | @@ -1,7 +1,7 @@ |
| 16 | /* |
| 17 | * RDC321x watchdog driver |
| 18 | * |
| 19 | - * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org> |
| 20 | + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org> |
| 21 | * |
| 22 | * This driver is highly inspired from the cpu5_wdt driver |
| 23 | * |
| 24 | @@ -36,8 +36,7 @@ |
| 25 | #include <linux/watchdog.h> |
| 26 | #include <linux/io.h> |
| 27 | #include <linux/uaccess.h> |
| 28 | - |
| 29 | -#include <asm/rdc321x_defs.h> |
| 30 | +#include <linux/mfd/rdc321x.h> |
| 31 | |
| 32 | #define RDC_WDT_MASK 0x80000000 /* Mask */ |
| 33 | #define RDC_WDT_EN 0x00800000 /* Enable bit */ |
| 34 | @@ -63,6 +62,8 @@ static struct { |
| 35 | int default_ticks; |
| 36 | unsigned long inuse; |
| 37 | spinlock_t lock; |
| 38 | + struct pci_dev *sb_pdev; |
| 39 | + int base_reg; |
| 40 | } rdc321x_wdt_device; |
| 41 | |
| 42 | /* generic helper functions */ |
| 43 | @@ -70,14 +71,18 @@ static struct { |
| 44 | static void rdc321x_wdt_trigger(unsigned long unused) |
| 45 | { |
| 46 | unsigned long flags; |
| 47 | + u32 val; |
| 48 | |
| 49 | if (rdc321x_wdt_device.running) |
| 50 | ticks--; |
| 51 | |
| 52 | /* keep watchdog alive */ |
| 53 | spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); |
| 54 | - outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA), |
| 55 | - RDC3210_CFGREG_DATA); |
| 56 | + pci_read_config_dword(rdc321x_wdt_device.sb_pdev, |
| 57 | + rdc321x_wdt_device.base_reg, &val); |
| 58 | + val |= RDC_WDT_EN; |
| 59 | + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, |
| 60 | + rdc321x_wdt_device.base_reg, val); |
| 61 | spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); |
| 62 | |
| 63 | /* requeue?? */ |
| 64 | @@ -105,10 +110,13 @@ static void rdc321x_wdt_start(void) |
| 65 | |
| 66 | /* Clear the timer */ |
| 67 | spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); |
| 68 | - outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR); |
| 69 | + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, |
| 70 | + rdc321x_wdt_device.base_reg, RDC_CLS_TMR); |
| 71 | |
| 72 | /* Enable watchdog and set the timeout to 81.92 us */ |
| 73 | - outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA); |
| 74 | + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, |
| 75 | + rdc321x_wdt_device.base_reg, |
| 76 | + RDC_WDT_EN | RDC_WDT_CNT); |
| 77 | spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); |
| 78 | |
| 79 | mod_timer(&rdc321x_wdt_device.timer, |
| 80 | @@ -148,7 +156,7 @@ static long rdc321x_wdt_ioctl(struct fil |
| 81 | unsigned long arg) |
| 82 | { |
| 83 | void __user *argp = (void __user *)arg; |
| 84 | - unsigned int value; |
| 85 | + u32 value; |
| 86 | static struct watchdog_info ident = { |
| 87 | .options = WDIOF_CARDRESET, |
| 88 | .identity = "RDC321x WDT", |
| 89 | @@ -162,9 +170,10 @@ static long rdc321x_wdt_ioctl(struct fil |
| 90 | case WDIOC_GETSTATUS: |
| 91 | /* Read the value from the DATA register */ |
| 92 | spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); |
| 93 | - value = inl(RDC3210_CFGREG_DATA); |
| 94 | + pci_read_config_dword(rdc321x_wdt_device.sb_pdev, |
| 95 | + rdc321x_wdt_device.base_reg, &value); |
| 96 | spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); |
| 97 | - if (copy_to_user(argp, &value, sizeof(int))) |
| 98 | + if (copy_to_user(argp, &value, sizeof(u32))) |
| 99 | return -EFAULT; |
| 100 | break; |
| 101 | case WDIOC_GETSUPPORT: |
| 102 | @@ -219,17 +228,35 @@ static struct miscdevice rdc321x_wdt_mis |
| 103 | static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) |
| 104 | { |
| 105 | int err; |
| 106 | + struct resource *r; |
| 107 | + struct rdc321x_wdt_pdata *pdata; |
| 108 | + |
| 109 | + pdata = platform_get_drvdata(pdev); |
| 110 | + if (!pdata) { |
| 111 | + dev_err(&pdev->dev, "no platform data supplied\n"); |
| 112 | + return -ENODEV; |
| 113 | + } |
| 114 | + |
| 115 | + r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg"); |
| 116 | + if (!r) { |
| 117 | + dev_err(&pdev->dev, "failed to get wdt-reg resource\n"); |
| 118 | + return -ENODEV; |
| 119 | + } |
| 120 | + |
| 121 | + rdc321x_wdt_device.sb_pdev = pdata->sb_pdev; |
| 122 | + rdc321x_wdt_device.base_reg = r->start; |
| 123 | |
| 124 | err = misc_register(&rdc321x_wdt_misc); |
| 125 | if (err < 0) { |
| 126 | - printk(KERN_ERR PFX "watchdog misc_register failed\n"); |
| 127 | + dev_err(&pdev->dev, "misc_register failed\n"); |
| 128 | return err; |
| 129 | } |
| 130 | |
| 131 | spin_lock_init(&rdc321x_wdt_device.lock); |
| 132 | |
| 133 | /* Reset the watchdog */ |
| 134 | - outl(RDC_WDT_RST, RDC3210_CFGREG_DATA); |
| 135 | + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, |
| 136 | + rdc321x_wdt_device.base_reg, RDC_WDT_RST); |
| 137 | |
| 138 | init_completion(&rdc321x_wdt_device.stop); |
| 139 | rdc321x_wdt_device.queue = 0; |
| 140 | @@ -240,7 +267,7 @@ static int __devinit rdc321x_wdt_probe(s |
| 141 | |
| 142 | rdc321x_wdt_device.default_ticks = ticks; |
| 143 | |
| 144 | - printk(KERN_INFO PFX "watchdog init success\n"); |
| 145 | + dev_info(&pdev->dev, "watchdog init success\n"); |
| 146 | |
| 147 | return 0; |
| 148 | } |
| 149 | |