aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2007-10-12 21:27:47 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2007-10-12 21:27:47 -0400
commitb981d8b3f5e008ff10d993be633ad00564fc22cd (patch)
treee292dc07b22308912cf6a58354a608b9e5e8e1fd /drivers/char
parentb11d2127c4893a7315d1e16273bc8560049fa3ca (diff)
parent2b9e0aae1d50e880c58d46788e5e3ebd89d75d62 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/macintosh/adbhid.c
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig70
-rw-r--r--drivers/char/Makefile10
-rw-r--r--drivers/char/agp/Kconfig2
-rw-r--r--drivers/char/agp/agp.h3
-rw-r--r--drivers/char/agp/amd-k7-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c12
-rw-r--r--drivers/char/agp/compat_ioctl.c1
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/frontend.c1
-rw-r--r--drivers/char/agp/generic.c2
-rw-r--r--drivers/char/agp/hp-agp.c1
-rw-r--r--drivers/char/agp/i460-agp.c4
-rw-r--r--drivers/char/agp/intel-agp.c40
-rw-r--r--drivers/char/agp/nvidia-agp.c3
-rw-r--r--drivers/char/agp/sgi-agp.c1
-rw-r--r--drivers/char/agp/via-agp.c5
-rw-r--r--drivers/char/amiserial.c3
-rw-r--r--drivers/char/decserial.c67
-rw-r--r--drivers/char/drm/drm_bufs.c13
-rw-r--r--drivers/char/drm/i915_dma.c14
-rw-r--r--drivers/char/drm/i915_drv.h7
-rw-r--r--drivers/char/drm/i915_irq.c12
-rw-r--r--drivers/char/drm/via_dmablit.c5
-rw-r--r--drivers/char/dsp56k.c4
-rw-r--r--drivers/char/esp.c6
-rw-r--r--drivers/char/hpet.c90
-rw-r--r--drivers/char/hvc_beat.c4
-rw-r--r--drivers/char/hvc_iseries.c8
-rw-r--r--drivers/char/hvc_lguest.c177
-rw-r--r--drivers/char/hvc_rtas.c2
-rw-r--r--drivers/char/hvc_xen.c159
-rw-r--r--drivers/char/hvcs.c12
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/char/i8k.c4
-rw-r--r--drivers/char/ip2/ip2main.c19
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c6
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c3
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c21
-rw-r--r--drivers/char/istallion.c8
-rw-r--r--drivers/char/keyboard.c4
-rw-r--r--drivers/char/lcd.c1
-rw-r--r--drivers/char/lp.c5
-rw-r--r--drivers/char/mbcs.c27
-rw-r--r--drivers/char/mbcs.h10
-rw-r--r--drivers/char/mmtimer.c1
-rw-r--r--drivers/char/mspec.c66
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c10
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c7
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/ps3flash.c440
-rw-r--r--drivers/char/pty.c9
-rw-r--r--drivers/char/random.c19
-rw-r--r--drivers/char/raw.c5
-rw-r--r--drivers/char/rio/rio_linux.c4
-rw-r--r--drivers/char/rio/riocmd.c4
-rw-r--r--drivers/char/rio/riotable.c3
-rw-r--r--drivers/char/rocket.c3
-rw-r--r--drivers/char/rtc.c32
-rw-r--r--drivers/char/serial167.c6
-rw-r--r--drivers/char/snsc.c3
-rw-r--r--drivers/char/sonypi.c9
-rw-r--r--drivers/char/stallion.c12
-rw-r--r--drivers/char/synclink.c3
-rw-r--r--drivers/char/synclink_gt.c82
-rw-r--r--drivers/char/synclinkmp.c3
-rw-r--r--drivers/char/tipar.c6
-rw-r--r--drivers/char/tpm/tpm.c2
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm_atmel.c2
-rw-r--r--drivers/char/tpm/tpm_atmel.h2
-rw-r--r--drivers/char/tpm/tpm_bios.c24
-rw-r--r--drivers/char/tpm/tpm_nsc.c2
-rw-r--r--drivers/char/tpm/tpm_tis.c2
-rw-r--r--drivers/char/tty_io.c62
-rw-r--r--drivers/char/tty_ioctl.c14
-rw-r--r--drivers/char/viotape.c142
-rw-r--r--drivers/char/vme_scc.c8
-rw-r--r--drivers/char/vt_ioctl.c19
-rw-r--r--drivers/char/watchdog/Kconfig133
-rw-r--r--drivers/char/watchdog/Makefile44
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c7
-rw-r--r--drivers/char/watchdog/bfin_wdt.c490
-rw-r--r--drivers/char/watchdog/booke_wdt.c2
-rw-r--r--drivers/char/watchdog/cpu5wdt.c4
-rw-r--r--drivers/char/watchdog/davinci_wdt.c281
-rw-r--r--drivers/char/watchdog/eurotechwdt.c13
-rw-r--r--drivers/char/watchdog/iTCO_wdt.c38
-rw-r--r--drivers/char/watchdog/iop_wdt.c262
-rw-r--r--drivers/char/watchdog/machzwd.c1
-rw-r--r--drivers/char/watchdog/mixcomwd.c5
-rw-r--r--drivers/char/watchdog/mpc5200_wdt.c286
-rw-r--r--drivers/char/watchdog/mpc83xx_wdt.c3
-rw-r--r--drivers/char/watchdog/mpc8xx_wdt.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c3
-rw-r--r--drivers/char/watchdog/mtx-1_wdt.c1
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c218
-rw-r--r--drivers/char/watchdog/omap_wdt.c4
-rw-r--r--drivers/char/watchdog/pcwd_usb.c3
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c6
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c3
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c4
-rw-r--r--drivers/char/watchdog/sc1200wdt.c4
-rw-r--r--drivers/char/watchdog/sc520_wdt.c4
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c24
104 files changed, 2997 insertions, 711 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d8d7125529c4..b391776e5bf3 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -130,6 +130,7 @@ config ROCKETPORT
130config CYCLADES 130config CYCLADES
131 tristate "Cyclades async mux support" 131 tristate "Cyclades async mux support"
132 depends on SERIAL_NONSTANDARD && (PCI || ISA) 132 depends on SERIAL_NONSTANDARD && (PCI || ISA)
133 select FW_LOADER
133 ---help--- 134 ---help---
134 This driver supports Cyclades Z and Y multiserial boards. 135 This driver supports Cyclades Z and Y multiserial boards.
135 You would need something like this to connect more than two modems to 136 You would need something like this to connect more than two modems to
@@ -185,7 +186,7 @@ config ESPSERIAL
185 186
186config MOXA_INTELLIO 187config MOXA_INTELLIO
187 tristate "Moxa Intellio support" 188 tristate "Moxa Intellio support"
188 depends on SERIAL_NONSTANDARD 189 depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
189 help 190 help
190 Say Y here if you have a Moxa Intellio multiport serial card. 191 Say Y here if you have a Moxa Intellio multiport serial card.
191 192
@@ -241,7 +242,7 @@ config SYNCLINK
241 242
242config SYNCLINKMP 243config SYNCLINKMP
243 tristate "SyncLink Multiport support" 244 tristate "SyncLink Multiport support"
244 depends on SERIAL_NONSTANDARD 245 depends on SERIAL_NONSTANDARD && PCI
245 help 246 help
246 Enable support for the SyncLink Multiport (2 or 4 ports) 247 Enable support for the SyncLink Multiport (2 or 4 ports)
247 serial adapter, running asynchronous and HDLC communications up 248 serial adapter, running asynchronous and HDLC communications up
@@ -372,39 +373,6 @@ config ISTALLION
372 To compile this driver as a module, choose M here: the 373 To compile this driver as a module, choose M here: the
373 module will be called istallion. 374 module will be called istallion.
374 375
375config SERIAL_DEC
376 bool "DECstation serial support"
377 depends on MACH_DECSTATION
378 default y
379 help
380 This selects whether you want to be asked about drivers for
381 DECstation serial ports.
382
383 Note that the answer to this question won't directly affect the
384 kernel: saying N will just cause the configurator to skip all
385 the questions about DECstation serial ports.
386
387config SERIAL_DEC_CONSOLE
388 bool "Support for console on a DECstation serial port"
389 depends on SERIAL_DEC
390 default y
391 help
392 If you say Y here, it will be possible to use a serial port as the
393 system console (the system console is the device which receives all
394 kernel messages and warnings and which allows logins in single user
395 mode). Note that the firmware uses ttyS0 as the serial console on
396 the Maxine and ttyS2 on the others.
397
398 If unsure, say Y.
399
400config ZS
401 bool "Z85C30 Serial Support"
402 depends on SERIAL_DEC
403 default y
404 help
405 Documentation on the Zilog 85C350 serial communications controller
406 is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>
407
408config A2232 376config A2232
409 tristate "Commodore A2232 serial support (EXPERIMENTAL)" 377 tristate "Commodore A2232 serial support (EXPERIMENTAL)"
410 depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP 378 depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
@@ -637,6 +605,14 @@ config HVC_BEAT
637 help 605 help
638 Toshiba's Cell Reference Set Beat Console device driver 606 Toshiba's Cell Reference Set Beat Console device driver
639 607
608config HVC_XEN
609 bool "Xen Hypervisor Console support"
610 depends on XEN
611 select HVC_DRIVER
612 default y
613 help
614 Xen virtual console device driver
615
640config HVCS 616config HVCS
641 tristate "IBM Hypervisor Virtual Console Server support" 617 tristate "IBM Hypervisor Virtual Console Server support"
642 depends on PPC_PSERIES 618 depends on PPC_PSERIES
@@ -751,7 +727,7 @@ config NVRAM
751 727
752config RTC 728config RTC
753 tristate "Enhanced Real Time Clock Support" 729 tristate "Enhanced Real Time Clock Support"
754 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH && !S390 730 depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390
755 ---help--- 731 ---help---
756 If you say Y here and create a character special file /dev/rtc with 732 If you say Y here and create a character special file /dev/rtc with
757 major number 10 and minor number 135 using mknod ("man mknod"), you 733 major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -775,6 +751,28 @@ config RTC
775 To compile this driver as a module, choose M here: the 751 To compile this driver as a module, choose M here: the
776 module will be called rtc. 752 module will be called rtc.
777 753
754config JS_RTC
755 tristate "Enhanced Real Time Clock Support"
756 depends on SPARC32 && PCI
757 ---help---
758 If you say Y here and create a character special file /dev/rtc with
759 major number 10 and minor number 135 using mknod ("man mknod"), you
760 will get access to the real time clock (or hardware clock) built
761 into your computer.
762
763 Every PC has such a clock built in. It can be used to generate
764 signals from as low as 1Hz up to 8192Hz, and can also be used
765 as a 24 hour alarm. It reports status information via the file
766 /proc/driver/rtc and its behaviour is set by various ioctls on
767 /dev/rtc.
768
769 If you think you have a use for such a device (such as periodic data
770 sampling), then say Y here, and read <file:Documentation/rtc.txt>
771 for details.
772
773 To compile this driver as a module, choose M here: the
774 module will be called js-rtc.
775
778config SGI_DS1286 776config SGI_DS1286
779 tristate "SGI DS1286 RTC support" 777 tristate "SGI DS1286 RTC support"
780 depends on SGI_IP22 778 depends on SGI_IP22
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index f2996a95eb07..c78ff26647ee 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -42,12 +42,14 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
42obj-$(CONFIG_N_HDLC) += n_hdlc.o 42obj-$(CONFIG_N_HDLC) += n_hdlc.o
43obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 43obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
44obj-$(CONFIG_SX) += sx.o generic_serial.o 44obj-$(CONFIG_SX) += sx.o generic_serial.o
45obj-$(CONFIG_LGUEST_GUEST) += hvc_lguest.o
45obj-$(CONFIG_RIO) += rio/ generic_serial.o 46obj-$(CONFIG_RIO) += rio/ generic_serial.o
46obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o 47obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
47obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o 48obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
48obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 49obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
49obj-$(CONFIG_HVC_BEAT) += hvc_beat.o 50obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
50obj-$(CONFIG_HVC_DRIVER) += hvc_console.o 51obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
52obj-$(CONFIG_HVC_XEN) += hvc_xen.o
51obj-$(CONFIG_RAW_DRIVER) += raw.o 53obj-$(CONFIG_RAW_DRIVER) += raw.o
52obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 54obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
53obj-$(CONFIG_MSPEC) += mspec.o 55obj-$(CONFIG_MSPEC) += mspec.o
@@ -95,7 +97,6 @@ obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
95obj-$(CONFIG_GPIO_TB0219) += tb0219.o 97obj-$(CONFIG_GPIO_TB0219) += tb0219.o
96obj-$(CONFIG_TELCLOCK) += tlclk.o 98obj-$(CONFIG_TELCLOCK) += tlclk.o
97 99
98obj-$(CONFIG_WATCHDOG) += watchdog/
99obj-$(CONFIG_MWAVE) += mwave/ 100obj-$(CONFIG_MWAVE) += mwave/
100obj-$(CONFIG_AGP) += agp/ 101obj-$(CONFIG_AGP) += agp/
101obj-$(CONFIG_DRM) += drm/ 102obj-$(CONFIG_DRM) += drm/
@@ -105,6 +106,11 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/
105obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o 106obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
106obj-$(CONFIG_TCG_TPM) += tpm/ 107obj-$(CONFIG_TCG_TPM) += tpm/
107 108
109obj-$(CONFIG_PS3_FLASH) += ps3flash.o
110
111obj-$(CONFIG_JS_RTC) += js-rtc.o
112js-rtc-y = rtc.o
113
108# Files generated that shall be removed upon make clean 114# Files generated that shall be removed upon make clean
109clean-files := consolemap_deftbl.c defkeymap.c 115clean-files := consolemap_deftbl.c defkeymap.c
110 116
@@ -123,7 +129,7 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c
123 129
124ifdef GENERATE_KEYMAP 130ifdef GENERATE_KEYMAP
125 131
126$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map 132$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
127 loadkeys --mktable $< > $@.tmp 133 loadkeys --mktable $< > $@.tmp
128 sed -e 's/^static *//' $@.tmp > $@ 134 sed -e 's/^static *//' $@.tmp > $@
129 rm $@.tmp 135 rm $@.tmp
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index a9f9c48c2424..713533d8a86e 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -50,7 +50,7 @@ config AGP_ATI
50 50
51config AGP_AMD 51config AGP_AMD
52 tristate "AMD Irongate, 761, and 762 chipset support" 52 tristate "AMD Irongate, 761, and 762 chipset support"
53 depends on AGP && X86_32 53 depends on AGP && (X86_32 || ALPHA)
54 help 54 help
55 This option gives you AGP support for the GLX component of 55 This option gives you AGP support for the GLX component of
56 X on AMD Irongate, 761, and 762 chipsets. 56 X on AMD Irongate, 761, and 762 chipsets.
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 35ab1a9f8e8b..8955e7ff759a 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -176,7 +176,7 @@ struct agp_bridge_data {
176#define I830_GMCH_MEM_MASK 0x1 176#define I830_GMCH_MEM_MASK 0x1
177#define I830_GMCH_MEM_64M 0x1 177#define I830_GMCH_MEM_64M 0x1
178#define I830_GMCH_MEM_128M 0 178#define I830_GMCH_MEM_128M 0
179#define I830_GMCH_GMS_MASK 0xF0 179#define I830_GMCH_GMS_MASK 0x70
180#define I830_GMCH_GMS_DISABLED 0x00 180#define I830_GMCH_GMS_DISABLED 0x00
181#define I830_GMCH_GMS_LOCAL 0x10 181#define I830_GMCH_GMS_LOCAL 0x10
182#define I830_GMCH_GMS_STOLEN_512 0x20 182#define I830_GMCH_GMS_STOLEN_512 0x20
@@ -190,6 +190,7 @@ struct agp_bridge_data {
190#define INTEL_I830_ERRSTS 0x92 190#define INTEL_I830_ERRSTS 0x92
191 191
192/* Intel 855GM/852GM registers */ 192/* Intel 855GM/852GM registers */
193#define I855_GMCH_GMS_MASK 0xF0
193#define I855_GMCH_GMS_STOLEN_0M 0x0 194#define I855_GMCH_GMS_STOLEN_0M 0x0
194#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) 195#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
195#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) 196#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index df0ddf14b85c..f60bca70d1fb 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -223,6 +223,8 @@ static int amd_irongate_configure(void)
223 pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); 223 pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
224 temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); 224 temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
225 amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); 225 amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
226 if (!amd_irongate_private.registers)
227 return -ENOMEM;
226 228
227 /* Write out the address of the gatt table */ 229 /* Write out the address of the gatt table */
228 writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); 230 writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 780e59e588ad..2d46b713c8f2 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -123,21 +123,16 @@ static int ati_create_gatt_pages(int nr_tables)
123 123
124 for (i = 0; i < nr_tables; i++) { 124 for (i = 0; i < nr_tables; i++) {
125 entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); 125 entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL);
126 tables[i] = entry;
126 if (entry == NULL) { 127 if (entry == NULL) {
127 while (i > 0) {
128 kfree(tables[i-1]);
129 i--;
130 }
131 kfree(tables);
132 retval = -ENOMEM; 128 retval = -ENOMEM;
133 break; 129 break;
134 } 130 }
135 tables[i] = entry;
136 retval = ati_create_page_map(entry); 131 retval = ati_create_page_map(entry);
137 if (retval != 0) 132 if (retval != 0)
138 break; 133 break;
139 } 134 }
140 ati_generic_private.num_tables = nr_tables; 135 ati_generic_private.num_tables = i;
141 ati_generic_private.gatt_pages = tables; 136 ati_generic_private.gatt_pages = tables;
142 137
143 if (retval != 0) 138 if (retval != 0)
@@ -218,6 +213,9 @@ static int ati_configure(void)
218 temp = (temp & 0xfffff000); 213 temp = (temp & 0xfffff000);
219 ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); 214 ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
220 215
216 if (!ati_generic_private.registers)
217 return -ENOMEM;
218
221 if (is_r200()) 219 if (is_r200())
222 pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); 220 pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000);
223 else 221 else
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
index fcb4b1bf0d4e..ecd4248861b9 100644
--- a/drivers/char/agp/compat_ioctl.c
+++ b/drivers/char/agp/compat_ioctl.c
@@ -28,6 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/fs.h>
31#include <linux/agpgart.h> 32#include <linux/agpgart.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include "agp.h" 34#include "agp.h"
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index df8da7262853..d78cd09186aa 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
375 if (!r->start && r->end) { 375 if (!r->start && r->end) {
376 if (pci_assign_resource(pdev, 0)) { 376 if (pci_assign_resource(pdev, 0)) {
377 printk(KERN_ERR PFX "could not assign resource 0\n"); 377 printk(KERN_ERR PFX "could not assign resource 0\n");
378 agp_put_bridge(bridge);
378 return -ENODEV; 379 return -ENODEV;
379 } 380 }
380 } 381 }
@@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
386 */ 387 */
387 if (pci_enable_device(pdev)) { 388 if (pci_enable_device(pdev)) {
388 printk(KERN_ERR PFX "Unable to Enable PCI device\n"); 389 printk(KERN_ERR PFX "Unable to Enable PCI device\n");
390 agp_put_bridge(bridge);
389 return -ENODEV; 391 return -ENODEV;
390 } 392 }
391 393
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index c7ed617aa7ff..7791e98de51c 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -37,6 +37,7 @@
37#include <linux/agpgart.h> 37#include <linux/agpgart.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/mm.h> 39#include <linux/mm.h>
40#include <linux/fs.h>
40#include <linux/sched.h> 41#include <linux/sched.h>
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index d535c406b319..3db4f4076ed4 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1170,7 +1170,6 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
1170 map_page_into_agp(page); 1170 map_page_into_agp(page);
1171 1171
1172 get_page(page); 1172 get_page(page);
1173 SetPageLocked(page);
1174 atomic_inc(&agp_bridge->current_memory_agp); 1173 atomic_inc(&agp_bridge->current_memory_agp);
1175 return page_address(page); 1174 return page_address(page);
1176} 1175}
@@ -1187,7 +1186,6 @@ void agp_generic_destroy_page(void *addr)
1187 page = virt_to_page(addr); 1186 page = virt_to_page(addr);
1188 unmap_page_from_agp(page); 1187 unmap_page_from_agp(page);
1189 put_page(page); 1188 put_page(page);
1190 unlock_page(page);
1191 free_page((unsigned long)addr); 1189 free_page((unsigned long)addr);
1192 atomic_dec(&agp_bridge->current_memory_agp); 1190 atomic_dec(&agp_bridge->current_memory_agp);
1193} 1191}
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index bcdb149c8179..313a133a1172 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa)
221 if (cap != PCI_CAP_ID_AGP) { 221 if (cap != PCI_CAP_ID_AGP) {
222 printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", 222 printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
223 cap, hp->lba_cap_offset); 223 cap, hp->lba_cap_offset);
224 iounmap(hp->lba_regs);
224 return -ENODEV; 225 return -ENODEV;
225 } 226 }
226 227
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 53354bf83af7..75d2aca6353d 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge)
249 num_entries = A_SIZE_8(temp)->num_entries; 249 num_entries = A_SIZE_8(temp)->num_entries;
250 250
251 i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); 251 i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order);
252 if (!i460.gatt) {
253 printk(KERN_ERR PFX "ioremap failed\n");
254 return -ENOMEM;
255 }
252 256
253 /* These are no good, the should be removed from the agp_bridge strucure... */ 257 /* These are no good, the should be removed from the agp_bridge strucure... */
254 agp_bridge->gatt_table_real = NULL; 258 agp_bridge->gatt_table_real = NULL;
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index a1240603912c..141ca176c397 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -20,7 +20,9 @@
20#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2 20#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
21#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00 21#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
22#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02 22#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
23#define PCI_DEVICE_ID_INTEL_82965GME_HB 0x2A10
23#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 24#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
25#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
24#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE 26#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
25#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 27#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
26#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 28#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
@@ -33,7 +35,8 @@
33 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ 35 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
34 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ 36 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
35 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ 37 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
36 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB) 38 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
39 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
37 40
38#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ 41#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
39 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ 42 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
@@ -213,7 +216,6 @@ static void *i8xx_alloc_pages(void)
213 } 216 }
214 global_flush_tlb(); 217 global_flush_tlb();
215 get_page(page); 218 get_page(page);
216 SetPageLocked(page);
217 atomic_inc(&agp_bridge->current_memory_agp); 219 atomic_inc(&agp_bridge->current_memory_agp);
218 return page_address(page); 220 return page_address(page);
219} 221}
@@ -229,7 +231,6 @@ static void i8xx_destroy_pages(void *addr)
229 change_page_attr(page, 4, PAGE_KERNEL); 231 change_page_attr(page, 4, PAGE_KERNEL);
230 global_flush_tlb(); 232 global_flush_tlb();
231 put_page(page); 233 put_page(page);
232 unlock_page(page);
233 __free_pages(page, 2); 234 __free_pages(page, 2);
234 atomic_dec(&agp_bridge->current_memory_agp); 235 atomic_dec(&agp_bridge->current_memory_agp);
235} 236}
@@ -505,7 +506,7 @@ static void intel_i830_init_gtt_entries(void)
505 break; 506 break;
506 } 507 }
507 } else { 508 } else {
508 switch (gmch_ctrl & I830_GMCH_GMS_MASK) { 509 switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
509 case I855_GMCH_GMS_STOLEN_1M: 510 case I855_GMCH_GMS_STOLEN_1M:
510 gtt_entries = MB(1) - KB(size); 511 gtt_entries = MB(1) - KB(size);
511 break; 512 break;
@@ -527,6 +528,7 @@ static void intel_i830_init_gtt_entries(void)
527 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || 528 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
528 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || 529 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
529 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || 530 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
531 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
530 IS_I965 || IS_G33) 532 IS_I965 || IS_G33)
531 gtt_entries = MB(48) - KB(size); 533 gtt_entries = MB(48) - KB(size);
532 else 534 else
@@ -538,6 +540,7 @@ static void intel_i830_init_gtt_entries(void)
538 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || 540 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
539 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || 541 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
540 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || 542 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
543 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
541 IS_I965 || IS_G33) 544 IS_I965 || IS_G33)
542 gtt_entries = MB(64) - KB(size); 545 gtt_entries = MB(64) - KB(size);
543 else 546 else
@@ -911,6 +914,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
911 struct aper_size_info_fixed *size; 914 struct aper_size_info_fixed *size;
912 int num_entries; 915 int num_entries;
913 u32 temp, temp2; 916 u32 temp, temp2;
917 int gtt_map_size = 256 * 1024;
914 918
915 size = agp_bridge->current_size; 919 size = agp_bridge->current_size;
916 page_order = size->page_order; 920 page_order = size->page_order;
@@ -920,15 +924,19 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
920 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); 924 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
921 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); 925 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
922 926
923 intel_private.gtt = ioremap(temp2, 256 * 1024); 927 if (IS_G33)
928 gtt_map_size = 1024 * 1024; /* 1M on G33 */
929 intel_private.gtt = ioremap(temp2, gtt_map_size);
924 if (!intel_private.gtt) 930 if (!intel_private.gtt)
925 return -ENOMEM; 931 return -ENOMEM;
926 932
927 temp &= 0xfff80000; 933 temp &= 0xfff80000;
928 934
929 intel_private.registers = ioremap(temp,128 * 4096); 935 intel_private.registers = ioremap(temp,128 * 4096);
930 if (!intel_private.registers) 936 if (!intel_private.registers) {
937 iounmap(intel_private.gtt);
931 return -ENOMEM; 938 return -ENOMEM;
939 }
932 940
933 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; 941 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
934 global_cache_flush(); /* FIXME: ? */ 942 global_cache_flush(); /* FIXME: ? */
@@ -982,13 +990,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
982 temp &= 0xfff00000; 990 temp &= 0xfff00000;
983 intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); 991 intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
984 992
985 if (!intel_private.gtt) 993 if (!intel_private.gtt)
986 return -ENOMEM; 994 return -ENOMEM;
987 995
988 996
989 intel_private.registers = ioremap(temp,128 * 4096); 997 intel_private.registers = ioremap(temp,128 * 4096);
990 if (!intel_private.registers) 998 if (!intel_private.registers) {
991 return -ENOMEM; 999 iounmap(intel_private.gtt);
1000 return -ENOMEM;
1001 }
992 1002
993 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; 1003 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
994 global_cache_flush(); /* FIXME: ? */ 1004 global_cache_flush(); /* FIXME: ? */
@@ -1848,9 +1858,9 @@ static const struct intel_driver_description {
1848 NULL, &intel_915_driver }, 1858 NULL, &intel_915_driver },
1849 { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G", 1859 { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G",
1850 NULL, &intel_915_driver }, 1860 NULL, &intel_915_driver },
1851 { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM", 1861 { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 0, "945GM",
1852 NULL, &intel_915_driver }, 1862 NULL, &intel_915_driver },
1853 { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME", 1863 { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
1854 NULL, &intel_915_driver }, 1864 NULL, &intel_915_driver },
1855 { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", 1865 { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ",
1856 NULL, &intel_i965_driver }, 1866 NULL, &intel_i965_driver },
@@ -1860,9 +1870,9 @@ static const struct intel_driver_description {
1860 NULL, &intel_i965_driver }, 1870 NULL, &intel_i965_driver },
1861 { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G", 1871 { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G",
1862 NULL, &intel_i965_driver }, 1872 NULL, &intel_i965_driver },
1863 { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM", 1873 { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 0, "965GM",
1864 NULL, &intel_i965_driver }, 1874 NULL, &intel_i965_driver },
1865 { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE", 1875 { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
1866 NULL, &intel_i965_driver }, 1876 NULL, &intel_i965_driver },
1867 { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL }, 1877 { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL },
1868 { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL }, 1878 { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL },
@@ -2051,11 +2061,13 @@ static struct pci_device_id agp_intel_pci_table[] = {
2051 ID(PCI_DEVICE_ID_INTEL_82915GM_HB), 2061 ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
2052 ID(PCI_DEVICE_ID_INTEL_82945G_HB), 2062 ID(PCI_DEVICE_ID_INTEL_82945G_HB),
2053 ID(PCI_DEVICE_ID_INTEL_82945GM_HB), 2063 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
2064 ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
2054 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), 2065 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
2055 ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), 2066 ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
2056 ID(PCI_DEVICE_ID_INTEL_82965Q_HB), 2067 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
2057 ID(PCI_DEVICE_ID_INTEL_82965G_HB), 2068 ID(PCI_DEVICE_ID_INTEL_82965G_HB),
2058 ID(PCI_DEVICE_ID_INTEL_82965GM_HB), 2069 ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
2070 ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
2059 ID(PCI_DEVICE_ID_INTEL_G33_HB), 2071 ID(PCI_DEVICE_ID_INTEL_G33_HB),
2060 ID(PCI_DEVICE_ID_INTEL_Q35_HB), 2072 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
2061 ID(PCI_DEVICE_ID_INTEL_Q33_HB), 2073 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 6cd7373dcdf4..225ed2a53d45 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -157,6 +157,9 @@ static int nvidia_configure(void)
157 nvidia_private.aperture = 157 nvidia_private.aperture =
158 (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); 158 (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE);
159 159
160 if (!nvidia_private.aperture)
161 return -ENOMEM;
162
160 return 0; 163 return 0;
161} 164}
162 165
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index cda608c42bea..98cf8abb3e57 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -51,7 +51,6 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge)
51 return NULL; 51 return NULL;
52 52
53 get_page(page); 53 get_page(page);
54 SetPageLocked(page);
55 atomic_inc(&agp_bridge->current_memory_agp); 54 atomic_inc(&agp_bridge->current_memory_agp);
56 return page_address(page); 55 return page_address(page);
57} 56}
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 9aaf401a8975..0ecc54d327bc 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
399 .device_id = PCI_DEVICE_ID_VIA_P4M890, 399 .device_id = PCI_DEVICE_ID_VIA_P4M890,
400 .chipset_name = "P4M890", 400 .chipset_name = "P4M890",
401 }, 401 },
402 /* P4M900 */
403 {
404 .device_id = PCI_DEVICE_ID_VIA_VT3364,
405 .chipset_name = "P4M900",
406 },
402 { }, /* dummy final entry, always present */ 407 { }, /* dummy final entry, always present */
403}; 408};
404 409
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 7b02bf1289a2..3d468f502d2d 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1721,12 +1721,11 @@ static int get_async_struct(int line, struct async_struct **ret_info)
1721 *ret_info = sstate->info; 1721 *ret_info = sstate->info;
1722 return 0; 1722 return 0;
1723 } 1723 }
1724 info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); 1724 info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
1725 if (!info) { 1725 if (!info) {
1726 sstate->count--; 1726 sstate->count--;
1727 return -ENOMEM; 1727 return -ENOMEM;
1728 } 1728 }
1729 memset(info, 0, sizeof(struct async_struct));
1730#ifdef DECLARE_WAITQUEUE 1729#ifdef DECLARE_WAITQUEUE
1731 init_waitqueue_head(&info->open_wait); 1730 init_waitqueue_head(&info->open_wait);
1732 init_waitqueue_head(&info->close_wait); 1731 init_waitqueue_head(&info->close_wait);
diff --git a/drivers/char/decserial.c b/drivers/char/decserial.c
deleted file mode 100644
index 8ea2bea2b183..000000000000
--- a/drivers/char/decserial.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * sercons.c
3 * choose the right serial device at boot time
4 *
5 * triemer 6-SEP-1998
6 * sercons.c is designed to allow the three different kinds
7 * of serial devices under the decstation world to co-exist
8 * in the same kernel. The idea here is to abstract
9 * the pieces of the drivers that are common to this file
10 * so that they do not clash at compile time and runtime.
11 *
12 * HK 16-SEP-1998 v0.002
13 * removed the PROM console as this is not a real serial
14 * device. Added support for PROM console in drivers/char/tty_io.c
15 * instead. Although it may work to enable more than one
16 * console device I strongly recommend to use only one.
17 */
18
19#include <linux/init.h>
20#include <asm/dec/machtype.h>
21
22#ifdef CONFIG_ZS
23extern int zs_init(void);
24#endif
25
26#ifdef CONFIG_SERIAL_CONSOLE
27
28#ifdef CONFIG_ZS
29extern void zs_serial_console_init(void);
30#endif
31
32#endif
33
34/* rs_init - starts up the serial interface -
35 handle normal case of starting up the serial interface */
36
37#ifdef CONFIG_SERIAL
38
39int __init rs_init(void)
40{
41#ifdef CONFIG_ZS
42 if (IOASIC)
43 return zs_init();
44#endif
45 return -ENXIO;
46}
47
48__initcall(rs_init);
49
50#endif
51
52#ifdef CONFIG_SERIAL_CONSOLE
53
54/* serial_console_init handles the special case of starting
55 * up the console on the serial port
56 */
57static int __init decserial_console_init(void)
58{
59#ifdef CONFIG_ZS
60 if (IOASIC)
61 zs_serial_console_init();
62#endif
63 return 0;
64}
65console_initcall(decserial_console_init);
66
67#endif
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 923174c54a1c..c115b39b8517 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
177 MTRR_TYPE_WRCOMB, 1); 177 MTRR_TYPE_WRCOMB, 1);
178 } 178 }
179 } 179 }
180 if (map->type == _DRM_REGISTERS) 180 if (map->type == _DRM_REGISTERS) {
181 map->handle = ioremap(map->offset, map->size); 181 map->handle = ioremap(map->offset, map->size);
182 if (!map->handle) {
183 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
184 return -ENOMEM;
185 }
186 }
187
182 break; 188 break;
183 case _DRM_SHM: 189 case _DRM_SHM:
184 list = drm_find_matching_map(dev, map); 190 list = drm_find_matching_map(dev, map);
@@ -479,11 +485,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
479 return -EINVAL; 485 return -EINVAL;
480 } 486 }
481 487
482 if (!map) {
483 mutex_unlock(&dev->struct_mutex);
484 return -EINVAL;
485 }
486
487 /* Register and framebuffer maps are permanent */ 488 /* Register and framebuffer maps are permanent */
488 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { 489 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
489 mutex_unlock(&dev->struct_mutex); 490 mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 3359cc2b9736..8e7d713a5a15 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -184,6 +184,8 @@ static int i915_initialize(struct drm_device * dev,
184 * private backbuffer/depthbuffer usage. 184 * private backbuffer/depthbuffer usage.
185 */ 185 */
186 dev_priv->use_mi_batchbuffer_start = 0; 186 dev_priv->use_mi_batchbuffer_start = 0;
187 if (IS_I965G(dev)) /* 965 doesn't support older method */
188 dev_priv->use_mi_batchbuffer_start = 1;
187 189
188 /* Allow hardware batchbuffers unless told otherwise. 190 /* Allow hardware batchbuffers unless told otherwise.
189 */ 191 */
@@ -517,8 +519,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
517 519
518 if (dev_priv->use_mi_batchbuffer_start) { 520 if (dev_priv->use_mi_batchbuffer_start) {
519 BEGIN_LP_RING(2); 521 BEGIN_LP_RING(2);
520 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 522 if (IS_I965G(dev)) {
521 OUT_RING(batch->start | MI_BATCH_NON_SECURE); 523 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
524 OUT_RING(batch->start);
525 } else {
526 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
527 OUT_RING(batch->start | MI_BATCH_NON_SECURE);
528 }
522 ADVANCE_LP_RING(); 529 ADVANCE_LP_RING();
523 } else { 530 } else {
524 BEGIN_LP_RING(4); 531 BEGIN_LP_RING(4);
@@ -735,7 +742,8 @@ static int i915_setparam(DRM_IOCTL_ARGS)
735 742
736 switch (param.param) { 743 switch (param.param) {
737 case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 744 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
738 dev_priv->use_mi_batchbuffer_start = param.value; 745 if (!IS_I965G(dev))
746 dev_priv->use_mi_batchbuffer_start = param.value;
739 break; 747 break;
740 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 748 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
741 dev_priv->tex_lru_log_granularity = param.value; 749 dev_priv->tex_lru_log_granularity = param.value;
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index fd918565f4e5..28b98733beb8 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
210#define I915REG_INT_MASK_R 0x020a8 210#define I915REG_INT_MASK_R 0x020a8
211#define I915REG_INT_ENABLE_R 0x020a0 211#define I915REG_INT_ENABLE_R 0x020a0
212 212
213#define I915REG_PIPEASTAT 0x70024
214#define I915REG_PIPEBSTAT 0x71024
215
216#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
217#define I915_VBLANK_CLEAR (1UL<<1)
218
213#define SRX_INDEX 0x3c4 219#define SRX_INDEX 0x3c4
214#define SRX_DATA 0x3c5 220#define SRX_DATA 0x3c5
215#define SR01 1 221#define SR01 1
@@ -282,6 +288,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
282#define MI_BATCH_BUFFER_START (0x31<<23) 288#define MI_BATCH_BUFFER_START (0x31<<23)
283#define MI_BATCH_BUFFER_END (0xA<<23) 289#define MI_BATCH_BUFFER_END (0xA<<23)
284#define MI_BATCH_NON_SECURE (1) 290#define MI_BATCH_NON_SECURE (1)
291#define MI_BATCH_NON_SECURE_I965 (1<<8)
285 292
286#define MI_WAIT_FOR_EVENT ((0x3<<23)) 293#define MI_WAIT_FOR_EVENT ((0x3<<23))
287#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) 294#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 4b4b2ce89863..bb8e9e9c8201 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
214 struct drm_device *dev = (struct drm_device *) arg; 214 struct drm_device *dev = (struct drm_device *) arg;
215 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 215 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
216 u16 temp; 216 u16 temp;
217 u32 pipea_stats, pipeb_stats;
218
219 pipea_stats = I915_READ(I915REG_PIPEASTAT);
220 pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
217 221
218 temp = I915_READ16(I915REG_INT_IDENTITY_R); 222 temp = I915_READ16(I915REG_INT_IDENTITY_R);
219 223
@@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
225 return IRQ_NONE; 229 return IRQ_NONE;
226 230
227 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 231 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
232 (void) I915_READ16(I915REG_INT_IDENTITY_R);
233 DRM_READMEMORYBARRIER();
228 234
229 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 235 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
230 236
@@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
252 258
253 if (dev_priv->swaps_pending > 0) 259 if (dev_priv->swaps_pending > 0)
254 drm_locked_tasklet(dev, i915_vblank_tasklet); 260 drm_locked_tasklet(dev, i915_vblank_tasklet);
261 I915_WRITE(I915REG_PIPEASTAT,
262 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
263 I915_VBLANK_CLEAR);
264 I915_WRITE(I915REG_PIPEBSTAT,
265 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
266 I915_VBLANK_CLEAR);
255 } 267 }
256 268
257 return IRQ_HANDLED; 269 return IRQ_HANDLED;
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index fdb8609dd76f..3dd1ed3d1bf5 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -273,10 +273,9 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
273 vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / 273 vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
274 vsg->descriptors_per_page; 274 vsg->descriptors_per_page;
275 275
276 if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL))) 276 if (NULL == (vsg->desc_pages = kcalloc(vsg->num_desc_pages, sizeof(void *), GFP_KERNEL)))
277 return DRM_ERR(ENOMEM); 277 return DRM_ERR(ENOMEM);
278 278
279 memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages);
280 vsg->state = dr_via_desc_pages_alloc; 279 vsg->state = dr_via_desc_pages_alloc;
281 for (i=0; i<vsg->num_desc_pages; ++i) { 280 for (i=0; i<vsg->num_desc_pages; ++i) {
282 if (NULL == (vsg->desc_pages[i] = 281 if (NULL == (vsg->desc_pages[i] =
@@ -561,7 +560,7 @@ via_init_dmablit(struct drm_device *dev)
561 blitq->head = 0; 560 blitq->head = 0;
562 blitq->cur = 0; 561 blitq->cur = 0;
563 blitq->serviced = 0; 562 blitq->serviced = 0;
564 blitq->num_free = VIA_NUM_BLIT_SLOTS; 563 blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
565 blitq->num_outstanding = 0; 564 blitq->num_outstanding = 0;
566 blitq->is_active = 0; 565 blitq->is_active = 0;
567 blitq->aborting = 0; 566 blitq->aborting = 0;
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 9b8278e1f4f8..acbfe1c49b4d 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -513,7 +513,7 @@ static int __init dsp56k_init_driver(void)
513 err = PTR_ERR(dsp56k_class); 513 err = PTR_ERR(dsp56k_class);
514 goto out_chrdev; 514 goto out_chrdev;
515 } 515 }
516 class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); 516 device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k");
517 517
518 printk(banner); 518 printk(banner);
519 goto out; 519 goto out;
@@ -527,7 +527,7 @@ module_init(dsp56k_init_driver);
527 527
528static void __exit dsp56k_cleanup_driver(void) 528static void __exit dsp56k_cleanup_driver(void)
529{ 529{
530 class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); 530 device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
531 class_destroy(dsp56k_class); 531 class_destroy(dsp56k_class);
532 unregister_chrdev(DSP56K_MAJOR, "dsp56k"); 532 unregister_chrdev(DSP56K_MAJOR, "dsp56k");
533} 533}
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 74cd5118af57..2e7ae42a5503 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2459,7 +2459,7 @@ static int __init espserial_init(void)
2459 return 1; 2459 return 1;
2460 } 2460 }
2461 2461
2462 info = kmalloc(sizeof(struct esp_struct), GFP_KERNEL); 2462 info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
2463 2463
2464 if (!info) 2464 if (!info)
2465 { 2465 {
@@ -2469,7 +2469,6 @@ static int __init espserial_init(void)
2469 return 1; 2469 return 1;
2470 } 2470 }
2471 2471
2472 memset((void *)info, 0, sizeof(struct esp_struct));
2473 spin_lock_init(&info->lock); 2472 spin_lock_init(&info->lock);
2474 /* rx_trigger, tx_trigger are needed by autoconfig */ 2473 /* rx_trigger, tx_trigger are needed by autoconfig */
2475 info->config.rx_trigger = rx_trigger; 2474 info->config.rx_trigger = rx_trigger;
@@ -2527,7 +2526,7 @@ static int __init espserial_init(void)
2527 if (!dma) 2526 if (!dma)
2528 info->stat_flags |= ESP_STAT_NEVER_DMA; 2527 info->stat_flags |= ESP_STAT_NEVER_DMA;
2529 2528
2530 info = kmalloc(sizeof(struct esp_struct), GFP_KERNEL); 2529 info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
2531 if (!info) 2530 if (!info)
2532 { 2531 {
2533 printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); 2532 printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
@@ -2536,7 +2535,6 @@ static int __init espserial_init(void)
2536 return 0; 2535 return 0;
2537 } 2536 }
2538 2537
2539 memset((void *)info, 0, sizeof(struct esp_struct));
2540 /* rx_trigger, tx_trigger are needed by autoconfig */ 2538 /* rx_trigger, tx_trigger are needed by autoconfig */
2541 info->config.rx_trigger = rx_trigger; 2539 info->config.rx_trigger = rx_trigger;
2542 info->config.tx_trigger = tx_trigger; 2540 info->config.tx_trigger = tx_trigger;
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 0be700f4e8fd..4c16778e3f84 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -29,6 +29,7 @@
29#include <linux/bcd.h> 29#include <linux/bcd.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/bitops.h> 31#include <linux/bitops.h>
32#include <linux/clocksource.h>
32 33
33#include <asm/current.h> 34#include <asm/current.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -51,8 +52,37 @@
51 52
52#define HPET_RANGE_SIZE 1024 /* from HPET spec */ 53#define HPET_RANGE_SIZE 1024 /* from HPET spec */
53 54
55#if BITS_PER_LONG == 64
56#define write_counter(V, MC) writeq(V, MC)
57#define read_counter(MC) readq(MC)
58#else
59#define write_counter(V, MC) writel(V, MC)
60#define read_counter(MC) readl(MC)
61#endif
62
54static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; 63static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
55 64
65/* This clocksource driver currently only works on ia64 */
66#ifdef CONFIG_IA64
67static void __iomem *hpet_mctr;
68
69static cycle_t read_hpet(void)
70{
71 return (cycle_t)read_counter((void __iomem *)hpet_mctr);
72}
73
74static struct clocksource clocksource_hpet = {
75 .name = "hpet",
76 .rating = 250,
77 .read = read_hpet,
78 .mask = CLOCKSOURCE_MASK(64),
79 .mult = 0, /*to be caluclated*/
80 .shift = 10,
81 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
82};
83static struct clocksource *hpet_clocksource;
84#endif
85
56/* A lock for concurrent access by app and isr hpet activity. */ 86/* A lock for concurrent access by app and isr hpet activity. */
57static DEFINE_SPINLOCK(hpet_lock); 87static DEFINE_SPINLOCK(hpet_lock);
58/* A lock for concurrent intermodule access to hpet and isr hpet activity. */ 88/* A lock for concurrent intermodule access to hpet and isr hpet activity. */
@@ -79,7 +109,7 @@ struct hpets {
79 struct hpets *hp_next; 109 struct hpets *hp_next;
80 struct hpet __iomem *hp_hpet; 110 struct hpet __iomem *hp_hpet;
81 unsigned long hp_hpet_phys; 111 unsigned long hp_hpet_phys;
82 struct time_interpolator *hp_interpolator; 112 struct clocksource *hp_clocksource;
83 unsigned long long hp_tick_freq; 113 unsigned long long hp_tick_freq;
84 unsigned long hp_delta; 114 unsigned long hp_delta;
85 unsigned int hp_ntimer; 115 unsigned int hp_ntimer;
@@ -94,13 +124,6 @@ static struct hpets *hpets;
94#define HPET_PERIODIC 0x0004 124#define HPET_PERIODIC 0x0004
95#define HPET_SHARED_IRQ 0x0008 125#define HPET_SHARED_IRQ 0x0008
96 126
97#if BITS_PER_LONG == 64
98#define write_counter(V, MC) writeq(V, MC)
99#define read_counter(MC) readq(MC)
100#else
101#define write_counter(V, MC) writel(V, MC)
102#define read_counter(MC) readl(MC)
103#endif
104 127
105#ifndef readq 128#ifndef readq
106static inline unsigned long long readq(void __iomem *addr) 129static inline unsigned long long readq(void __iomem *addr)
@@ -737,27 +760,6 @@ static ctl_table dev_root[] = {
737 760
738static struct ctl_table_header *sysctl_header; 761static struct ctl_table_header *sysctl_header;
739 762
740static void hpet_register_interpolator(struct hpets *hpetp)
741{
742#ifdef CONFIG_TIME_INTERPOLATION
743 struct time_interpolator *ti;
744
745 ti = kzalloc(sizeof(*ti), GFP_KERNEL);
746 if (!ti)
747 return;
748
749 ti->source = TIME_SOURCE_MMIO64;
750 ti->shift = 10;
751 ti->addr = &hpetp->hp_hpet->hpet_mc;
752 ti->frequency = hpetp->hp_tick_freq;
753 ti->drift = HPET_DRIFT;
754 ti->mask = -1;
755
756 hpetp->hp_interpolator = ti;
757 register_time_interpolator(ti);
758#endif
759}
760
761/* 763/*
762 * Adjustment for when arming the timer with 764 * Adjustment for when arming the timer with
763 * initial conditions. That is, main counter 765 * initial conditions. That is, main counter
@@ -909,7 +911,19 @@ int hpet_alloc(struct hpet_data *hdp)
909 } 911 }
910 912
911 hpetp->hp_delta = hpet_calibrate(hpetp); 913 hpetp->hp_delta = hpet_calibrate(hpetp);
912 hpet_register_interpolator(hpetp); 914
915/* This clocksource driver currently only works on ia64 */
916#ifdef CONFIG_IA64
917 if (!hpet_clocksource) {
918 hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
919 CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr);
920 clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq,
921 clocksource_hpet.shift);
922 clocksource_register(&clocksource_hpet);
923 hpetp->hp_clocksource = &clocksource_hpet;
924 hpet_clocksource = &clocksource_hpet;
925 }
926#endif
913 927
914 return 0; 928 return 0;
915} 929}
@@ -932,14 +946,14 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
932 printk(KERN_DEBUG "%s: 0x%lx is busy\n", 946 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
933 __FUNCTION__, hdp->hd_phys_address); 947 __FUNCTION__, hdp->hd_phys_address);
934 iounmap(hdp->hd_address); 948 iounmap(hdp->hd_address);
935 return -EBUSY; 949 return AE_ALREADY_EXISTS;
936 } 950 }
937 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { 951 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
938 struct acpi_resource_fixed_memory32 *fixmem32; 952 struct acpi_resource_fixed_memory32 *fixmem32;
939 953
940 fixmem32 = &res->data.fixed_memory32; 954 fixmem32 = &res->data.fixed_memory32;
941 if (!fixmem32) 955 if (!fixmem32)
942 return -EINVAL; 956 return AE_NO_MEMORY;
943 957
944 hdp->hd_phys_address = fixmem32->address; 958 hdp->hd_phys_address = fixmem32->address;
945 hdp->hd_address = ioremap(fixmem32->address, 959 hdp->hd_address = ioremap(fixmem32->address,
@@ -949,7 +963,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
949 printk(KERN_DEBUG "%s: 0x%lx is busy\n", 963 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
950 __FUNCTION__, hdp->hd_phys_address); 964 __FUNCTION__, hdp->hd_phys_address);
951 iounmap(hdp->hd_address); 965 iounmap(hdp->hd_address);
952 return -EBUSY; 966 return AE_ALREADY_EXISTS;
953 } 967 }
954 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { 968 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
955 struct acpi_resource_extended_irq *irqp; 969 struct acpi_resource_extended_irq *irqp;
@@ -995,13 +1009,19 @@ static int hpet_acpi_add(struct acpi_device *device)
995 1009
996static int hpet_acpi_remove(struct acpi_device *device, int type) 1010static int hpet_acpi_remove(struct acpi_device *device, int type)
997{ 1011{
998 /* XXX need to unregister interpolator, dealloc mem, etc */ 1012 /* XXX need to unregister clocksource, dealloc mem, etc */
999 return -EINVAL; 1013 return -EINVAL;
1000} 1014}
1001 1015
1016static const struct acpi_device_id hpet_device_ids[] = {
1017 {"PNP0103", 0},
1018 {"", 0},
1019};
1020MODULE_DEVICE_TABLE(acpi, hpet_device_ids);
1021
1002static struct acpi_driver hpet_acpi_driver = { 1022static struct acpi_driver hpet_acpi_driver = {
1003 .name = "hpet", 1023 .name = "hpet",
1004 .ids = "PNP0103", 1024 .ids = hpet_device_ids,
1005 .ops = { 1025 .ops = {
1006 .add = hpet_acpi_add, 1026 .add = hpet_acpi_add,
1007 .remove = hpet_acpi_remove, 1027 .remove = hpet_acpi_remove,
diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c
index 6f019f19be71..e74bb949c289 100644
--- a/drivers/char/hvc_beat.c
+++ b/drivers/char/hvc_beat.c
@@ -97,7 +97,7 @@ static int hvc_beat_config(char *p)
97 return 0; 97 return 0;
98} 98}
99 99
100static int hvc_beat_console_init(void) 100static int __init hvc_beat_console_init(void)
101{ 101{
102 if (hvc_beat_useit && machine_is_compatible("Beat")) { 102 if (hvc_beat_useit && machine_is_compatible("Beat")) {
103 hvc_instantiate(0, 0, &hvc_beat_get_put_ops); 103 hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
@@ -106,7 +106,7 @@ static int hvc_beat_console_init(void)
106} 106}
107 107
108/* temp */ 108/* temp */
109static int hvc_beat_init(void) 109static int __init hvc_beat_init(void)
110{ 110{
111 struct hvc_struct *hp; 111 struct hvc_struct *hp;
112 112
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index b37f1d5a5be6..a08f8f981c11 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -472,7 +472,7 @@ static void hvc_handle_event(struct HvLpEvent *event)
472 } 472 }
473} 473}
474 474
475static int send_open(HvLpIndex remoteLp, void *sem) 475static int __init send_open(HvLpIndex remoteLp, void *sem)
476{ 476{
477 return HvCallEvent_signalLpEventFast(remoteLp, 477 return HvCallEvent_signalLpEventFast(remoteLp,
478 HvLpEvent_Type_VirtualIo, 478 HvLpEvent_Type_VirtualIo,
@@ -484,7 +484,7 @@ static int send_open(HvLpIndex remoteLp, void *sem)
484 0, 0, 0, 0); 484 0, 0, 0, 0);
485} 485}
486 486
487static int hvc_vio_init(void) 487static int __init hvc_vio_init(void)
488{ 488{
489 atomic_t wait_flag; 489 atomic_t wait_flag;
490 int rc; 490 int rc;
@@ -552,14 +552,14 @@ static int hvc_vio_init(void)
552} 552}
553module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ 553module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
554 554
555static void hvc_vio_exit(void) 555static void __exit hvc_vio_exit(void)
556{ 556{
557 vio_unregister_driver(&hvc_vio_driver); 557 vio_unregister_driver(&hvc_vio_driver);
558} 558}
559module_exit(hvc_vio_exit); 559module_exit(hvc_vio_exit);
560 560
561/* the device tree order defines our numbering */ 561/* the device tree order defines our numbering */
562static int hvc_find_vtys(void) 562static int __init hvc_find_vtys(void)
563{ 563{
564 struct device_node *vty; 564 struct device_node *vty;
565 int num_found = 0; 565 int num_found = 0;
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c
new file mode 100644
index 000000000000..3d6bd0baa56d
--- /dev/null
+++ b/drivers/char/hvc_lguest.c
@@ -0,0 +1,177 @@
1/*D:300
2 * The Guest console driver
3 *
4 * This is a trivial console driver: we use lguest's DMA mechanism to send
5 * bytes out, and register a DMA buffer to receive bytes in. It is assumed to
6 * be present and available from the very beginning of boot.
7 *
8 * Writing console drivers is one of the few remaining Dark Arts in Linux.
9 * Fortunately for us, the path of virtual consoles has been well-trodden by
10 * the PowerPC folks, who wrote "hvc_console.c" to generically support any
11 * virtual console. We use that infrastructure which only requires us to write
12 * the basic put_chars and get_chars functions and call the right register
13 * functions.
14 :*/
15
16/*M:002 The console can be flooded: while the Guest is processing input the
17 * Host can send more. Buffering in the Host could alleviate this, but it is a
18 * difficult problem in general. :*/
19/* Copyright (C) 2006 Rusty Russell, IBM Corporation
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 */
35#include <linux/err.h>
36#include <linux/init.h>
37#include <linux/lguest_bus.h>
38#include <asm/paravirt.h>
39#include "hvc_console.h"
40
41/*D:340 This is our single console input buffer, with associated "struct
42 * lguest_dma" referring to it. Note the 0-terminated length array, and the
43 * use of physical address for the buffer itself. */
44static char inbuf[256];
45static struct lguest_dma cons_input = { .used_len = 0,
46 .addr[0] = __pa(inbuf),
47 .len[0] = sizeof(inbuf),
48 .len[1] = 0 };
49
50/*D:310 The put_chars() callback is pretty straightforward.
51 *
52 * First we put the pointer and length in a "struct lguest_dma": we only have
53 * one pointer, so we set the second length to 0. Then we use SEND_DMA to send
54 * the data to (Host) buffers attached to the console key. Usually a device's
55 * key is a physical address within the device's memory, but because the
56 * console device doesn't have any associated physical memory, we use the
57 * LGUEST_CONSOLE_DMA_KEY constant (aka 0). */
58static int put_chars(u32 vtermno, const char *buf, int count)
59{
60 struct lguest_dma dma;
61
62 /* FIXME: DMA buffers in a "struct lguest_dma" are not allowed
63 * to go over page boundaries. This never seems to happen,
64 * but if it did we'd need to fix this code. */
65 dma.len[0] = count;
66 dma.len[1] = 0;
67 dma.addr[0] = __pa(buf);
68
69 lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
70 /* We're expected to return the amount of data we wrote: all of it. */
71 return count;
72}
73
74/*D:350 get_chars() is the callback from the hvc_console infrastructure when
75 * an interrupt is received.
76 *
77 * Firstly we see if our buffer has been filled: if not, we return. The rest
78 * of the code deals with the fact that the hvc_console() infrastructure only
79 * asks us for 16 bytes at a time. We keep a "cons_offset" variable for
80 * partially-read buffers. */
81static int get_chars(u32 vtermno, char *buf, int count)
82{
83 static int cons_offset;
84
85 /* Nothing left to see here... */
86 if (!cons_input.used_len)
87 return 0;
88
89 /* You want more than we have to give? Well, try wanting less! */
90 if (cons_input.used_len - cons_offset < count)
91 count = cons_input.used_len - cons_offset;
92
93 /* Copy across to their buffer and increment offset. */
94 memcpy(buf, inbuf + cons_offset, count);
95 cons_offset += count;
96
97 /* Finished? Zero offset, and reset cons_input so Host will use it
98 * again. */
99 if (cons_offset == cons_input.used_len) {
100 cons_offset = 0;
101 cons_input.used_len = 0;
102 }
103 return count;
104}
105/*:*/
106
107static struct hv_ops lguest_cons = {
108 .get_chars = get_chars,
109 .put_chars = put_chars,
110};
111
112/*D:320 Console drivers are initialized very early so boot messages can go
113 * out. At this stage, the console is output-only. Our driver checks we're a
114 * Guest, and if so hands hvc_instantiate() the console number (0), priority
115 * (0), and the struct hv_ops containing the put_chars() function. */
116static int __init cons_init(void)
117{
118 if (strcmp(paravirt_ops.name, "lguest") != 0)
119 return 0;
120
121 return hvc_instantiate(0, 0, &lguest_cons);
122}
123console_initcall(cons_init);
124
125/*D:370 To set up and manage our virtual console, we call hvc_alloc() and
126 * stash the result in the private pointer of the "struct lguest_device".
127 * Since we never remove the console device we never need this pointer again,
128 * but using ->private is considered good form, and you never know who's going
129 * to copy your driver.
130 *
131 * Once the console is set up, we bind our input buffer ready for input. */
132static int lguestcons_probe(struct lguest_device *lgdev)
133{
134 int err;
135
136 /* The first argument of hvc_alloc() is the virtual console number, so
137 * we use zero. The second argument is the interrupt number.
138 *
139 * The third argument is a "struct hv_ops" containing the put_chars()
140 * and get_chars() pointers. The final argument is the output buffer
141 * size: we use 256 and expect the Host to have room for us to send
142 * that much. */
143 lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
144 if (IS_ERR(lgdev->private))
145 return PTR_ERR(lgdev->private);
146
147 /* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY.
148 * "cons_input" is that statically-initialized global DMA buffer we saw
149 * above, and we also give the interrupt we want. */
150 err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
151 lgdev_irq(lgdev));
152 if (err)
153 printk("lguest console: failed to bind buffer.\n");
154 return err;
155}
156/* Note the use of lgdev_irq() for the interrupt number. We tell hvc_alloc()
157 * to expect input when this interrupt is triggered, and then tell
158 * lguest_bind_dma() that is the interrupt to send us when input comes in. */
159
160/*D:360 From now on the console driver follows standard Guest driver form:
161 * register_lguest_driver() registers the device type and probe function, and
162 * the probe function sets up the device.
163 *
164 * The standard "struct lguest_driver": */
165static struct lguest_driver lguestcons_drv = {
166 .name = "lguestcons",
167 .owner = THIS_MODULE,
168 .device_type = LGUEST_DEVICE_T_CONSOLE,
169 .probe = lguestcons_probe,
170};
171
172/* The standard init function */
173static int __init hvc_lguest_init(void)
174{
175 return register_lguest_driver(&lguestcons_drv);
176}
177module_init(hvc_lguest_init);
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
index 4b97eaf18602..bb09413d5a21 100644
--- a/drivers/char/hvc_rtas.c
+++ b/drivers/char/hvc_rtas.c
@@ -115,7 +115,7 @@ static void __exit hvc_rtas_exit(void)
115module_exit(hvc_rtas_exit); 115module_exit(hvc_rtas_exit);
116 116
117/* This will happen prior to module init. There is no tty at this time? */ 117/* This will happen prior to module init. There is no tty at this time? */
118static int hvc_rtas_console_init(void) 118static int __init hvc_rtas_console_init(void)
119{ 119{
120 rtascons_put_char_token = rtas_token("put-term-char"); 120 rtascons_put_char_token = rtas_token("put-term-char");
121 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) 121 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
new file mode 100644
index 000000000000..dd68f8541c2d
--- /dev/null
+++ b/drivers/char/hvc_xen.c
@@ -0,0 +1,159 @@
1/*
2 * xen console driver interface to hvc_console.c
3 *
4 * (c) 2007 Gerd Hoffmann <kraxel@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/err.h>
24#include <linux/init.h>
25#include <linux/types.h>
26
27#include <asm/xen/hypervisor.h>
28#include <xen/page.h>
29#include <xen/events.h>
30#include <xen/interface/io/console.h>
31#include <xen/hvc-console.h>
32
33#include "hvc_console.h"
34
35#define HVC_COOKIE 0x58656e /* "Xen" in hex */
36
37static struct hvc_struct *hvc;
38static int xencons_irq;
39
40/* ------------------------------------------------------------------ */
41
42static inline struct xencons_interface *xencons_interface(void)
43{
44 return mfn_to_virt(xen_start_info->console.domU.mfn);
45}
46
47static inline void notify_daemon(void)
48{
49 /* Use evtchn: this is called early, before irq is set up. */
50 notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
51}
52
53static int write_console(uint32_t vtermno, const char *data, int len)
54{
55 struct xencons_interface *intf = xencons_interface();
56 XENCONS_RING_IDX cons, prod;
57 int sent = 0;
58
59 cons = intf->out_cons;
60 prod = intf->out_prod;
61 mb(); /* update queue values before going on */
62 BUG_ON((prod - cons) > sizeof(intf->out));
63
64 while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
65 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
66
67 wmb(); /* write ring before updating pointer */
68 intf->out_prod = prod;
69
70 notify_daemon();
71 return sent;
72}
73
74static int read_console(uint32_t vtermno, char *buf, int len)
75{
76 struct xencons_interface *intf = xencons_interface();
77 XENCONS_RING_IDX cons, prod;
78 int recv = 0;
79
80 cons = intf->in_cons;
81 prod = intf->in_prod;
82 mb(); /* get pointers before reading ring */
83 BUG_ON((prod - cons) > sizeof(intf->in));
84
85 while (cons != prod && recv < len)
86 buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
87
88 mb(); /* read ring before consuming */
89 intf->in_cons = cons;
90
91 notify_daemon();
92 return recv;
93}
94
95static struct hv_ops hvc_ops = {
96 .get_chars = read_console,
97 .put_chars = write_console,
98};
99
100static int __init xen_init(void)
101{
102 struct hvc_struct *hp;
103
104 if (!is_running_on_xen())
105 return 0;
106
107 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
108 if (xencons_irq < 0)
109 xencons_irq = 0 /* NO_IRQ */;
110 hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
111 if (IS_ERR(hp))
112 return PTR_ERR(hp);
113
114 hvc = hp;
115 return 0;
116}
117
118static void __exit xen_fini(void)
119{
120 if (hvc)
121 hvc_remove(hvc);
122}
123
124static int xen_cons_init(void)
125{
126 if (!is_running_on_xen())
127 return 0;
128
129 hvc_instantiate(HVC_COOKIE, 0, &hvc_ops);
130 return 0;
131}
132
133module_init(xen_init);
134module_exit(xen_fini);
135console_initcall(xen_cons_init);
136
137static void xenboot_write_console(struct console *console, const char *string,
138 unsigned len)
139{
140 unsigned int linelen, off = 0;
141 const char *pos;
142
143 while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
144 linelen = pos-string+off;
145 if (off + linelen > len)
146 break;
147 write_console(0, string+off, linelen);
148 write_console(0, "\r\n", 2);
149 off += linelen + 1;
150 }
151 if (off < len)
152 write_console(0, string+off, len-off);
153}
154
155struct console xenboot_console = {
156 .name = "xenboot",
157 .write = xenboot_write_console,
158 .flags = CON_PRINTBUFFER | CON_BOOT,
159};
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 207f7343ba60..69d8866de783 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -210,9 +210,9 @@ static struct ktermios hvcs_tty_termios = {
210static int hvcs_parm_num_devs = -1; 210static int hvcs_parm_num_devs = -1;
211module_param(hvcs_parm_num_devs, int, 0); 211module_param(hvcs_parm_num_devs, int, 0);
212 212
213char hvcs_driver_name[] = "hvcs"; 213static const char hvcs_driver_name[] = "hvcs";
214char hvcs_device_node[] = "hvcs"; 214static const char hvcs_device_node[] = "hvcs";
215char hvcs_driver_string[] 215static const char hvcs_driver_string[]
216 = "IBM hvcs (Hypervisor Virtual Console Server) Driver"; 216 = "IBM hvcs (Hypervisor Virtual Console Server) Driver";
217 217
218/* Status of partner info rescan triggered via sysfs. */ 218/* Status of partner info rescan triggered via sysfs. */
@@ -784,12 +784,10 @@ static int __devinit hvcs_probe(
784 return -EFAULT; 784 return -EFAULT;
785 } 785 }
786 786
787 hvcsd = kmalloc(sizeof(*hvcsd), GFP_KERNEL); 787 hvcsd = kzalloc(sizeof(*hvcsd), GFP_KERNEL);
788 if (!hvcsd) 788 if (!hvcsd)
789 return -ENODEV; 789 return -ENODEV;
790 790
791 /* hvcsd->tty is zeroed out with the memset */
792 memset(hvcsd, 0x00, sizeof(*hvcsd));
793 791
794 spin_lock_init(&hvcsd->lock); 792 spin_lock_init(&hvcsd->lock);
795 /* Automatically incs the refcount the first time */ 793 /* Automatically incs the refcount the first time */
@@ -1094,7 +1092,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
1094 * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when 1092 * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when
1095 * calling this function or you will get deadlock. 1093 * calling this function or you will get deadlock.
1096 */ 1094 */
1097struct hvcs_struct *hvcs_get_by_index(int index) 1095static struct hvcs_struct *hvcs_get_by_index(int index)
1098{ 1096{
1099 struct hvcs_struct *hvcsd = NULL; 1097 struct hvcs_struct *hvcsd = NULL;
1100 unsigned long flags; 1098 unsigned long flags;
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 7cda04b33534..2d7cd486e025 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -41,7 +41,7 @@ config HW_RANDOM_AMD
41 41
42config HW_RANDOM_GEODE 42config HW_RANDOM_GEODE
43 tristate "AMD Geode HW Random Number Generator support" 43 tristate "AMD Geode HW Random Number Generator support"
44 depends on HW_RANDOM && X86 && PCI 44 depends on HW_RANDOM && X86_32 && PCI
45 default HW_RANDOM 45 default HW_RANDOM
46 ---help--- 46 ---help---
47 This driver provides kernel-side support for the Random Number 47 This driver provides kernel-side support for the Random Number
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 0289705967de..cd406416effd 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -98,9 +98,9 @@ struct smm_regs {
98 unsigned int edi __attribute__ ((packed)); 98 unsigned int edi __attribute__ ((packed));
99}; 99};
100 100
101static inline char *i8k_get_dmi_data(int field) 101static inline const char *i8k_get_dmi_data(int field)
102{ 102{
103 char *dmi_data = dmi_get_system_info(field); 103 const char *dmi_data = dmi_get_system_info(field);
104 104
105 return dmi_data && *dmi_data ? dmi_data : "?"; 105 return dmi_data && *dmi_data ? dmi_data : "?";
106} 106}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 83c7258d3580..bd94d5f9e62b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -411,8 +411,8 @@ cleanup_module(void)
411 iiResetDelay( i2BoardPtrTable[i] ); 411 iiResetDelay( i2BoardPtrTable[i] );
412 /* free io addresses and Tibet */ 412 /* free io addresses and Tibet */
413 release_region( ip2config.addr[i], 8 ); 413 release_region( ip2config.addr[i], 8 );
414 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); 414 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
415 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); 415 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
416 } 416 }
417 /* Disable and remove interrupt handler. */ 417 /* Disable and remove interrupt handler. */
418 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 418 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
@@ -425,9 +425,7 @@ cleanup_module(void)
425 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); 425 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
426 } 426 }
427 put_tty_driver(ip2_tty_driver); 427 put_tty_driver(ip2_tty_driver);
428 if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) { 428 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
429 printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
430 }
431 remove_proc_entry("ip2mem", &proc_root); 429 remove_proc_entry("ip2mem", &proc_root);
432 430
433 // free memory 431 // free memory
@@ -502,7 +500,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
502{ 500{
503 int i, j, box; 501 int i, j, box;
504 int err = 0; 502 int err = 0;
505 int status = 0;
506 static int loaded; 503 static int loaded;
507 i2eBordStrPtr pB = NULL; 504 i2eBordStrPtr pB = NULL;
508 int rc = -1; 505 int rc = -1;
@@ -590,6 +587,8 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
590 case PCI: 587 case PCI:
591#ifdef CONFIG_PCI 588#ifdef CONFIG_PCI
592 { 589 {
590 int status;
591
593 pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, 592 pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
594 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); 593 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
595 if (pci_dev_i != NULL) { 594 if (pci_dev_i != NULL) {
@@ -719,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
719 } 718 }
720 719
721 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { 720 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
722 class_device_create(ip2_class, NULL, 721 device_create(ip2_class, NULL,
723 MKDEV(IP2_IPL_MAJOR, 4 * i), 722 MKDEV(IP2_IPL_MAJOR, 4 * i),
724 NULL, "ipl%d", i); 723 "ipl%d", i);
725 class_device_create(ip2_class, NULL, 724 device_create(ip2_class, NULL,
726 MKDEV(IP2_IPL_MAJOR, 4 * i + 1), 725 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
727 NULL, "stat%d", i); 726 "stat%d", i);
728 727
729 for ( box = 0; box < ABS_MAX_BOXES; ++box ) 728 for ( box = 0; box < ABS_MAX_BOXES; ++box )
730 { 729 {
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index c2aa44ee6eb6..0246a2b8ce48 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -865,7 +865,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
865 entry->dev = dev; 865 entry->dev = dev;
866 866
867 mutex_lock(&reg_list_mutex); 867 mutex_lock(&reg_list_mutex);
868 class_device_create(ipmi_class, NULL, dev, device, "ipmi%d", if_num); 868 device_create(ipmi_class, device, dev, "ipmi%d", if_num);
869 list_add(&entry->link, &reg_list); 869 list_add(&entry->link, &reg_list);
870 mutex_unlock(&reg_list_mutex); 870 mutex_unlock(&reg_list_mutex);
871} 871}
@@ -883,7 +883,7 @@ static void ipmi_smi_gone(int if_num)
883 break; 883 break;
884 } 884 }
885 } 885 }
886 class_device_destroy(ipmi_class, dev); 886 device_destroy(ipmi_class, dev);
887 mutex_unlock(&reg_list_mutex); 887 mutex_unlock(&reg_list_mutex);
888} 888}
889 889
@@ -938,7 +938,7 @@ static __exit void cleanup_ipmi(void)
938 mutex_lock(&reg_list_mutex); 938 mutex_lock(&reg_list_mutex);
939 list_for_each_entry_safe(entry, entry2, &reg_list, link) { 939 list_for_each_entry_safe(entry, entry2, &reg_list, link) {
940 list_del(&entry->link); 940 list_del(&entry->link);
941 class_device_destroy(ipmi_class, entry->dev); 941 device_destroy(ipmi_class, entry->dev);
942 kfree(entry); 942 kfree(entry);
943 } 943 }
944 mutex_unlock(&reg_list_mutex); 944 mutex_unlock(&reg_list_mutex);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index b5df7e61aeb2..6a01dd9e43f8 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2639,10 +2639,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2639 return -ENODEV; 2639 return -ENODEV;
2640 } 2640 }
2641 2641
2642 intf = kmalloc(sizeof(*intf), GFP_KERNEL); 2642 intf = kzalloc(sizeof(*intf), GFP_KERNEL);
2643 if (!intf) 2643 if (!intf)
2644 return -ENOMEM; 2644 return -ENOMEM;
2645 memset(intf, 0, sizeof(*intf));
2646 2645
2647 intf->ipmi_version_major = ipmi_version_major(device_id); 2646 intf->ipmi_version_major = ipmi_version_major(device_id);
2648 intf->ipmi_version_minor = ipmi_version_minor(device_id); 2647 intf->ipmi_version_minor = ipmi_version_minor(device_id);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 4edfdda0cf99..a2894d425153 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1965,10 +1965,10 @@ struct dmi_ipmi_data
1965 u8 slave_addr; 1965 u8 slave_addr;
1966}; 1966};
1967 1967
1968static int __devinit decode_dmi(struct dmi_header *dm, 1968static int __devinit decode_dmi(const struct dmi_header *dm,
1969 struct dmi_ipmi_data *dmi) 1969 struct dmi_ipmi_data *dmi)
1970{ 1970{
1971 u8 *data = (u8 *)dm; 1971 const u8 *data = (const u8 *)dm;
1972 unsigned long base_addr; 1972 unsigned long base_addr;
1973 u8 reg_spacing; 1973 u8 reg_spacing;
1974 u8 len = dm->length; 1974 u8 len = dm->length;
@@ -2050,6 +2050,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
2050 info->si_type = SI_BT; 2050 info->si_type = SI_BT;
2051 break; 2051 break;
2052 default: 2052 default:
2053 kfree(info);
2053 return; 2054 return;
2054 } 2055 }
2055 2056
@@ -2090,13 +2091,14 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
2090 2091
2091static void __devinit dmi_find_bmc(void) 2092static void __devinit dmi_find_bmc(void)
2092{ 2093{
2093 struct dmi_device *dev = NULL; 2094 const struct dmi_device *dev = NULL;
2094 struct dmi_ipmi_data data; 2095 struct dmi_ipmi_data data;
2095 int rv; 2096 int rv;
2096 2097
2097 while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { 2098 while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) {
2098 memset(&data, 0, sizeof(data)); 2099 memset(&data, 0, sizeof(data));
2099 rv = decode_dmi((struct dmi_header *) dev->device_data, &data); 2100 rv = decode_dmi((const struct dmi_header *) dev->device_data,
2101 &data);
2100 if (!rv) 2102 if (!rv)
2101 try_init_dmi(&data); 2103 try_init_dmi(&data);
2102 } 2104 }
@@ -2214,7 +2216,8 @@ static int ipmi_pci_resume(struct pci_dev *pdev)
2214 2216
2215static struct pci_device_id ipmi_pci_devices[] = { 2217static struct pci_device_id ipmi_pci_devices[] = {
2216 { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, 2218 { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
2217 { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } 2219 { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
2220 { 0, }
2218}; 2221};
2219MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); 2222MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
2220 2223
@@ -2250,19 +2253,19 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
2250 return ret; 2253 return ret;
2251 } 2254 }
2252 2255
2253 regsize = get_property(np, "reg-size", &proplen); 2256 regsize = of_get_property(np, "reg-size", &proplen);
2254 if (regsize && proplen != 4) { 2257 if (regsize && proplen != 4) {
2255 dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); 2258 dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
2256 return -EINVAL; 2259 return -EINVAL;
2257 } 2260 }
2258 2261
2259 regspacing = get_property(np, "reg-spacing", &proplen); 2262 regspacing = of_get_property(np, "reg-spacing", &proplen);
2260 if (regspacing && proplen != 4) { 2263 if (regspacing && proplen != 4) {
2261 dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); 2264 dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
2262 return -EINVAL; 2265 return -EINVAL;
2263 } 2266 }
2264 2267
2265 regshift = get_property(np, "reg-shift", &proplen); 2268 regshift = of_get_property(np, "reg-shift", &proplen);
2266 if (regshift && proplen != 4) { 2269 if (regshift && proplen != 4) {
2267 dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); 2270 dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
2268 return -EINVAL; 2271 return -EINVAL;
@@ -2291,7 +2294,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
2291 info->irq = irq_of_parse_and_map(dev->node, 0); 2294 info->irq = irq_of_parse_and_map(dev->node, 0);
2292 info->dev = &dev->dev; 2295 info->dev = &dev->dev;
2293 2296
2294 dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", 2297 dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n",
2295 info->io.addr_data, info->io.regsize, info->io.regspacing, 2298 info->io.addr_data, info->io.regsize, info->io.regspacing,
2296 info->irq); 2299 info->irq);
2297 2300
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 3c66f402f9d7..1f27be1ec3d4 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -4624,9 +4624,8 @@ static int __init istallion_module_init(void)
4624 4624
4625 istallion_class = class_create(THIS_MODULE, "staliomem"); 4625 istallion_class = class_create(THIS_MODULE, "staliomem");
4626 for (i = 0; i < 4; i++) 4626 for (i = 0; i < 4; i++)
4627 class_device_create(istallion_class, NULL, 4627 device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
4628 MKDEV(STL_SIOMEMMAJOR, i), 4628 "staliomem%d", i);
4629 NULL, "staliomem%d", i);
4630 4629
4631 return 0; 4630 return 0;
4632err_deinit: 4631err_deinit:
@@ -4659,8 +4658,7 @@ static void __exit istallion_module_exit(void)
4659 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); 4658 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4660 4659
4661 for (j = 0; j < 4; j++) 4660 for (j = 0; j < 4; j++)
4662 class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, 4661 device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
4663 j));
4664 class_destroy(istallion_class); 4662 class_destroy(istallion_class);
4665 4663
4666 pci_unregister_driver(&stli_pcidriver); 4664 pci_unregister_driver(&stli_pcidriver);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 2ce0af1bd588..d95f316afb5a 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] =
1022 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 1022 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1023 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; 1023 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1024 1024
1025#ifdef CONFIG_MAC_EMUMOUSEBTN
1026extern int mac_hid_mouse_emulate_buttons(int, int, int);
1027#endif /* CONFIG_MAC_EMUMOUSEBTN */
1028
1029#ifdef CONFIG_SPARC 1025#ifdef CONFIG_SPARC
1030static int sparc_l1_a_state = 0; 1026static int sparc_l1_a_state = 0;
1031extern void sun_do_break(void); 1027extern void sun_do_break(void);
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 1f0962616ee5..4fe9206f84de 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -25,7 +25,6 @@
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/system.h> 27#include <asm/system.h>
28#include <linux/delay.h>
29 28
30#include "lcd.h" 29#include "lcd.h"
31 30
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 62051f8b0910..c59e2a0996cc 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -799,8 +799,7 @@ static int lp_register(int nr, struct parport *port)
799 if (reset) 799 if (reset)
800 lp_reset(nr); 800 lp_reset(nr);
801 801
802 class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, 802 device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr);
803 "lp%d", nr);
804 803
805 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 804 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
806 (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); 805 (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
@@ -971,7 +970,7 @@ static void lp_cleanup_module (void)
971 if (lp_table[offset].dev == NULL) 970 if (lp_table[offset].dev == NULL)
972 continue; 971 continue;
973 parport_unregister_device(lp_table[offset].dev); 972 parport_unregister_device(lp_table[offset].dev);
974 class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); 973 device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
975 } 974 }
976 class_destroy(lp_class); 975 class_destroy(lp_class);
977} 976}
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 57f9115a456c..7ee5d9444926 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -39,14 +39,14 @@
39#else 39#else
40#define DBG(fmt...) 40#define DBG(fmt...)
41#endif 41#endif
42int mbcs_major; 42static int mbcs_major;
43 43
44LIST_HEAD(soft_list); 44static LIST_HEAD(soft_list);
45 45
46/* 46/*
47 * file operations 47 * file operations
48 */ 48 */
49const struct file_operations mbcs_ops = { 49static const struct file_operations mbcs_ops = {
50 .open = mbcs_open, 50 .open = mbcs_open,
51 .llseek = mbcs_sram_llseek, 51 .llseek = mbcs_sram_llseek,
52 .read = mbcs_sram_read, 52 .read = mbcs_sram_read,
@@ -377,7 +377,7 @@ dmaread_exit:
377 return rv; 377 return rv;
378} 378}
379 379
380int mbcs_open(struct inode *ip, struct file *fp) 380static int mbcs_open(struct inode *ip, struct file *fp)
381{ 381{
382 struct mbcs_soft *soft; 382 struct mbcs_soft *soft;
383 int minor; 383 int minor;
@@ -394,7 +394,7 @@ int mbcs_open(struct inode *ip, struct file *fp)
394 return -ENODEV; 394 return -ENODEV;
395} 395}
396 396
397ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off) 397static ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
398{ 398{
399 struct cx_dev *cx_dev = fp->private_data; 399 struct cx_dev *cx_dev = fp->private_data;
400 struct mbcs_soft *soft = cx_dev->soft; 400 struct mbcs_soft *soft = cx_dev->soft;
@@ -418,7 +418,7 @@ ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t *
418 return rv; 418 return rv;
419} 419}
420 420
421ssize_t 421static ssize_t
422mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off) 422mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off)
423{ 423{
424 struct cx_dev *cx_dev = fp->private_data; 424 struct cx_dev *cx_dev = fp->private_data;
@@ -443,7 +443,7 @@ mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * o
443 return rv; 443 return rv;
444} 444}
445 445
446loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence) 446static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
447{ 447{
448 loff_t newpos; 448 loff_t newpos;
449 449
@@ -491,7 +491,7 @@ static void mbcs_gscr_pioaddr_set(struct mbcs_soft *soft)
491 soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START); 491 soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START);
492} 492}
493 493
494int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma) 494static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
495{ 495{
496 struct cx_dev *cx_dev = fp->private_data; 496 struct cx_dev *cx_dev = fp->private_data;
497 struct mbcs_soft *soft = cx_dev->soft; 497 struct mbcs_soft *soft = cx_dev->soft;
@@ -793,7 +793,7 @@ static int mbcs_remove(struct cx_dev *dev)
793 return 0; 793 return 0;
794} 794}
795 795
796const struct cx_device_id __devinitdata mbcs_id_table[] = { 796static const struct cx_device_id __devinitdata mbcs_id_table[] = {
797 { 797 {
798 .part_num = MBCS_PART_NUM, 798 .part_num = MBCS_PART_NUM,
799 .mfg_num = MBCS_MFG_NUM, 799 .mfg_num = MBCS_MFG_NUM,
@@ -807,7 +807,7 @@ const struct cx_device_id __devinitdata mbcs_id_table[] = {
807 807
808MODULE_DEVICE_TABLE(cx, mbcs_id_table); 808MODULE_DEVICE_TABLE(cx, mbcs_id_table);
809 809
810struct cx_drv mbcs_driver = { 810static struct cx_drv mbcs_driver = {
811 .name = DEVICE_NAME, 811 .name = DEVICE_NAME,
812 .id_table = mbcs_id_table, 812 .id_table = mbcs_id_table,
813 .probe = mbcs_probe, 813 .probe = mbcs_probe,
@@ -816,12 +816,7 @@ struct cx_drv mbcs_driver = {
816 816
817static void __exit mbcs_exit(void) 817static void __exit mbcs_exit(void)
818{ 818{
819 int rv; 819 unregister_chrdev(mbcs_major, DEVICE_NAME);
820
821 rv = unregister_chrdev(mbcs_major, DEVICE_NAME);
822 if (rv < 0)
823 DBG(KERN_ALERT "Error in unregister_chrdev: %d\n", rv);
824
825 cx_driver_unregister(&mbcs_driver); 820 cx_driver_unregister(&mbcs_driver);
826} 821}
827 822
diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h
index e7fd47e43257..c9905a3c3353 100644
--- a/drivers/char/mbcs.h
+++ b/drivers/char/mbcs.h
@@ -542,12 +542,12 @@ struct mbcs_soft {
542 struct semaphore algolock; 542 struct semaphore algolock;
543}; 543};
544 544
545extern int mbcs_open(struct inode *ip, struct file *fp); 545static int mbcs_open(struct inode *ip, struct file *fp);
546extern ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len, 546static ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
547 loff_t * off); 547 loff_t * off);
548extern ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len, 548static ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
549 loff_t * off); 549 loff_t * off);
550extern loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence); 550static loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
551extern int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma); 551static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
552 552
553#endif // __MBCS_H__ 553#endif // __MBCS_H__
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 6e55cfb9c65a..e60a74c66e3d 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -25,6 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/fs.h>
28#include <linux/mmtimer.h> 29#include <linux/mmtimer.h>
29#include <linux/miscdevice.h> 30#include <linux/miscdevice.h>
30#include <linux/posix-timers.h> 31#include <linux/posix-timers.h>
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index c716ef0dd370..04ac155d3a07 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -38,6 +38,7 @@
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/mm.h> 40#include <linux/mm.h>
41#include <linux/fs.h>
41#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
42#include <linux/string.h> 43#include <linux/string.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
@@ -66,7 +67,7 @@
66/* 67/*
67 * Page types allocated by the device. 68 * Page types allocated by the device.
68 */ 69 */
69enum { 70enum mspec_page_type {
70 MSPEC_FETCHOP = 1, 71 MSPEC_FETCHOP = 1,
71 MSPEC_CACHED, 72 MSPEC_CACHED,
72 MSPEC_UNCACHED 73 MSPEC_UNCACHED
@@ -82,15 +83,25 @@ static int is_sn2;
82 * One of these structures is allocated when an mspec region is mmaped. The 83 * One of these structures is allocated when an mspec region is mmaped. The
83 * structure is pointed to by the vma->vm_private_data field in the vma struct. 84 * structure is pointed to by the vma->vm_private_data field in the vma struct.
84 * This structure is used to record the addresses of the mspec pages. 85 * This structure is used to record the addresses of the mspec pages.
86 * This structure is shared by all vma's that are split off from the
87 * original vma when split_vma()'s are done.
88 *
89 * The refcnt is incremented atomically because mm->mmap_sem does not
90 * protect in fork case where multiple tasks share the vma_data.
85 */ 91 */
86struct vma_data { 92struct vma_data {
87 atomic_t refcnt; /* Number of vmas sharing the data. */ 93 atomic_t refcnt; /* Number of vmas sharing the data. */
88 spinlock_t lock; /* Serialize access to the vma. */ 94 spinlock_t lock; /* Serialize access to this structure. */
89 int count; /* Number of pages allocated. */ 95 int count; /* Number of pages allocated. */
90 int type; /* Type of pages allocated. */ 96 enum mspec_page_type type; /* Type of pages allocated. */
97 int flags; /* See VMD_xxx below. */
98 unsigned long vm_start; /* Original (unsplit) base. */
99 unsigned long vm_end; /* Original (unsplit) end. */
91 unsigned long maddr[0]; /* Array of MSPEC addresses. */ 100 unsigned long maddr[0]; /* Array of MSPEC addresses. */
92}; 101};
93 102
103#define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */
104
94/* used on shub2 to clear FOP cache in the HUB */ 105/* used on shub2 to clear FOP cache in the HUB */
95static unsigned long scratch_page[MAX_NUMNODES]; 106static unsigned long scratch_page[MAX_NUMNODES];
96#define SH2_AMO_CACHE_ENTRIES 4 107#define SH2_AMO_CACHE_ENTRIES 4
@@ -128,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len)
128 * mspec_open 139 * mspec_open
129 * 140 *
130 * Called when a device mapping is created by a means other than mmap 141 * Called when a device mapping is created by a means other than mmap
131 * (via fork, etc.). Increments the reference count on the underlying 142 * (via fork, munmap, etc.). Increments the reference count on the
132 * mspec data so it is not freed prematurely. 143 * underlying mspec data so it is not freed prematurely.
133 */ 144 */
134static void 145static void
135mspec_open(struct vm_area_struct *vma) 146mspec_open(struct vm_area_struct *vma)
@@ -144,43 +155,43 @@ mspec_open(struct vm_area_struct *vma)
144 * mspec_close 155 * mspec_close
145 * 156 *
146 * Called when unmapping a device mapping. Frees all mspec pages 157 * Called when unmapping a device mapping. Frees all mspec pages
147 * belonging to the vma. 158 * belonging to all the vma's sharing this vma_data structure.
148 */ 159 */
149static void 160static void
150mspec_close(struct vm_area_struct *vma) 161mspec_close(struct vm_area_struct *vma)
151{ 162{
152 struct vma_data *vdata; 163 struct vma_data *vdata;
153 int i, pages, result, vdata_size; 164 int index, last_index;
165 unsigned long my_page;
154 166
155 vdata = vma->vm_private_data; 167 vdata = vma->vm_private_data;
168
156 if (!atomic_dec_and_test(&vdata->refcnt)) 169 if (!atomic_dec_and_test(&vdata->refcnt))
157 return; 170 return;
158 171
159 pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 172 last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT;
160 vdata_size = sizeof(struct vma_data) + pages * sizeof(long); 173 for (index = 0; index < last_index; index++) {
161 for (i = 0; i < pages; i++) { 174 if (vdata->maddr[index] == 0)
162 if (vdata->maddr[i] == 0)
163 continue; 175 continue;
164 /* 176 /*
165 * Clear the page before sticking it back 177 * Clear the page before sticking it back
166 * into the pool. 178 * into the pool.
167 */ 179 */
168 result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE); 180 my_page = vdata->maddr[index];
169 if (!result) 181 vdata->maddr[index] = 0;
170 uncached_free_page(vdata->maddr[i]); 182 if (!mspec_zero_block(my_page, PAGE_SIZE))
183 uncached_free_page(my_page);
171 else 184 else
172 printk(KERN_WARNING "mspec_close(): " 185 printk(KERN_WARNING "mspec_close(): "
173 "failed to zero page %i\n", 186 "failed to zero page %ld\n", my_page);
174 result);
175 } 187 }
176 188
177 if (vdata_size <= PAGE_SIZE) 189 if (vdata->flags & VMD_VMALLOCED)
178 kfree(vdata);
179 else
180 vfree(vdata); 190 vfree(vdata);
191 else
192 kfree(vdata);
181} 193}
182 194
183
184/* 195/*
185 * mspec_nopfn 196 * mspec_nopfn
186 * 197 *
@@ -194,7 +205,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
194 int index; 205 int index;
195 struct vma_data *vdata = vma->vm_private_data; 206 struct vma_data *vdata = vma->vm_private_data;
196 207
197 index = (address - vma->vm_start) >> PAGE_SHIFT; 208 BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
209 index = (address - vdata->vm_start) >> PAGE_SHIFT;
198 maddr = (volatile unsigned long) vdata->maddr[index]; 210 maddr = (volatile unsigned long) vdata->maddr[index];
199 if (maddr == 0) { 211 if (maddr == 0) {
200 maddr = uncached_alloc_page(numa_node_id()); 212 maddr = uncached_alloc_page(numa_node_id());
@@ -236,10 +248,11 @@ static struct vm_operations_struct mspec_vm_ops = {
236 * underlying pages. 248 * underlying pages.
237 */ 249 */
238static int 250static int
239mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) 251mspec_mmap(struct file *file, struct vm_area_struct *vma,
252 enum mspec_page_type type)
240{ 253{
241 struct vma_data *vdata; 254 struct vma_data *vdata;
242 int pages, vdata_size; 255 int pages, vdata_size, flags = 0;
243 256
244 if (vma->vm_pgoff != 0) 257 if (vma->vm_pgoff != 0)
245 return -EINVAL; 258 return -EINVAL;
@@ -254,12 +267,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
254 vdata_size = sizeof(struct vma_data) + pages * sizeof(long); 267 vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
255 if (vdata_size <= PAGE_SIZE) 268 if (vdata_size <= PAGE_SIZE)
256 vdata = kmalloc(vdata_size, GFP_KERNEL); 269 vdata = kmalloc(vdata_size, GFP_KERNEL);
257 else 270 else {
258 vdata = vmalloc(vdata_size); 271 vdata = vmalloc(vdata_size);
272 flags = VMD_VMALLOCED;
273 }
259 if (!vdata) 274 if (!vdata)
260 return -ENOMEM; 275 return -ENOMEM;
261 memset(vdata, 0, vdata_size); 276 memset(vdata, 0, vdata_size);
262 277
278 vdata->vm_start = vma->vm_start;
279 vdata->vm_end = vma->vm_end;
280 vdata->flags = flags;
263 vdata->type = type; 281 vdata->type = type;
264 spin_lock_init(&vdata->lock); 282 spin_lock_init(&vdata->lock);
265 vdata->refcnt = ATOMIC_INIT(1); 283 vdata->refcnt = ATOMIC_INIT(1);
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index fee58e03dbe2..cc5d77797def 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1629,7 +1629,7 @@ static int cmm_open(struct inode *inode, struct file *filp)
1629{ 1629{
1630 struct cm4000_dev *dev; 1630 struct cm4000_dev *dev;
1631 struct pcmcia_device *link; 1631 struct pcmcia_device *link;
1632 int rc, minor = iminor(inode); 1632 int minor = iminor(inode);
1633 1633
1634 if (minor >= CM4000_MAX_DEV) 1634 if (minor >= CM4000_MAX_DEV)
1635 return -ENODEV; 1635 return -ENODEV;
@@ -1668,7 +1668,6 @@ static int cmm_open(struct inode *inode, struct file *filp)
1668 start_monitor(dev); 1668 start_monitor(dev);
1669 1669
1670 link->open = 1; /* only one open per device */ 1670 link->open = 1; /* only one open per device */
1671 rc = 0;
1672 1671
1673 DEBUGP(2, dev, "<- cmm_open\n"); 1672 DEBUGP(2, dev, "<- cmm_open\n");
1674 return nonseekable_open(inode, filp); 1673 return nonseekable_open(inode, filp);
@@ -1824,7 +1823,7 @@ static int cm4000_resume(struct pcmcia_device *link)
1824 1823
1825static void cm4000_release(struct pcmcia_device *link) 1824static void cm4000_release(struct pcmcia_device *link)
1826{ 1825{
1827 cmm_cm4000_release(link->priv); /* delay release until device closed */ 1826 cmm_cm4000_release(link); /* delay release until device closed */
1828 pcmcia_disable_device(link); 1827 pcmcia_disable_device(link);
1829} 1828}
1830 1829
@@ -1864,8 +1863,7 @@ static int cm4000_probe(struct pcmcia_device *link)
1864 return ret; 1863 return ret;
1865 } 1864 }
1866 1865
1867 class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, 1866 device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i);
1868 "cmm%d", i);
1869 1867
1870 return 0; 1868 return 0;
1871} 1869}
@@ -1889,7 +1887,7 @@ static void cm4000_detach(struct pcmcia_device *link)
1889 dev_table[devno] = NULL; 1887 dev_table[devno] = NULL;
1890 kfree(dev); 1888 kfree(dev);
1891 1889
1892 class_device_destroy(cmm_class, MKDEV(major, devno)); 1890 device_destroy(cmm_class, MKDEV(major, devno));
1893 1891
1894 return; 1892 return;
1895} 1893}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index af88181a17f4..a0b9c8728d56 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -599,7 +599,7 @@ cs_release:
599 599
600static void reader_release(struct pcmcia_device *link) 600static void reader_release(struct pcmcia_device *link)
601{ 601{
602 cm4040_reader_release(link->priv); 602 cm4040_reader_release(link);
603 pcmcia_disable_device(link); 603 pcmcia_disable_device(link);
604} 604}
605 605
@@ -642,8 +642,7 @@ static int reader_probe(struct pcmcia_device *link)
642 return ret; 642 return ret;
643 } 643 }
644 644
645 class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, 645 device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i);
646 "cmx%d", i);
647 646
648 return 0; 647 return 0;
649} 648}
@@ -666,7 +665,7 @@ static void reader_detach(struct pcmcia_device *link)
666 dev_table[devno] = NULL; 665 dev_table[devno] = NULL;
667 kfree(dev); 666 kfree(dev);
668 667
669 class_device_destroy(cmx_class, MKDEV(major, devno)); 668 device_destroy(cmx_class, MKDEV(major, devno));
670 669
671 return; 670 return;
672} 671}
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 13808f6083a0..2b889317461e 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -540,13 +540,12 @@ static int mgslpc_probe(struct pcmcia_device *link)
540 if (debug_level >= DEBUG_LEVEL_INFO) 540 if (debug_level >= DEBUG_LEVEL_INFO)
541 printk("mgslpc_attach\n"); 541 printk("mgslpc_attach\n");
542 542
543 info = kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); 543 info = kzalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
544 if (!info) { 544 if (!info) {
545 printk("Error can't allocate device instance data\n"); 545 printk("Error can't allocate device instance data\n");
546 return -ENOMEM; 546 return -ENOMEM;
547 } 547 }
548 548
549 memset(info, 0, sizeof(MGSLPC_INFO));
550 info->magic = MGSLPC_MAGIC; 549 info->magic = MGSLPC_MAGIC;
551 INIT_WORK(&info->task, bh_handler); 550 INIT_WORK(&info->task, bh_handler);
552 info->max_frame_size = 4096; 551 info->max_frame_size = 4096;
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
new file mode 100644
index 000000000000..79b6f461be75
--- /dev/null
+++ b/drivers/char/ps3flash.c
@@ -0,0 +1,440 @@
1/*
2 * PS3 FLASH ROM Storage Driver
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/fs.h>
22#include <linux/miscdevice.h>
23#include <linux/uaccess.h>
24
25#include <asm/lv1call.h>
26#include <asm/ps3stor.h>
27
28
29#define DEVICE_NAME "ps3flash"
30
31#define FLASH_BLOCK_SIZE (256*1024)
32
33
34struct ps3flash_private {
35 struct mutex mutex; /* Bounce buffer mutex */
36};
37
38static struct ps3_storage_device *ps3flash_dev;
39
40static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev,
41 u64 lpar, u64 start_sector,
42 u64 sectors, int write)
43{
44 u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors,
45 write);
46 if (res) {
47 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
48 __LINE__, write ? "write" : "read", res);
49 return -EIO;
50 }
51 return sectors;
52}
53
54static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev,
55 u64 start_sector, u64 sectors,
56 unsigned int sector_offset)
57{
58 u64 max_sectors, lpar;
59
60 max_sectors = dev->bounce_size / dev->blk_size;
61 if (sectors > max_sectors) {
62 dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n",
63 __func__, __LINE__, max_sectors);
64 sectors = max_sectors;
65 }
66
67 lpar = dev->bounce_lpar + sector_offset * dev->blk_size;
68 return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors,
69 0);
70}
71
72static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev,
73 u64 start_sector)
74{
75 u64 sectors = dev->bounce_size / dev->blk_size;
76 return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector,
77 sectors, 1);
78}
79
80static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
81{
82 struct ps3_storage_device *dev = ps3flash_dev;
83 loff_t res;
84
85 mutex_lock(&file->f_mapping->host->i_mutex);
86 switch (origin) {
87 case 1:
88 offset += file->f_pos;
89 break;
90 case 2:
91 offset += dev->regions[dev->region_idx].size*dev->blk_size;
92 break;
93 }
94 if (offset < 0) {
95 res = -EINVAL;
96 goto out;
97 }
98
99 file->f_pos = offset;
100 res = file->f_pos;
101
102out:
103 mutex_unlock(&file->f_mapping->host->i_mutex);
104 return res;
105}
106
107static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
108 loff_t *pos)
109{
110 struct ps3_storage_device *dev = ps3flash_dev;
111 struct ps3flash_private *priv = dev->sbd.core.driver_data;
112 u64 size, start_sector, end_sector, offset;
113 ssize_t sectors_read;
114 size_t remaining, n;
115
116 dev_dbg(&dev->sbd.core,
117 "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n",
118 __func__, __LINE__, count, *pos, buf);
119
120 size = dev->regions[dev->region_idx].size*dev->blk_size;
121 if (*pos >= size || !count)
122 return 0;
123
124 if (*pos + count > size) {
125 dev_dbg(&dev->sbd.core,
126 "%s:%u Truncating count from %zu to %llu\n", __func__,
127 __LINE__, count, size - *pos);
128 count = size - *pos;
129 }
130
131 start_sector = *pos / dev->blk_size;
132 offset = *pos % dev->blk_size;
133 end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
134
135 remaining = count;
136 do {
137 mutex_lock(&priv->mutex);
138
139 sectors_read = ps3flash_read_sectors(dev, start_sector,
140 end_sector-start_sector,
141 0);
142 if (sectors_read < 0) {
143 mutex_unlock(&priv->mutex);
144 goto fail;
145 }
146
147 n = min(remaining, sectors_read*dev->blk_size-offset);
148 dev_dbg(&dev->sbd.core,
149 "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n",
150 __func__, __LINE__, n, dev->bounce_buf+offset, buf);
151 if (copy_to_user(buf, dev->bounce_buf+offset, n)) {
152 mutex_unlock(&priv->mutex);
153 sectors_read = -EFAULT;
154 goto fail;
155 }
156
157 mutex_unlock(&priv->mutex);
158
159 *pos += n;
160 buf += n;
161 remaining -= n;
162 start_sector += sectors_read;
163 offset = 0;
164 } while (remaining > 0);
165
166 return count;
167
168fail:
169 return sectors_read;
170}
171
172static ssize_t ps3flash_write(struct file *file, const char __user *buf,
173 size_t count, loff_t *pos)
174{
175 struct ps3_storage_device *dev = ps3flash_dev;
176 struct ps3flash_private *priv = dev->sbd.core.driver_data;
177 u64 size, chunk_sectors, start_write_sector, end_write_sector,
178 end_read_sector, start_read_sector, head, tail, offset;
179 ssize_t res;
180 size_t remaining, n;
181 unsigned int sec_off;
182
183 dev_dbg(&dev->sbd.core,
184 "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n",
185 __func__, __LINE__, count, *pos, buf);
186
187 size = dev->regions[dev->region_idx].size*dev->blk_size;
188 if (*pos >= size || !count)
189 return 0;
190
191 if (*pos + count > size) {
192 dev_dbg(&dev->sbd.core,
193 "%s:%u Truncating count from %zu to %llu\n", __func__,
194 __LINE__, count, size - *pos);
195 count = size - *pos;
196 }
197
198 chunk_sectors = dev->bounce_size / dev->blk_size;
199
200 start_write_sector = *pos / dev->bounce_size * chunk_sectors;
201 offset = *pos % dev->bounce_size;
202 end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
203 chunk_sectors;
204
205 end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
206 start_read_sector = (*pos + count) / dev->blk_size;
207
208 /*
209 * As we have to write in 256 KiB chunks, while we can read in blk_size
210 * (usually 512 bytes) chunks, we perform the following steps:
211 * 1. Read from start_write_sector to end_read_sector ("head")
212 * 2. Read from start_read_sector to end_write_sector ("tail")
213 * 3. Copy data to buffer
214 * 4. Write from start_write_sector to end_write_sector
215 * All of this is complicated by using only one 256 KiB bounce buffer.
216 */
217
218 head = end_read_sector - start_write_sector;
219 tail = end_write_sector - start_read_sector;
220
221 remaining = count;
222 do {
223 mutex_lock(&priv->mutex);
224
225 if (end_read_sector >= start_read_sector) {
226 /* Merge head and tail */
227 dev_dbg(&dev->sbd.core,
228 "Merged head and tail: %lu sectors at %lu\n",
229 chunk_sectors, start_write_sector);
230 res = ps3flash_read_sectors(dev, start_write_sector,
231 chunk_sectors, 0);
232 if (res < 0)
233 goto fail;
234 } else {
235 if (head) {
236 /* Read head */
237 dev_dbg(&dev->sbd.core,
238 "head: %lu sectors at %lu\n", head,
239 start_write_sector);
240 res = ps3flash_read_sectors(dev,
241 start_write_sector,
242 head, 0);
243 if (res < 0)
244 goto fail;
245 }
246 if (start_read_sector <
247 start_write_sector+chunk_sectors) {
248 /* Read tail */
249 dev_dbg(&dev->sbd.core,
250 "tail: %lu sectors at %lu\n", tail,
251 start_read_sector);
252 sec_off = start_read_sector-start_write_sector;
253 res = ps3flash_read_sectors(dev,
254 start_read_sector,
255 tail, sec_off);
256 if (res < 0)
257 goto fail;
258 }
259 }
260
261 n = min(remaining, dev->bounce_size-offset);
262 dev_dbg(&dev->sbd.core,
263 "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
264 __func__, __LINE__, n, buf, dev->bounce_buf+offset);
265 if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
266 res = -EFAULT;
267 goto fail;
268 }
269
270 res = ps3flash_write_chunk(dev, start_write_sector);
271 if (res < 0)
272 goto fail;
273
274 mutex_unlock(&priv->mutex);
275
276 *pos += n;
277 buf += n;
278 remaining -= n;
279 start_write_sector += chunk_sectors;
280 head = 0;
281 offset = 0;
282 } while (remaining > 0);
283
284 return count;
285
286fail:
287 mutex_unlock(&priv->mutex);
288 return res;
289}
290
291
292static irqreturn_t ps3flash_interrupt(int irq, void *data)
293{
294 struct ps3_storage_device *dev = data;
295 int res;
296 u64 tag, status;
297
298 res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
299
300 if (tag != dev->tag)
301 dev_err(&dev->sbd.core,
302 "%s:%u: tag mismatch, got %lx, expected %lx\n",
303 __func__, __LINE__, tag, dev->tag);
304
305 if (res) {
306 dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
307 __func__, __LINE__, res, status);
308 } else {
309 dev->lv1_status = status;
310 complete(&dev->done);
311 }
312 return IRQ_HANDLED;
313}
314
315
316static const struct file_operations ps3flash_fops = {
317 .owner = THIS_MODULE,
318 .llseek = ps3flash_llseek,
319 .read = ps3flash_read,
320 .write = ps3flash_write,
321};
322
323static struct miscdevice ps3flash_misc = {
324 .minor = MISC_DYNAMIC_MINOR,
325 .name = DEVICE_NAME,
326 .fops = &ps3flash_fops,
327};
328
329static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
330{
331 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
332 struct ps3flash_private *priv;
333 int error;
334 unsigned long tmp;
335
336 tmp = dev->regions[dev->region_idx].start*dev->blk_size;
337 if (tmp % FLASH_BLOCK_SIZE) {
338 dev_err(&dev->sbd.core,
339 "%s:%u region start %lu is not aligned\n", __func__,
340 __LINE__, tmp);
341 return -EINVAL;
342 }
343 tmp = dev->regions[dev->region_idx].size*dev->blk_size;
344 if (tmp % FLASH_BLOCK_SIZE) {
345 dev_err(&dev->sbd.core,
346 "%s:%u region size %lu is not aligned\n", __func__,
347 __LINE__, tmp);
348 return -EINVAL;
349 }
350
351 /* use static buffer, kmalloc cannot allocate 256 KiB */
352 if (!ps3flash_bounce_buffer.address)
353 return -ENODEV;
354
355 if (ps3flash_dev) {
356 dev_err(&dev->sbd.core,
357 "Only one FLASH device is supported\n");
358 return -EBUSY;
359 }
360
361 ps3flash_dev = dev;
362
363 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
364 if (!priv) {
365 error = -ENOMEM;
366 goto fail;
367 }
368
369 dev->sbd.core.driver_data = priv;
370 mutex_init(&priv->mutex);
371
372 dev->bounce_size = ps3flash_bounce_buffer.size;
373 dev->bounce_buf = ps3flash_bounce_buffer.address;
374
375 error = ps3stor_setup(dev, ps3flash_interrupt);
376 if (error)
377 goto fail_free_priv;
378
379 ps3flash_misc.parent = &dev->sbd.core;
380 error = misc_register(&ps3flash_misc);
381 if (error) {
382 dev_err(&dev->sbd.core, "%s:%u: misc_register failed %d\n",
383 __func__, __LINE__, error);
384 goto fail_teardown;
385 }
386
387 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
388 __func__, __LINE__, ps3flash_misc.minor);
389 return 0;
390
391fail_teardown:
392 ps3stor_teardown(dev);
393fail_free_priv:
394 kfree(priv);
395 dev->sbd.core.driver_data = NULL;
396fail:
397 ps3flash_dev = NULL;
398 return error;
399}
400
401static int ps3flash_remove(struct ps3_system_bus_device *_dev)
402{
403 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
404
405 misc_deregister(&ps3flash_misc);
406 ps3stor_teardown(dev);
407 kfree(dev->sbd.core.driver_data);
408 dev->sbd.core.driver_data = NULL;
409 ps3flash_dev = NULL;
410 return 0;
411}
412
413
414static struct ps3_system_bus_driver ps3flash = {
415 .match_id = PS3_MATCH_ID_STOR_FLASH,
416 .core.name = DEVICE_NAME,
417 .core.owner = THIS_MODULE,
418 .probe = ps3flash_probe,
419 .remove = ps3flash_remove,
420 .shutdown = ps3flash_remove,
421};
422
423
424static int __init ps3flash_init(void)
425{
426 return ps3_system_bus_driver_register(&ps3flash);
427}
428
429static void __exit ps3flash_exit(void)
430{
431 ps3_system_bus_driver_unregister(&ps3flash);
432}
433
434module_init(ps3flash_init);
435module_exit(ps3flash_exit);
436
437MODULE_LICENSE("GPL");
438MODULE_DESCRIPTION("PS3 FLASH ROM Storage Driver");
439MODULE_AUTHOR("Sony Corporation");
440MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH);
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index de14aea34e11..73de77105fea 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -248,14 +248,19 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
248 return -ENOIOCTLCMD; 248 return -ENOIOCTLCMD;
249} 249}
250 250
251static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
252module_param(legacy_count, int, 0);
253
251static void __init legacy_pty_init(void) 254static void __init legacy_pty_init(void)
252{ 255{
256 if (legacy_count <= 0)
257 return;
253 258
254 pty_driver = alloc_tty_driver(NR_PTYS); 259 pty_driver = alloc_tty_driver(legacy_count);
255 if (!pty_driver) 260 if (!pty_driver)
256 panic("Couldn't allocate pty driver"); 261 panic("Couldn't allocate pty driver");
257 262
258 pty_slave_driver = alloc_tty_driver(NR_PTYS); 263 pty_slave_driver = alloc_tty_driver(legacy_count);
259 if (!pty_slave_driver) 264 if (!pty_slave_driver)
260 panic("Couldn't allocate pty slave driver"); 265 panic("Couldn't allocate pty slave driver");
261 266
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7f5271272f91..af274e5a25ee 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -693,9 +693,14 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
693 693
694 if (r->pull && r->entropy_count < nbytes * 8 && 694 if (r->pull && r->entropy_count < nbytes * 8 &&
695 r->entropy_count < r->poolinfo->POOLBITS) { 695 r->entropy_count < r->poolinfo->POOLBITS) {
696 int bytes = max_t(int, random_read_wakeup_thresh / 8, 696 /* If we're limited, always leave two wakeup worth's BITS */
697 min_t(int, nbytes, sizeof(tmp)));
698 int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; 697 int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
698 int bytes = nbytes;
699
700 /* pull at least as many as BYTES as wakeup BITS */
701 bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
702 /* but never more than the buffer size */
703 bytes = min_t(int, bytes, sizeof(tmp));
699 704
700 DEBUG_ENT("going to reseed %s with %d bits " 705 DEBUG_ENT("going to reseed %s with %d bits "
701 "(%d of %d requested)\n", 706 "(%d of %d requested)\n",
@@ -1545,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
1545 * As close as possible to RFC 793, which 1550 * As close as possible to RFC 793, which
1546 * suggests using a 250 kHz clock. 1551 * suggests using a 250 kHz clock.
1547 * Further reading shows this assumes 2 Mb/s networks. 1552 * Further reading shows this assumes 2 Mb/s networks.
1548 * For 10 Gb/s Ethernet, a 1 GHz clock is appropriate. 1553 * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
1549 * That's funny, Linux has one built in! Use it! 1554 * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
1550 * (Networks are faster now - should this be increased?) 1555 * we also need to limit the resolution so that the u32 seq
1556 * overlaps less than one time per MSL (2 minutes).
1557 * Choosing a clock of 64 ns period is OK. (period of 274 s)
1551 */ 1558 */
1552 seq += ktime_get_real().tv64; 1559 seq += ktime_get_real().tv64 >> 6;
1553#if 0 1560#if 0
1554 printk("init_seq(%lx, %lx, %d, %d) = %d\n", 1561 printk("init_seq(%lx, %lx, %d, %d) = %d\n",
1555 saddr, daddr, sport, dport, seq); 1562 saddr, daddr, sport, dport, seq);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 1f0d7c60c944..bbfa0e241cba 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -255,10 +255,7 @@ static const struct file_operations raw_ctl_fops = {
255 .owner = THIS_MODULE, 255 .owner = THIS_MODULE,
256}; 256};
257 257
258static struct cdev raw_cdev = { 258static struct cdev raw_cdev;
259 .kobj = {.name = "raw", },
260 .owner = THIS_MODULE,
261};
262 259
263static int __init raw_init(void) 260static int __init raw_init(void)
264{ 261{
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 294e9cb0c449..0ce96670f979 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -803,9 +803,7 @@ static void *ckmalloc(int size)
803{ 803{
804 void *p; 804 void *p;
805 805
806 p = kmalloc(size, GFP_KERNEL); 806 p = kzalloc(size, GFP_KERNEL);
807 if (p)
808 memset(p, 0, size);
809 return p; 807 return p;
810} 808}
811 809
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 8cc60b693460..7321d002c34f 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -556,9 +556,7 @@ struct CmdBlk *RIOGetCmdBlk(void)
556{ 556{
557 struct CmdBlk *CmdBlkP; 557 struct CmdBlk *CmdBlkP;
558 558
559 CmdBlkP = kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC); 559 CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
560 if (CmdBlkP)
561 memset(CmdBlkP, 0, sizeof(struct CmdBlk));
562 return CmdBlkP; 560 return CmdBlkP;
563} 561}
564 562
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index 7e988357326e..991119c9f473 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -863,8 +863,7 @@ int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
863 if (PortP->TxRingBuffer) 863 if (PortP->TxRingBuffer)
864 memset(PortP->TxRingBuffer, 0, p->RIOBufferSize); 864 memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
865 else if (p->RIOBufferSize) { 865 else if (p->RIOBufferSize) {
866 PortP->TxRingBuffer = kmalloc(p->RIOBufferSize, GFP_KERNEL); 866 PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL);
867 memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
868 } 867 }
869 PortP->TxBufferOut = 0; 868 PortP->TxBufferOut = 0;
870 PortP->TxBufferIn = 0; 869 PortP->TxBufferIn = 0;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 0270080ff0c0..56cbba7b6ec0 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -635,12 +635,11 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
635 ctlp = sCtlNumToCtlPtr(board); 635 ctlp = sCtlNumToCtlPtr(board);
636 636
637 /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */ 637 /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
638 info = kmalloc(sizeof (struct r_port), GFP_KERNEL); 638 info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
639 if (!info) { 639 if (!info) {
640 printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line); 640 printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line);
641 return; 641 return;
642 } 642 }
643 memset(info, 0, sizeof (struct r_port));
644 643
645 info->magic = RPORT_MAGIC; 644 info->magic = RPORT_MAGIC;
646 info->line = line; 645 info->line = line;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 22cf7aa56cc4..ec6b65ec69ea 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -82,16 +82,13 @@
82#include <asm/uaccess.h> 82#include <asm/uaccess.h>
83#include <asm/system.h> 83#include <asm/system.h>
84 84
85#if defined(__i386__) 85#ifdef CONFIG_X86
86#include <asm/hpet.h> 86#include <asm/hpet.h>
87#endif 87#endif
88 88
89#ifdef __sparc__ 89#ifdef CONFIG_SPARC32
90#include <linux/pci.h> 90#include <linux/pci.h>
91#include <asm/ebus.h> 91#include <asm/ebus.h>
92#ifdef __sparc_v9__
93#include <asm/isa.h>
94#endif
95 92
96static unsigned long rtc_port; 93static unsigned long rtc_port;
97static int rtc_irq = PCI_IRQ_NONE; 94static int rtc_irq = PCI_IRQ_NONE;
@@ -930,13 +927,9 @@ static int __init rtc_init(void)
930 unsigned int year, ctrl; 927 unsigned int year, ctrl;
931 char *guess = NULL; 928 char *guess = NULL;
932#endif 929#endif
933#ifdef __sparc__ 930#ifdef CONFIG_SPARC32
934 struct linux_ebus *ebus; 931 struct linux_ebus *ebus;
935 struct linux_ebus_device *edev; 932 struct linux_ebus_device *edev;
936#ifdef __sparc_v9__
937 struct sparc_isa_bridge *isa_br;
938 struct sparc_isa_device *isa_dev;
939#endif
940#else 933#else
941 void *r; 934 void *r;
942#ifdef RTC_IRQ 935#ifdef RTC_IRQ
@@ -944,7 +937,7 @@ static int __init rtc_init(void)
944#endif 937#endif
945#endif 938#endif
946 939
947#ifdef __sparc__ 940#ifdef CONFIG_SPARC32
948 for_each_ebus(ebus) { 941 for_each_ebus(ebus) {
949 for_each_ebusdev(edev, ebus) { 942 for_each_ebusdev(edev, ebus) {
950 if(strcmp(edev->prom_node->name, "rtc") == 0) { 943 if(strcmp(edev->prom_node->name, "rtc") == 0) {
@@ -954,17 +947,6 @@ static int __init rtc_init(void)
954 } 947 }
955 } 948 }
956 } 949 }
957#ifdef __sparc_v9__
958 for_each_isa(isa_br) {
959 for_each_isadev(isa_dev, isa_br) {
960 if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
961 rtc_port = isa_dev->resource.start;
962 rtc_irq = isa_dev->irq;
963 goto found;
964 }
965 }
966 }
967#endif
968 rtc_has_irq = 0; 950 rtc_has_irq = 0;
969 printk(KERN_ERR "rtc_init: no PC rtc found\n"); 951 printk(KERN_ERR "rtc_init: no PC rtc found\n");
970 return -EIO; 952 return -EIO;
@@ -1020,7 +1002,7 @@ no_irq:
1020 1002
1021#endif 1003#endif
1022 1004
1023#endif /* __sparc__ vs. others */ 1005#endif /* CONFIG_SPARC32 vs. others */
1024 1006
1025 if (misc_register(&rtc_dev)) { 1007 if (misc_register(&rtc_dev)) {
1026#ifdef RTC_IRQ 1008#ifdef RTC_IRQ
@@ -1105,7 +1087,7 @@ static void __exit rtc_exit (void)
1105 remove_proc_entry ("driver/rtc", NULL); 1087 remove_proc_entry ("driver/rtc", NULL);
1106 misc_deregister(&rtc_dev); 1088 misc_deregister(&rtc_dev);
1107 1089
1108#ifdef __sparc__ 1090#ifdef CONFIG_SPARC32
1109 if (rtc_has_irq) 1091 if (rtc_has_irq)
1110 free_irq (rtc_irq, &rtc_port); 1092 free_irq (rtc_irq, &rtc_port);
1111#else 1093#else
@@ -1117,7 +1099,7 @@ static void __exit rtc_exit (void)
1117 if (rtc_has_irq) 1099 if (rtc_has_irq)
1118 free_irq (RTC_IRQ, NULL); 1100 free_irq (RTC_IRQ, NULL);
1119#endif 1101#endif
1120#endif /* __sparc__ */ 1102#endif /* CONFIG_SPARC32 */
1121} 1103}
1122 1104
1123module_init(rtc_init); 1105module_init(rtc_init);
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index c585b4738f86..f1497cecffd8 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -2573,16 +2573,10 @@ static struct tty_driver *serial167_console_device(struct console *c,
2573 return cy_serial_driver; 2573 return cy_serial_driver;
2574} 2574}
2575 2575
2576static int __init serial167_console_setup(struct console *co, char *options)
2577{
2578 return 0;
2579}
2580
2581static struct console sercons = { 2576static struct console sercons = {
2582 .name = "ttyS", 2577 .name = "ttyS",
2583 .write = serial167_console_write, 2578 .write = serial167_console_write,
2584 .device = serial167_console_device, 2579 .device = serial167_console_device,
2585 .setup = serial167_console_setup,
2586 .flags = CON_PRINTBUFFER, 2580 .flags = CON_PRINTBUFFER,
2587 .index = -1, 2581 .index = -1,
2588}; 2582};
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 52753e723eaa..b9c1dba6bd01 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -441,8 +441,7 @@ scdrv_init(void)
441 continue; 441 continue;
442 } 442 }
443 443
444 class_device_create(snsc_class, NULL, dev, NULL, 444 device_create(snsc_class, NULL, dev, "%s", devname);
445 "%s", devname);
446 445
447 ia64_sn_irtr_intr_enable(scd->scd_nasid, 446 ia64_sn_irtr_intr_enable(scd->scd_nasid,
448 0 /*ignored */ , 447 0 /*ignored */ ,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 73037a4d3c50..859858561ab6 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -875,7 +875,7 @@ found:
875 875
876#ifdef CONFIG_ACPI 876#ifdef CONFIG_ACPI
877 if (sonypi_acpi_device) 877 if (sonypi_acpi_device)
878 acpi_bus_generate_event(sonypi_acpi_device, 1, event); 878 acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
879#endif 879#endif
880 880
881 kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); 881 kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
@@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
1147 return 0; 1147 return 0;
1148} 1148}
1149 1149
1150const static struct acpi_device_id sonypi_device_ids[] = {
1151 {"SNY6001", 0},
1152 {"", 0},
1153};
1154
1150static struct acpi_driver sonypi_acpi_driver = { 1155static struct acpi_driver sonypi_acpi_driver = {
1151 .name = "sonypi", 1156 .name = "sonypi",
1152 .class = "hkey", 1157 .class = "hkey",
1153 .ids = "SNY6001", 1158 .ids = sonypi_device_ids,
1154 .ops = { 1159 .ops = {
1155 .add = sonypi_acpi_add, 1160 .add = sonypi_acpi_add,
1156 .remove = sonypi_acpi_remove, 1161 .remove = sonypi_acpi_remove,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 93d0bb8b4c0f..45758d5b56ef 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -4778,9 +4778,8 @@ static int __init stallion_module_init(void)
4778 if (IS_ERR(stallion_class)) 4778 if (IS_ERR(stallion_class))
4779 printk("STALLION: failed to create class\n"); 4779 printk("STALLION: failed to create class\n");
4780 for (i = 0; i < 4; i++) 4780 for (i = 0; i < 4; i++)
4781 class_device_create(stallion_class, NULL, 4781 device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
4782 MKDEV(STL_SIOMEMMAJOR, i), NULL, 4782 "staliomem%d", i);
4783 "staliomem%d", i);
4784 4783
4785 return 0; 4784 return 0;
4786err_unrtty: 4785err_unrtty:
@@ -4795,7 +4794,6 @@ static void __exit stallion_module_exit(void)
4795{ 4794{
4796 struct stlbrd *brdp; 4795 struct stlbrd *brdp;
4797 unsigned int i, j; 4796 unsigned int i, j;
4798 int retval;
4799 4797
4800 pr_debug("cleanup_module()\n"); 4798 pr_debug("cleanup_module()\n");
4801 4799
@@ -4817,10 +4815,8 @@ static void __exit stallion_module_exit(void)
4817 } 4815 }
4818 4816
4819 for (i = 0; i < 4; i++) 4817 for (i = 0; i < 4; i++)
4820 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); 4818 device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
4821 if ((retval = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) 4819 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4822 printk("STALLION: failed to un-register serial memory device, "
4823 "errno=%d\n", -retval);
4824 class_destroy(stallion_class); 4820 class_destroy(stallion_class);
4825 4821
4826 pci_unregister_driver(&stl_pcidriver); 4822 pci_unregister_driver(&stl_pcidriver);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index f53e51ddb9d7..fdc256b380b8 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4324,13 +4324,12 @@ static struct mgsl_struct* mgsl_allocate_device(void)
4324{ 4324{
4325 struct mgsl_struct *info; 4325 struct mgsl_struct *info;
4326 4326
4327 info = kmalloc(sizeof(struct mgsl_struct), 4327 info = kzalloc(sizeof(struct mgsl_struct),
4328 GFP_KERNEL); 4328 GFP_KERNEL);
4329 4329
4330 if (!info) { 4330 if (!info) {
4331 printk("Error can't allocate device instance data\n"); 4331 printk("Error can't allocate device instance data\n");
4332 } else { 4332 } else {
4333 memset(info, 0, sizeof(struct mgsl_struct));
4334 info->magic = MGSL_MAGIC; 4333 info->magic = MGSL_MAGIC;
4335 INIT_WORK(&info->task, mgsl_bh_handler); 4334 INIT_WORK(&info->task, mgsl_bh_handler);
4336 info->max_frame_size = 4096; 4335 info->max_frame_size = 4096;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 428b514201f4..2f97d2f8f916 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $ 2 * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $
3 * 3 *
4 * Device driver for Microgate SyncLink GT serial adapters. 4 * Device driver for Microgate SyncLink GT serial adapters.
5 * 5 *
@@ -93,7 +93,7 @@
93 * module identification 93 * module identification
94 */ 94 */
95static char *driver_name = "SyncLink GT"; 95static char *driver_name = "SyncLink GT";
96static char *driver_version = "$Revision: 4.36 $"; 96static char *driver_version = "$Revision: 4.50 $";
97static char *tty_driver_name = "synclink_gt"; 97static char *tty_driver_name = "synclink_gt";
98static char *tty_dev_prefix = "ttySLG"; 98static char *tty_dev_prefix = "ttySLG";
99MODULE_LICENSE("GPL"); 99MODULE_LICENSE("GPL");
@@ -477,6 +477,7 @@ static void tx_set_idle(struct slgt_info *info);
477static unsigned int free_tbuf_count(struct slgt_info *info); 477static unsigned int free_tbuf_count(struct slgt_info *info);
478static void reset_tbufs(struct slgt_info *info); 478static void reset_tbufs(struct slgt_info *info);
479static void tdma_reset(struct slgt_info *info); 479static void tdma_reset(struct slgt_info *info);
480static void tdma_start(struct slgt_info *info);
480static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); 481static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
481 482
482static void get_signals(struct slgt_info *info); 483static void get_signals(struct slgt_info *info);
@@ -904,6 +905,8 @@ start:
904 spin_lock_irqsave(&info->lock,flags); 905 spin_lock_irqsave(&info->lock,flags);
905 if (!info->tx_active) 906 if (!info->tx_active)
906 tx_start(info); 907 tx_start(info);
908 else
909 tdma_start(info);
907 spin_unlock_irqrestore(&info->lock,flags); 910 spin_unlock_irqrestore(&info->lock,flags);
908 } 911 }
909 912
@@ -1562,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev)
1562 int rc; 1565 int rc;
1563 unsigned long flags; 1566 unsigned long flags;
1564 1567
1568 if (!try_module_get(THIS_MODULE))
1569 return -EBUSY;
1570
1565 DBGINFO(("%s hdlcdev_open\n", dev->name)); 1571 DBGINFO(("%s hdlcdev_open\n", dev->name));
1566 1572
1567 /* generic HDLC layer open processing */ 1573 /* generic HDLC layer open processing */
@@ -1631,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev)
1631 info->netcount=0; 1637 info->netcount=0;
1632 spin_unlock_irqrestore(&info->netlock, flags); 1638 spin_unlock_irqrestore(&info->netlock, flags);
1633 1639
1640 module_put(THIS_MODULE);
1634 return 0; 1641 return 0;
1635} 1642}
1636 1643
@@ -3414,13 +3421,12 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
3414{ 3421{
3415 struct slgt_info *info; 3422 struct slgt_info *info;
3416 3423
3417 info = kmalloc(sizeof(struct slgt_info), GFP_KERNEL); 3424 info = kzalloc(sizeof(struct slgt_info), GFP_KERNEL);
3418 3425
3419 if (!info) { 3426 if (!info) {
3420 DBGERR(("%s device alloc failed adapter=%d port=%d\n", 3427 DBGERR(("%s device alloc failed adapter=%d port=%d\n",
3421 driver_name, adapter_num, port_num)); 3428 driver_name, adapter_num, port_num));
3422 } else { 3429 } else {
3423 memset(info, 0, sizeof(struct slgt_info));
3424 info->magic = MGSL_MAGIC; 3430 info->magic = MGSL_MAGIC;
3425 INIT_WORK(&info->task, bh_handler); 3431 INIT_WORK(&info->task, bh_handler);
3426 info->max_frame_size = 4096; 3432 info->max_frame_size = 4096;
@@ -3872,44 +3878,58 @@ static void tx_start(struct slgt_info *info)
3872 slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); 3878 slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
3873 /* clear tx idle and underrun status bits */ 3879 /* clear tx idle and underrun status bits */
3874 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); 3880 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
3875
3876 if (!(rd_reg32(info, TDCSR) & BIT0)) {
3877 /* tx DMA stopped, restart tx DMA */
3878 tdma_reset(info);
3879 /* set 1st descriptor address */
3880 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3881 switch(info->params.mode) {
3882 case MGSL_MODE_RAW:
3883 case MGSL_MODE_MONOSYNC:
3884 case MGSL_MODE_BISYNC:
3885 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
3886 break;
3887 default:
3888 wr_reg32(info, TDCSR, BIT0); /* DMA enable */
3889 }
3890 }
3891
3892 if (info->params.mode == MGSL_MODE_HDLC) 3881 if (info->params.mode == MGSL_MODE_HDLC)
3893 mod_timer(&info->tx_timer, jiffies + 3882 mod_timer(&info->tx_timer, jiffies +
3894 msecs_to_jiffies(5000)); 3883 msecs_to_jiffies(5000));
3895 } else { 3884 } else {
3896 tdma_reset(info);
3897 /* set 1st descriptor address */
3898 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3899
3900 slgt_irq_off(info, IRQ_TXDATA); 3885 slgt_irq_off(info, IRQ_TXDATA);
3901 slgt_irq_on(info, IRQ_TXIDLE); 3886 slgt_irq_on(info, IRQ_TXIDLE);
3902 /* clear tx idle status bit */ 3887 /* clear tx idle status bit */
3903 wr_reg16(info, SSR, IRQ_TXIDLE); 3888 wr_reg16(info, SSR, IRQ_TXIDLE);
3904
3905 /* enable tx DMA */
3906 wr_reg32(info, TDCSR, BIT0);
3907 } 3889 }
3908 3890 tdma_start(info);
3909 info->tx_active = 1; 3891 info->tx_active = 1;
3910 } 3892 }
3911} 3893}
3912 3894
3895/*
3896 * start transmit DMA if inactive and there are unsent buffers
3897 */
3898static void tdma_start(struct slgt_info *info)
3899{
3900 unsigned int i;
3901
3902 if (rd_reg32(info, TDCSR) & BIT0)
3903 return;
3904
3905 /* transmit DMA inactive, check for unsent buffers */
3906 i = info->tbuf_start;
3907 while (!desc_count(info->tbufs[i])) {
3908 if (++i == info->tbuf_count)
3909 i = 0;
3910 if (i == info->tbuf_current)
3911 return;
3912 }
3913 info->tbuf_start = i;
3914
3915 /* there are unsent buffers, start transmit DMA */
3916
3917 /* reset needed if previous error condition */
3918 tdma_reset(info);
3919
3920 /* set 1st descriptor address */
3921 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3922 switch(info->params.mode) {
3923 case MGSL_MODE_RAW:
3924 case MGSL_MODE_MONOSYNC:
3925 case MGSL_MODE_BISYNC:
3926 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
3927 break;
3928 default:
3929 wr_reg32(info, TDCSR, BIT0); /* DMA enable */
3930 }
3931}
3932
3913static void tx_stop(struct slgt_info *info) 3933static void tx_stop(struct slgt_info *info)
3914{ 3934{
3915 unsigned short val; 3935 unsigned short val;
@@ -4643,8 +4663,8 @@ static unsigned int free_tbuf_count(struct slgt_info *info)
4643 i=0; 4663 i=0;
4644 } while (i != info->tbuf_current); 4664 } while (i != info->tbuf_current);
4645 4665
4646 /* last buffer with zero count may be in use, assume it is */ 4666 /* if tx DMA active, last zero count buffer is in use */
4647 if (count) 4667 if (count && (rd_reg32(info, TDCSR) & BIT0))
4648 --count; 4668 --count;
4649 4669
4650 return count; 4670 return count;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index a65407b32079..c63013b2fc36 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -3786,14 +3786,13 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
3786{ 3786{
3787 SLMP_INFO *info; 3787 SLMP_INFO *info;
3788 3788
3789 info = kmalloc(sizeof(SLMP_INFO), 3789 info = kzalloc(sizeof(SLMP_INFO),
3790 GFP_KERNEL); 3790 GFP_KERNEL);
3791 3791
3792 if (!info) { 3792 if (!info) {
3793 printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n", 3793 printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n",
3794 __FILE__,__LINE__, adapter_num, port_num); 3794 __FILE__,__LINE__, adapter_num, port_num);
3795 } else { 3795 } else {
3796 memset(info, 0, sizeof(SLMP_INFO));
3797 info->magic = MGSL_MAGIC; 3796 info->magic = MGSL_MAGIC;
3798 INIT_WORK(&info->task, bh_handler); 3797 INIT_WORK(&info->task, bh_handler);
3799 info->max_frame_size = 4096; 3798 info->max_frame_size = 4096;
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 35b40b996534..cef55c40654f 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -441,8 +441,8 @@ tipar_register(int nr, struct parport *port)
441 goto out; 441 goto out;
442 } 442 }
443 443
444 class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, 444 device_create(tipar_class, port->dev, MKDEV(TIPAR_MAJOR,
445 TIPAR_MINOR + nr), port->dev, "par%d", nr); 445 TIPAR_MINOR + nr), "par%d", nr);
446 446
447 /* Display informations */ 447 /* Display informations */
448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == 448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
@@ -534,7 +534,7 @@ tipar_cleanup_module(void)
534 if (table[i].dev == NULL) 534 if (table[i].dev == NULL)
535 continue; 535 continue;
536 parport_unregister_device(table[i].dev); 536 parport_unregister_device(table[i].dev);
537 class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); 537 device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
538 } 538 }
539 class_destroy(tipar_class); 539 class_destroy(tipar_class);
540 540
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9bb542913b86..39564b76d4a3 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -7,7 +7,7 @@
7 * Reiner Sailer <sailer@watson.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com>
9 * 9 *
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 * 11 *
12 * Device driver for TCG/TCPA TPM (trusted platform module). 12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org 13 * Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index b2e2b002a1bb..d15ccddc92eb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -7,7 +7,7 @@
7 * Reiner Sailer <sailer@watson.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com>
9 * 9 *
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 * 11 *
12 * Device driver for TCG/TCPA TPM (trusted platform module). 12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org 13 * Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 1ab0896070be..d0e7926eb486 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -7,7 +7,7 @@
7 * Reiner Sailer <sailer@watson.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com>
9 * 9 *
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 * 11 *
12 * Device driver for TCG/TCPA TPM (trusted platform module). 12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org 13 * Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index 9363bcf0a402..6c831f9466b7 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -4,7 +4,7 @@
4 * Authors: 4 * Authors:
5 * Kylene Hall <kjhall@us.ibm.com> 5 * Kylene Hall <kjhall@us.ibm.com>
6 * 6 *
7 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 7 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
8 * 8 *
9 * Device driver for TCG/TCPA TPM (trusted platform module). 9 * Device driver for TCG/TCPA TPM (trusted platform module).
10 * Specifications at www.trustedcomputinggroup.org 10 * Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 4eba32b23b29..60a2d2630e36 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -7,6 +7,8 @@
7 * Reiner Sailer <sailer@watson.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com>
9 * 9 *
10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 *
10 * Access to the eventlog extended by the TCG BIOS of PC platform 12 * Access to the eventlog extended by the TCG BIOS of PC platform
11 * 13 *
12 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
@@ -427,7 +429,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
427 return -ENOMEM; 429 return -ENOMEM;
428 430
429 if ((err = read_log(log))) 431 if ((err = read_log(log)))
430 return err; 432 goto out_free;
431 433
432 /* now register seq file */ 434 /* now register seq file */
433 err = seq_open(file, &tpm_ascii_b_measurments_seqops); 435 err = seq_open(file, &tpm_ascii_b_measurments_seqops);
@@ -435,10 +437,15 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
435 seq = file->private_data; 437 seq = file->private_data;
436 seq->private = log; 438 seq->private = log;
437 } else { 439 } else {
438 kfree(log->bios_event_log); 440 goto out_free;
439 kfree(log);
440 } 441 }
442
443out:
441 return err; 444 return err;
445out_free:
446 kfree(log->bios_event_log);
447 kfree(log);
448 goto out;
442} 449}
443 450
444const struct file_operations tpm_ascii_bios_measurements_ops = { 451const struct file_operations tpm_ascii_bios_measurements_ops = {
@@ -460,7 +467,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
460 return -ENOMEM; 467 return -ENOMEM;
461 468
462 if ((err = read_log(log))) 469 if ((err = read_log(log)))
463 return err; 470 goto out_free;
464 471
465 /* now register seq file */ 472 /* now register seq file */
466 err = seq_open(file, &tpm_binary_b_measurments_seqops); 473 err = seq_open(file, &tpm_binary_b_measurments_seqops);
@@ -468,10 +475,15 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
468 seq = file->private_data; 475 seq = file->private_data;
469 seq->private = log; 476 seq->private = log;
470 } else { 477 } else {
471 kfree(log->bios_event_log); 478 goto out_free;
472 kfree(log);
473 } 479 }
480
481out:
474 return err; 482 return err;
483out_free:
484 kfree(log->bios_event_log);
485 kfree(log);
486 goto out;
475} 487}
476 488
477const struct file_operations tpm_binary_bios_measurements_ops = { 489const struct file_operations tpm_binary_bios_measurements_ops = {
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 608f73071bef..6313326bc41f 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -7,7 +7,7 @@
7 * Reiner Sailer <sailer@watson.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com>
9 * 9 *
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 * 11 *
12 * Device driver for TCG/TCPA TPM (trusted platform module). 12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org 13 * Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 483f3f60013c..23fa18a6654c 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -5,6 +5,8 @@
5 * Leendert van Doorn <leendert@watson.ibm.com> 5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com> 6 * Kylene Hall <kjhall@us.ibm.com>
7 * 7 *
8 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
9 *
8 * Device driver for TCG/TCPA TPM (trusted platform module). 10 * Device driver for TCG/TCPA TPM (trusted platform module).
9 * Specifications at www.trustedcomputinggroup.org 11 * Specifications at www.trustedcomputinggroup.org
10 * 12 *
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index de37ebc3a4cf..9c867cf6de64 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -369,25 +369,54 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
369} 369}
370 370
371/** 371/**
372 * tty_buffer_flush - flush full tty buffers 372 * __tty_buffer_flush - flush full tty buffers
373 * @tty: tty to flush 373 * @tty: tty to flush
374 * 374 *
375 * flush all the buffers containing receive data 375 * flush all the buffers containing receive data. Caller must
376 * hold the buffer lock and must have ensured no parallel flush to
377 * ldisc is running.
376 * 378 *
377 * Locking: none 379 * Locking: Caller must hold tty->buf.lock
378 */ 380 */
379 381
380static void tty_buffer_flush(struct tty_struct *tty) 382static void __tty_buffer_flush(struct tty_struct *tty)
381{ 383{
382 struct tty_buffer *thead; 384 struct tty_buffer *thead;
383 unsigned long flags;
384 385
385 spin_lock_irqsave(&tty->buf.lock, flags);
386 while((thead = tty->buf.head) != NULL) { 386 while((thead = tty->buf.head) != NULL) {
387 tty->buf.head = thead->next; 387 tty->buf.head = thead->next;
388 tty_buffer_free(tty, thead); 388 tty_buffer_free(tty, thead);
389 } 389 }
390 tty->buf.tail = NULL; 390 tty->buf.tail = NULL;
391}
392
393/**
394 * tty_buffer_flush - flush full tty buffers
395 * @tty: tty to flush
396 *
397 * flush all the buffers containing receive data. If the buffer is
398 * being processed by flush_to_ldisc then we defer the processing
399 * to that function
400 *
401 * Locking: none
402 */
403
404static void tty_buffer_flush(struct tty_struct *tty)
405{
406 unsigned long flags;
407 spin_lock_irqsave(&tty->buf.lock, flags);
408
409 /* If the data is being pushed to the tty layer then we can't
410 process it here. Instead set a flag and the flush_to_ldisc
411 path will process the flush request before it exits */
412 if (test_bit(TTY_FLUSHING, &tty->flags)) {
413 set_bit(TTY_FLUSHPENDING, &tty->flags);
414 spin_unlock_irqrestore(&tty->buf.lock, flags);
415 wait_event(tty->read_wait,
416 test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
417 return;
418 } else
419 __tty_buffer_flush(tty);
391 spin_unlock_irqrestore(&tty->buf.lock, flags); 420 spin_unlock_irqrestore(&tty->buf.lock, flags);
392} 421}
393 422
@@ -2034,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2034 } 2063 }
2035 2064
2036 if (!*tp_loc) { 2065 if (!*tp_loc) {
2037 tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), 2066 tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
2038 GFP_KERNEL);
2039 if (!tp) 2067 if (!tp)
2040 goto free_mem_out; 2068 goto free_mem_out;
2041 *tp = driver->init_termios; 2069 *tp = driver->init_termios;
@@ -2065,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2065 } 2093 }
2066 2094
2067 if (!*o_tp_loc) { 2095 if (!*o_tp_loc) {
2068 o_tp = (struct ktermios *) 2096 o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
2069 kmalloc(sizeof(struct ktermios), GFP_KERNEL);
2070 if (!o_tp) 2097 if (!o_tp)
2071 goto free_mem_out; 2098 goto free_mem_out;
2072 *o_tp = driver->other->init_termios; 2099 *o_tp = driver->other->init_termios;
@@ -3594,6 +3621,7 @@ static void flush_to_ldisc(struct work_struct *work)
3594 return; 3621 return;
3595 3622
3596 spin_lock_irqsave(&tty->buf.lock, flags); 3623 spin_lock_irqsave(&tty->buf.lock, flags);
3624 set_bit(TTY_FLUSHING, &tty->flags); /* So we know a flush is running */
3597 head = tty->buf.head; 3625 head = tty->buf.head;
3598 if (head != NULL) { 3626 if (head != NULL) {
3599 tty->buf.head = NULL; 3627 tty->buf.head = NULL;
@@ -3607,6 +3635,11 @@ static void flush_to_ldisc(struct work_struct *work)
3607 tty_buffer_free(tty, tbuf); 3635 tty_buffer_free(tty, tbuf);
3608 continue; 3636 continue;
3609 } 3637 }
3638 /* Ldisc or user is trying to flush the buffers
3639 we are feeding to the ldisc, stop feeding the
3640 line discipline as we want to empty the queue */
3641 if (test_bit(TTY_FLUSHPENDING, &tty->flags))
3642 break;
3610 if (!tty->receive_room) { 3643 if (!tty->receive_room) {
3611 schedule_delayed_work(&tty->buf.work, 1); 3644 schedule_delayed_work(&tty->buf.work, 1);
3612 break; 3645 break;
@@ -3620,8 +3653,17 @@ static void flush_to_ldisc(struct work_struct *work)
3620 disc->receive_buf(tty, char_buf, flag_buf, count); 3653 disc->receive_buf(tty, char_buf, flag_buf, count);
3621 spin_lock_irqsave(&tty->buf.lock, flags); 3654 spin_lock_irqsave(&tty->buf.lock, flags);
3622 } 3655 }
3656 /* Restore the queue head */
3623 tty->buf.head = head; 3657 tty->buf.head = head;
3624 } 3658 }
3659 /* We may have a deferred request to flush the input buffer,
3660 if so pull the chain under the lock and empty the queue */
3661 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
3662 __tty_buffer_flush(tty);
3663 clear_bit(TTY_FLUSHPENDING, &tty->flags);
3664 wake_up(&tty->read_wait);
3665 }
3666 clear_bit(TTY_FLUSHING, &tty->flags);
3625 spin_unlock_irqrestore(&tty->buf.lock, flags); 3667 spin_unlock_irqrestore(&tty->buf.lock, flags);
3626 3668
3627 tty_ldisc_deref(disc); 3669 tty_ldisc_deref(disc);
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 3423e9ee6481..3ee73cf64bd2 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -795,6 +795,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
795 if (L_ICANON(tty)) 795 if (L_ICANON(tty))
796 retval = inq_canon(tty); 796 retval = inq_canon(tty);
797 return put_user(retval, (unsigned int __user *) arg); 797 return put_user(retval, (unsigned int __user *) arg);
798#ifndef TCGETS2
798 case TIOCGLCKTRMIOS: 799 case TIOCGLCKTRMIOS:
799 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) 800 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
800 return -EFAULT; 801 return -EFAULT;
@@ -806,6 +807,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
806 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) 807 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
807 return -EFAULT; 808 return -EFAULT;
808 return 0; 809 return 0;
810#else
811 case TIOCGLCKTRMIOS:
812 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
813 return -EFAULT;
814 return 0;
815
816 case TIOCSLCKTRMIOS:
817 if (!capable(CAP_SYS_ADMIN))
818 return -EPERM;
819 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
820 return -EFAULT;
821 return 0;
822#endif
809 823
810 case TIOCPKT: 824 case TIOCPKT:
811 { 825 {
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index db57277117bb..db7a731e2362 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
92#define VIOTAPOP_SETPART 14 92#define VIOTAPOP_SETPART 14
93#define VIOTAPOP_UNLOAD 15 93#define VIOTAPOP_UNLOAD 15
94 94
95struct viotapelpevent {
96 struct HvLpEvent event;
97 u32 reserved;
98 u16 version;
99 u16 sub_type_result;
100 u16 tape;
101 u16 flags;
102 u32 token;
103 u64 len;
104 union {
105 struct {
106 u32 tape_op;
107 u32 count;
108 } op;
109 struct {
110 u32 type;
111 u32 resid;
112 u32 dsreg;
113 u32 gstat;
114 u32 erreg;
115 u32 file_no;
116 u32 block_no;
117 } get_status;
118 struct {
119 u32 block_no;
120 } get_pos;
121 } u;
122};
123
124enum viotapesubtype {
125 viotapeopen = 0x0001,
126 viotapeclose = 0x0002,
127 viotaperead = 0x0003,
128 viotapewrite = 0x0004,
129 viotapegetinfo = 0x0005,
130 viotapeop = 0x0006,
131 viotapegetpos = 0x0007,
132 viotapesetpos = 0x0008,
133 viotapegetstatus = 0x0009
134};
135
136enum viotaperc { 95enum viotaperc {
137 viotape_InvalidRange = 0x0601, 96 viotape_InvalidRange = 0x0601,
138 viotape_InvalidToken = 0x0602, 97 viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
223#define VIOT_WRITING 2 182#define VIOT_WRITING 2
224 183
225/* Our info on the tapes */ 184/* Our info on the tapes */
226struct tape_descr { 185static struct {
227 char rsrcname[10]; 186 const char *rsrcname;
228 char type[4]; 187 const char *type;
229 char model[3]; 188 const char *model;
230}; 189} viotape_unitinfo[VIOTAPE_MAX_TAPE];
231
232static struct tape_descr *viotape_unitinfo;
233static dma_addr_t viotape_unitinfo_token;
234 190
235static struct mtget viomtget[VIOTAPE_MAX_TAPE]; 191static struct mtget viomtget[VIOTAPE_MAX_TAPE];
236 192
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
381 return -err->errno; 337 return -err->errno;
382} 338}
383 339
384/* Get info on all tapes from OS/400 */
385static int get_viotape_info(void)
386{
387 HvLpEvent_Rc hvrc;
388 int i;
389 size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
390 struct op_struct *op = get_op_struct();
391
392 if (op == NULL)
393 return -ENOMEM;
394
395 viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len,
396 &viotape_unitinfo_token, GFP_ATOMIC);
397 if (viotape_unitinfo == NULL) {
398 free_op_struct(op);
399 return -ENOMEM;
400 }
401
402 memset(viotape_unitinfo, 0, len);
403
404 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
405 HvLpEvent_Type_VirtualIo,
406 viomajorsubtype_tape | viotapegetinfo,
407 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
408 viopath_sourceinst(viopath_hostLp),
409 viopath_targetinst(viopath_hostLp),
410 (u64) (unsigned long) op, VIOVERSION << 16,
411 viotape_unitinfo_token, len, 0, 0);
412 if (hvrc != HvLpEvent_Rc_Good) {
413 printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
414 (int)hvrc);
415 free_op_struct(op);
416 return -EIO;
417 }
418
419 wait_for_completion(&op->com);
420
421 free_op_struct(op);
422
423 for (i = 0;
424 ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
425 i++)
426 viotape_numdev++;
427 return 0;
428}
429
430
431/* Write */ 340/* Write */
432static ssize_t viotap_write(struct file *file, const char *buf, 341static ssize_t viotap_write(struct file *file, const char *buf,
433 size_t count, loff_t * ppos) 342 size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
899 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; 808 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
900 op = (struct op_struct *)event->xCorrelationToken; 809 op = (struct op_struct *)event->xCorrelationToken;
901 switch (tapeminor) { 810 switch (tapeminor) {
902 case viotapegetinfo:
903 case viotapeopen: 811 case viotapeopen:
904 case viotapeclose: 812 case viotapeclose:
905 op->rc = tevent->sub_type_result; 813 op->rc = tevent->sub_type_result;
@@ -942,19 +850,31 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
942{ 850{
943 int i = vdev->unit_address; 851 int i = vdev->unit_address;
944 int j; 852 int j;
853 struct device_node *node = vdev->dev.archdata.of_node;
945 854
946 if (i >= viotape_numdev) 855 if (i > VIOTAPE_MAX_TAPE)
947 return -ENODEV; 856 return -ENODEV;
857 if (!node)
858 return -ENODEV;
859
860 if (i >= viotape_numdev)
861 viotape_numdev = i + 1;
948 862
949 tape_device[i] = &vdev->dev; 863 tape_device[i] = &vdev->dev;
864 viotape_unitinfo[i].rsrcname = of_get_property(node,
865 "linux,vio_rsrcname", NULL);
866 viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
867 NULL);
868 viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
869 NULL);
950 870
951 state[i].cur_part = 0; 871 state[i].cur_part = 0;
952 for (j = 0; j < MAX_PARTITIONS; ++j) 872 for (j = 0; j < MAX_PARTITIONS; ++j)
953 state[i].part_stat_rwi[j] = VIOT_IDLE; 873 state[i].part_stat_rwi[j] = VIOT_IDLE;
954 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, 874 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
955 "iseries!vt%d", i); 875 "iseries!vt%d", i);
956 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), 876 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
957 NULL, "iseries!nvt%d", i); 877 "iseries!nvt%d", i);
958 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " 878 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
959 "resource %10.10s type %4.4s, model %3.3s\n", 879 "resource %10.10s type %4.4s, model %3.3s\n",
960 i, viotape_unitinfo[i].rsrcname, 880 i, viotape_unitinfo[i].rsrcname,
@@ -966,8 +886,8 @@ static int viotape_remove(struct vio_dev *vdev)
966{ 886{
967 int i = vdev->unit_address; 887 int i = vdev->unit_address;
968 888
969 class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); 889 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
970 class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); 890 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
971 return 0; 891 return 0;
972} 892}
973 893
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
1044 goto unreg_chrdev; 964 goto unreg_chrdev;
1045 } 965 }
1046 966
1047 if ((ret = get_viotape_info()) < 0) {
1048 printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
1049 goto unreg_class;
1050 }
1051
1052 ret = vio_register_driver(&viotape_driver); 967 ret = vio_register_driver(&viotape_driver);
1053 if (ret) 968 if (ret)
1054 goto unreg_class; 969 goto unreg_class;
@@ -1098,19 +1013,10 @@ static int chg_state(int index, unsigned char new_state, struct file *file)
1098/* Cleanup */ 1013/* Cleanup */
1099static void __exit viotap_exit(void) 1014static void __exit viotap_exit(void)
1100{ 1015{
1101 int ret;
1102
1103 remove_proc_entry("iSeries/viotape", NULL); 1016 remove_proc_entry("iSeries/viotape", NULL);
1104 vio_unregister_driver(&viotape_driver); 1017 vio_unregister_driver(&viotape_driver);
1105 class_destroy(tape_class); 1018 class_destroy(tape_class);
1106 ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape"); 1019 unregister_chrdev(VIOTAPE_MAJOR, "viotape");
1107 if (ret < 0)
1108 printk(VIOTAPE_KERN_WARN "Error unregistering device: %d\n",
1109 ret);
1110 if (viotape_unitinfo)
1111 dma_free_coherent(iSeries_vio_dev,
1112 sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
1113 viotape_unitinfo, viotape_unitinfo_token);
1114 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); 1020 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1115 vio_clearHandler(viomajorsubtype_tape); 1021 vio_clearHandler(viomajorsubtype_tape);
1116 clear_op_struct_pool(); 1022 clear_op_struct_pool();
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index bef6d886d4fb..e122a0e87bb0 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -1013,18 +1013,10 @@ static struct tty_driver *scc_console_device(struct console *c, int *index)
1013 return scc_driver; 1013 return scc_driver;
1014} 1014}
1015 1015
1016
1017static int __init scc_console_setup(struct console *co, char *options)
1018{
1019 return 0;
1020}
1021
1022
1023static struct console sercons = { 1016static struct console sercons = {
1024 .name = "ttyS", 1017 .name = "ttyS",
1025 .write = scc_console_write, 1018 .write = scc_console_write,
1026 .device = scc_console_device, 1019 .device = scc_console_device,
1027 .setup = scc_console_setup,
1028 .flags = CON_PRINTBUFFER, 1020 .flags = CON_PRINTBUFFER,
1029 .index = -1, 1021 .index = -1,
1030}; 1022};
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index c6f6f4209739..7a61a2a9aafe 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
770 /* 770 /*
771 * Switching-from response 771 * Switching-from response
772 */ 772 */
773 acquire_console_sem();
773 if (vc->vt_newvt >= 0) { 774 if (vc->vt_newvt >= 0) {
774 if (arg == 0) 775 if (arg == 0)
775 /* 776 /*
@@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
784 * complete the switch. 785 * complete the switch.
785 */ 786 */
786 int newvt; 787 int newvt;
787 acquire_console_sem();
788 newvt = vc->vt_newvt; 788 newvt = vc->vt_newvt;
789 vc->vt_newvt = -1; 789 vc->vt_newvt = -1;
790 i = vc_allocate(newvt); 790 i = vc_allocate(newvt);
@@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
798 * other console switches.. 798 * other console switches..
799 */ 799 */
800 complete_change_console(vc_cons[newvt].d); 800 complete_change_console(vc_cons[newvt].d);
801 release_console_sem();
802 } 801 }
803 } 802 }
804 803
@@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
810 /* 809 /*
811 * If it's just an ACK, ignore it 810 * If it's just an ACK, ignore it
812 */ 811 */
813 if (arg != VT_ACKACQ) 812 if (arg != VT_ACKACQ) {
813 release_console_sem();
814 return -EINVAL; 814 return -EINVAL;
815 }
815 } 816 }
817 release_console_sem();
816 818
817 return 0; 819 return 0;
818 820
@@ -1030,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
1030 1032
1031/* 1033/*
1032 * Sleeps until a vt is activated, or the task is interrupted. Returns 1034 * Sleeps until a vt is activated, or the task is interrupted. Returns
1033 * 0 if activation, -EINTR if interrupted. 1035 * 0 if activation, -EINTR if interrupted by a signal handler.
1034 */ 1036 */
1035int vt_waitactive(int vt) 1037int vt_waitactive(int vt)
1036{ 1038{
@@ -1055,7 +1057,7 @@ int vt_waitactive(int vt)
1055 break; 1057 break;
1056 } 1058 }
1057 release_console_sem(); 1059 release_console_sem();
1058 retval = -EINTR; 1060 retval = -ERESTARTNOHAND;
1059 if (signal_pending(current)) 1061 if (signal_pending(current))
1060 break; 1062 break;
1061 schedule(); 1063 schedule();
@@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc)
1208 /* 1210 /*
1209 * Send the signal as privileged - kill_pid() will 1211 * Send the signal as privileged - kill_pid() will
1210 * tell us if the process has gone or something else 1212 * tell us if the process has gone or something else
1211 * is awry 1213 * is awry.
1214 *
1215 * We need to set vt_newvt *before* sending the signal or we
1216 * have a race.
1212 */ 1217 */
1218 vc->vt_newvt = new_vc->vc_num;
1213 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { 1219 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1214 /* 1220 /*
1215 * It worked. Mark the vt to switch to and 1221 * It worked. Mark the vt to switch to and
1216 * return. The process needs to send us a 1222 * return. The process needs to send us a
1217 * VT_RELDISP ioctl to complete the switch. 1223 * VT_RELDISP ioctl to complete the switch.
1218 */ 1224 */
1219 vc->vt_newvt = new_vc->vc_num;
1220 return; 1225 return;
1221 } 1226 }
1222 1227
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 2f48ba329961..37bddc1802de 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -55,6 +55,8 @@ config SOFT_WATCHDOG
55 To compile this driver as a module, choose M here: the 55 To compile this driver as a module, choose M here: the
56 module will be called softdog. 56 module will be called softdog.
57 57
58# ALPHA Architecture
59
58# ARM Architecture 60# ARM Architecture
59 61
60config AT91RM9200_WATCHDOG 62config AT91RM9200_WATCHDOG
@@ -187,15 +189,64 @@ config PNX4008_WATCHDOG
187 189
188 Say N if you are unsure. 190 Say N if you are unsure.
189 191
192config IOP_WATCHDOG
193 tristate "IOP Watchdog"
194 depends on PLAT_IOP
195 select WATCHDOG_NOWAYOUT if (ARCH_IOP32X || ARCH_IOP33X)
196 help
197 Say Y here if to include support for the watchdog timer
198 in the Intel IOP3XX & IOP13XX I/O Processors. This driver can
199 be built as a module by choosing M. The module will
200 be called iop_wdt.
201
202 Note: The IOP13XX watchdog does an Internal Bus Reset which will
203 affect both cores and the peripherals of the IOP. The ATU-X
204 and/or ATUe configuration registers will remain intact, but if
205 operating as an Root Complex and/or Central Resource, the PCI-X
206 and/or PCIe busses will also be reset. THIS IS A VERY BIG HAMMER.
207
208config DAVINCI_WATCHDOG
209 tristate "DaVinci watchdog"
210 depends on ARCH_DAVINCI
211 help
212 Say Y here if to include support for the watchdog timer
213 in the DaVinci DM644x/DM646x processors.
214 To compile this driver as a module, choose M here: the
215 module will be called davinci_wdt.
216
217 NOTE: once enabled, this timer cannot be disabled.
218 Say N if you are unsure.
219
220# ARM26 Architecture
221
190# AVR32 Architecture 222# AVR32 Architecture
191 223
192config AT32AP700X_WDT 224config AT32AP700X_WDT
193 tristate "AT32AP700x watchdog" 225 tristate "AT32AP700x watchdog"
194 depends on WATCHDOG && CPU_AT32AP7000 226 depends on CPU_AT32AP7000
195 help 227 help
196 Watchdog timer embedded into AT32AP700x devices. This will reboot 228 Watchdog timer embedded into AT32AP700x devices. This will reboot
197 your system when the timeout is reached. 229 your system when the timeout is reached.
198 230
231# BLACKFIN Architecture
232
233config BFIN_WDT
234 tristate "Blackfin On-Chip Watchdog Timer"
235 depends on BLACKFIN
236 ---help---
237 If you say yes here you will get support for the Blackfin On-Chip
238 Watchdog Timer. If you have one of these processors and wish to
239 have watchdog support enabled, say Y, otherwise say N.
240
241 To compile this driver as a module, choose M here: the
242 module will be called bfin_wdt.
243
244# CRIS Architecture
245
246# FRV Architecture
247
248# H8300 Architecture
249
199# X86 (i386 + ia64 + x86_64) Architecture 250# X86 (i386 + ia64 + x86_64) Architecture
200 251
201config ACQUIRE_WDT 252config ACQUIRE_WDT
@@ -524,37 +575,11 @@ config SBC_EPX_C3_WATCHDOG
524 To compile this driver as a module, choose M here: the 575 To compile this driver as a module, choose M here: the
525 module will be called sbc_epx_c3. 576 module will be called sbc_epx_c3.
526 577
527# PowerPC Architecture 578# M32R Architecture
528
529config 8xx_WDT
530 tristate "MPC8xx Watchdog Timer"
531 depends on 8xx
532
533config 83xx_WDT
534 tristate "MPC83xx Watchdog Timer"
535 depends on PPC_83xx
536
537config MV64X60_WDT
538 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
539 depends on MV64X60
540
541config BOOKE_WDT
542 bool "PowerPC Book-E Watchdog Timer"
543 depends on BOOKE || 4xx
544 ---help---
545 Please see Documentation/watchdog/watchdog-api.txt for
546 more information.
547
548# PPC64 Architecture
549 579
550config WATCHDOG_RTAS 580# M68K Architecture
551 tristate "RTAS watchdog"
552 depends on PPC_RTAS
553 help
554 This driver adds watchdog support for the RTAS watchdog.
555 581
556 To compile this driver as a module, choose M here. The module 582# M68KNOMMU Architecture
557 will be called wdrtas.
558 583
559# MIPS Architecture 584# MIPS Architecture
560 585
@@ -584,6 +609,44 @@ config WDT_RM9K_GPI
584 To compile this driver as a module, choose M here: the 609 To compile this driver as a module, choose M here: the
585 module will be called rm9k_wdt. 610 module will be called rm9k_wdt.
586 611
612# PARISC Architecture
613
614# POWERPC Architecture
615
616config MPC5200_WDT
617 tristate "MPC5200 Watchdog Timer"
618 depends on PPC_MPC52xx
619
620config 8xx_WDT
621 tristate "MPC8xx Watchdog Timer"
622 depends on 8xx
623
624config 83xx_WDT
625 tristate "MPC83xx Watchdog Timer"
626 depends on PPC_83xx
627
628config MV64X60_WDT
629 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
630 depends on MV64X60
631
632config BOOKE_WDT
633 bool "PowerPC Book-E Watchdog Timer"
634 depends on BOOKE || 4xx
635 ---help---
636 Please see Documentation/watchdog/watchdog-api.txt for
637 more information.
638
639# PPC64 Architecture
640
641config WATCHDOG_RTAS
642 tristate "RTAS watchdog"
643 depends on PPC_RTAS
644 help
645 This driver adds watchdog support for the RTAS watchdog.
646
647 To compile this driver as a module, choose M here. The module
648 will be called wdrtas.
649
587# S390 Architecture 650# S390 Architecture
588 651
589config ZVM_WATCHDOG 652config ZVM_WATCHDOG
@@ -598,11 +661,11 @@ config ZVM_WATCHDOG
598 To compile this driver as a module, choose M here. The module 661 To compile this driver as a module, choose M here. The module
599 will be called vmwatchdog. 662 will be called vmwatchdog.
600 663
601# SUPERH Architecture 664# SUPERH (sh + sh64) Architecture
602 665
603config SH_WDT 666config SH_WDT
604 tristate "SuperH Watchdog" 667 tristate "SuperH Watchdog"
605 depends on SUPERH 668 depends on SUPERH && (CPU_SH3 || CPU_SH4)
606 help 669 help
607 This driver adds watchdog support for the integrated watchdog in the 670 This driver adds watchdog support for the integrated watchdog in the
608 SuperH processors. If you have one of these processors and wish 671 SuperH processors. If you have one of these processors and wish
@@ -625,6 +688,8 @@ config SH_WDT_MMAP
625 If you say Y here, user applications will be able to mmap the 688 If you say Y here, user applications will be able to mmap the
626 WDT/CPG registers. 689 WDT/CPG registers.
627 690
691# SPARC Architecture
692
628# SPARC64 Architecture 693# SPARC64 Architecture
629 694
630config WATCHDOG_CP1XXX 695config WATCHDOG_CP1XXX
@@ -649,6 +714,10 @@ config WATCHDOG_RIO
649 machines. The watchdog timeout period is normally one minute but 714 machines. The watchdog timeout period is normally one minute but
650 can be changed with a boot-time parameter. 715 can be changed with a boot-time parameter.
651 716
717# V850 Architecture
718
719# XTENSA Architecture
720
652# 721#
653# ISA-based Watchdog Cards 722# ISA-based Watchdog Cards
654# 723#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 3907ec04a4e5..389f8b14ccc4 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o
22# USB-based Watchdog Cards 22# USB-based Watchdog Cards
23obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o 23obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
24 24
25# ALPHA Architecture
26
25# ARM Architecture 27# ARM Architecture
26obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o 28obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
27obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o 29obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
@@ -35,10 +37,23 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
35obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o 37obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
36obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o 38obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
37obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o 39obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
40obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
41obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
42
43# ARM26 Architecture
38 44
39# AVR32 Architecture 45# AVR32 Architecture
40obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 46obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
41 47
48# BLACKFIN Architecture
49obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
50
51# CRIS Architecture
52
53# FRV Architecture
54
55# H8300 Architecture
56
42# X86 (i386 + ia64 + x86_64) Architecture 57# X86 (i386 + ia64 + x86_64) Architecture
43obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o 58obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
44obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o 59obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
@@ -65,8 +80,22 @@ obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
65obj-$(CONFIG_MACHZ_WDT) += machzwd.o 80obj-$(CONFIG_MACHZ_WDT) += machzwd.o
66obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o 81obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
67 82
68# PowerPC Architecture 83# M32R Architecture
84
85# M68K Architecture
86
87# M68KNOMMU Architecture
88
89# MIPS Architecture
90obj-$(CONFIG_INDYDOG) += indydog.o
91obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
92obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
93
94# PARISC Architecture
95
96# POWERPC Architecture
69obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 97obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
98obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
70obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o 99obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o
71obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o 100obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
72obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o 101obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
@@ -74,17 +103,18 @@ obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
74# PPC64 Architecture 103# PPC64 Architecture
75obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 104obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
76 105
77# MIPS Architecture
78obj-$(CONFIG_INDYDOG) += indydog.o
79obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
80obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
81
82# S390 Architecture 106# S390 Architecture
83 107
84# SUPERH Architecture 108# SUPERH (sh + sh64) Architecture
85obj-$(CONFIG_SH_WDT) += shwdt.o 109obj-$(CONFIG_SH_WDT) += shwdt.o
86 110
111# SPARC Architecture
112
87# SPARC64 Architecture 113# SPARC64 Architecture
88 114
115# V850 Architecture
116
117# XTENSA Architecture
118
89# Architecture Independant 119# Architecture Independant
90obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o 120obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index e3f6a7d0c83d..c404fc69e7e6 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void
312 */ 312 */
313 313
314static struct pci_device_id ali_pci_tbl[] = { 314static struct pci_device_id ali_pci_tbl[] = {
315 { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,},
315 { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, 316 { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,},
316 { 0, }, 317 { 0, },
317}; 318};
@@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void)
329 struct pci_dev *pdev; 330 struct pci_dev *pdev;
330 u32 wdog; 331 u32 wdog;
331 332
332 /* Check for a 1535 series bridge */ 333 /* Check for a 1533/1535 series bridge */
333 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); 334 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
334 if(pdev == NULL) 335 if (pdev == NULL)
336 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL);
337 if (pdev == NULL)
335 return -ENODEV; 338 return -ENODEV;
336 pci_dev_put(pdev); 339 pci_dev_put(pdev);
337 340
diff --git a/drivers/char/watchdog/bfin_wdt.c b/drivers/char/watchdog/bfin_wdt.c
new file mode 100644
index 000000000000..309d27913fc1
--- /dev/null
+++ b/drivers/char/watchdog/bfin_wdt.c
@@ -0,0 +1,490 @@
1/*
2 * Blackfin On-Chip Watchdog Driver
3 * Supports BF53[123]/BF53[467]/BF54[2489]/BF561
4 *
5 * Originally based on softdog.c
6 * Copyright 2006-2007 Analog Devices Inc.
7 * Copyright 2006-2007 Michele d'Amico
8 * Copyright 1996 Alan Cox <alan@redhat.com>
9 *
10 * Enter bugs at http://blackfin.uclinux.org/
11 *
12 * Licensed under the GPL-2 or later.
13 */
14
15#include <linux/platform_device.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/types.h>
19#include <linux/timer.h>
20#include <linux/miscdevice.h>
21#include <linux/watchdog.h>
22#include <linux/fs.h>
23#include <linux/notifier.h>
24#include <linux/reboot.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <asm/blackfin.h>
28#include <asm/uaccess.h>
29
30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
31#define stampit() stamp("here i am")
32
33#define WATCHDOG_NAME "bfin-wdt"
34#define PFX WATCHDOG_NAME ": "
35
36/* The BF561 has two watchdogs (one per core), but since Linux
37 * only runs on core A, we'll just work with that one.
38 */
39#ifdef BF561_FAMILY
40# define bfin_read_WDOG_CTL() bfin_read_WDOGA_CTL()
41# define bfin_read_WDOG_CNT() bfin_read_WDOGA_CNT()
42# define bfin_read_WDOG_STAT() bfin_read_WDOGA_STAT()
43# define bfin_write_WDOG_CTL(x) bfin_write_WDOGA_CTL(x)
44# define bfin_write_WDOG_CNT(x) bfin_write_WDOGA_CNT(x)
45# define bfin_write_WDOG_STAT(x) bfin_write_WDOGA_STAT(x)
46#endif
47
48/* Bit in SWRST that indicates boot caused by watchdog */
49#define SWRST_RESET_WDOG 0x4000
50
51/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */
52#define WDOG_EXPIRED 0x8000
53
54/* Masks for WDEV field in WDOG_CTL register */
55#define ICTL_RESET 0x0
56#define ICTL_NMI 0x2
57#define ICTL_GPI 0x4
58#define ICTL_NONE 0x6
59#define ICTL_MASK 0x6
60
61/* Masks for WDEN field in WDOG_CTL register */
62#define WDEN_MASK 0x0FF0
63#define WDEN_ENABLE 0x0000
64#define WDEN_DISABLE 0x0AD0
65
66/* some defaults */
67#define WATCHDOG_TIMEOUT 20
68
69static unsigned int timeout = WATCHDOG_TIMEOUT;
70static int nowayout = WATCHDOG_NOWAYOUT;
71static struct watchdog_info bfin_wdt_info;
72static unsigned long open_check;
73static char expect_close;
74static spinlock_t bfin_wdt_spinlock = SPIN_LOCK_UNLOCKED;
75
76/**
77 * bfin_wdt_keepalive - Keep the Userspace Watchdog Alive
78 *
79 * The Userspace watchdog got a KeepAlive: schedule the next timeout.
80 */
81static int bfin_wdt_keepalive(void)
82{
83 stampit();
84 bfin_write_WDOG_STAT(0);
85 return 0;
86}
87
88/**
89 * bfin_wdt_stop - Stop the Watchdog
90 *
91 * Stops the on-chip watchdog.
92 */
93static int bfin_wdt_stop(void)
94{
95 stampit();
96 bfin_write_WDOG_CTL(WDEN_DISABLE);
97 return 0;
98}
99
100/**
101 * bfin_wdt_start - Start the Watchdog
102 *
103 * Starts the on-chip watchdog. Automatically loads WDOG_CNT
104 * into WDOG_STAT for us.
105 */
106static int bfin_wdt_start(void)
107{
108 stampit();
109 bfin_write_WDOG_CTL(WDEN_ENABLE | ICTL_RESET);
110 return 0;
111}
112
113/**
114 * bfin_wdt_running - Check Watchdog status
115 *
116 * See if the watchdog is running.
117 */
118static int bfin_wdt_running(void)
119{
120 stampit();
121 return ((bfin_read_WDOG_CTL() & WDEN_MASK) != WDEN_DISABLE);
122}
123
124/**
125 * bfin_wdt_set_timeout - Set the Userspace Watchdog timeout
126 * @t: new timeout value (in seconds)
127 *
128 * Translate the specified timeout in seconds into System Clock
129 * terms which is what the on-chip Watchdog requires.
130 */
131static int bfin_wdt_set_timeout(unsigned long t)
132{
133 u32 cnt;
134 unsigned long flags;
135
136 stampit();
137
138 cnt = t * get_sclk();
139 if (cnt < get_sclk()) {
140 printk(KERN_WARNING PFX "timeout value is too large\n");
141 return -EINVAL;
142 }
143
144 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
145 {
146 int run = bfin_wdt_running();
147 bfin_wdt_stop();
148 bfin_write_WDOG_CNT(cnt);
149 if (run) bfin_wdt_start();
150 }
151 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
152
153 timeout = t;
154
155 return 0;
156}
157
158/**
159 * bfin_wdt_open - Open the Device
160 * @inode: inode of device
161 * @file: file handle of device
162 *
163 * Watchdog device is opened and started.
164 */
165static int bfin_wdt_open(struct inode *inode, struct file *file)
166{
167 stampit();
168
169 if (test_and_set_bit(0, &open_check))
170 return -EBUSY;
171
172 if (nowayout)
173 __module_get(THIS_MODULE);
174
175 bfin_wdt_keepalive();
176 bfin_wdt_start();
177
178 return nonseekable_open(inode, file);
179}
180
181/**
182 * bfin_wdt_close - Close the Device
183 * @inode: inode of device
184 * @file: file handle of device
185 *
186 * Watchdog device is closed and stopped.
187 */
188static int bfin_wdt_release(struct inode *inode, struct file *file)
189{
190 stampit();
191
192 if (expect_close == 42) {
193 bfin_wdt_stop();
194 } else {
195 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
196 bfin_wdt_keepalive();
197 }
198
199 expect_close = 0;
200 clear_bit(0, &open_check);
201
202 return 0;
203}
204
205/**
206 * bfin_wdt_write - Write to Device
207 * @file: file handle of device
208 * @buf: buffer to write
209 * @count: length of buffer
210 * @ppos: offset
211 *
212 * Pings the watchdog on write.
213 */
214static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
215 size_t len, loff_t *ppos)
216{
217 stampit();
218
219 if (len) {
220 if (!nowayout) {
221 size_t i;
222
223 /* In case it was set long ago */
224 expect_close = 0;
225
226 for (i = 0; i != len; i++) {
227 char c;
228 if (get_user(c, data + i))
229 return -EFAULT;
230 if (c == 'V')
231 expect_close = 42;
232 }
233 }
234 bfin_wdt_keepalive();
235 }
236
237 return len;
238}
239
240/**
241 * bfin_wdt_ioctl - Query Device
242 * @inode: inode of device
243 * @file: file handle of device
244 * @cmd: watchdog command
245 * @arg: argument
246 *
247 * Query basic information from the device or ping it, as outlined by the
248 * watchdog API.
249 */
250static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
251 unsigned int cmd, unsigned long arg)
252{
253 void __user *argp = (void __user *)arg;
254 int __user *p = argp;
255
256 stampit();
257
258 switch (cmd) {
259 default:
260 return -ENOTTY;
261
262 case WDIOC_GETSUPPORT:
263 if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
264 return -EFAULT;
265 else
266 return 0;
267
268 case WDIOC_GETSTATUS:
269 case WDIOC_GETBOOTSTATUS:
270 return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
271
272 case WDIOC_KEEPALIVE:
273 bfin_wdt_keepalive();
274 return 0;
275
276 case WDIOC_SETTIMEOUT: {
277 int new_timeout;
278
279 if (get_user(new_timeout, p))
280 return -EFAULT;
281
282 if (bfin_wdt_set_timeout(new_timeout))
283 return -EINVAL;
284 }
285 /* Fall */
286 case WDIOC_GETTIMEOUT:
287 return put_user(timeout, p);
288
289 case WDIOC_SETOPTIONS: {
290 unsigned long flags;
291 int options, ret = -EINVAL;
292
293 if (get_user(options, p))
294 return -EFAULT;
295
296 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
297
298 if (options & WDIOS_DISABLECARD) {
299 bfin_wdt_stop();
300 ret = 0;
301 }
302
303 if (options & WDIOS_ENABLECARD) {
304 bfin_wdt_start();
305 ret = 0;
306 }
307
308 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
309
310 return ret;
311 }
312 }
313}
314
315/**
316 * bfin_wdt_notify_sys - Notifier Handler
317 * @this: notifier block
318 * @code: notifier event
319 * @unused: unused
320 *
321 * Handles specific events, such as turning off the watchdog during a
322 * shutdown event.
323 */
324static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code,
325 void *unused)
326{
327 stampit();
328
329 if (code == SYS_DOWN || code == SYS_HALT)
330 bfin_wdt_stop();
331
332 return NOTIFY_DONE;
333}
334
335#ifdef CONFIG_PM
336static int state_before_suspend;
337
338/**
339 * bfin_wdt_suspend - suspend the watchdog
340 * @pdev: device being suspended
341 * @state: requested suspend state
342 *
343 * Remember if the watchdog was running and stop it.
344 * TODO: is this even right? Doesn't seem to be any
345 * standard in the watchdog world ...
346 */
347static int bfin_wdt_suspend(struct platform_device *pdev, pm_message_t state)
348{
349 stampit();
350
351 state_before_suspend = bfin_wdt_running();
352 bfin_wdt_stop();
353
354 return 0;
355}
356
357/**
358 * bfin_wdt_resume - resume the watchdog
359 * @pdev: device being resumed
360 *
361 * If the watchdog was running, turn it back on.
362 */
363static int bfin_wdt_resume(struct platform_device *pdev)
364{
365 stampit();
366
367 if (state_before_suspend) {
368 bfin_wdt_set_timeout(timeout);
369 bfin_wdt_start();
370 }
371
372 return 0;
373}
374#else
375# define bfin_wdt_suspend NULL
376# define bfin_wdt_resume NULL
377#endif
378
379static struct platform_device bfin_wdt_device = {
380 .name = WATCHDOG_NAME,
381 .id = -1,
382};
383
384static struct platform_driver bfin_wdt_driver = {
385 .driver = {
386 .name = WATCHDOG_NAME,
387 .owner = THIS_MODULE,
388 },
389 .suspend = bfin_wdt_suspend,
390 .resume = bfin_wdt_resume,
391};
392
393static struct file_operations bfin_wdt_fops = {
394 .owner = THIS_MODULE,
395 .llseek = no_llseek,
396 .write = bfin_wdt_write,
397 .ioctl = bfin_wdt_ioctl,
398 .open = bfin_wdt_open,
399 .release = bfin_wdt_release,
400};
401
402static struct miscdevice bfin_wdt_miscdev = {
403 .minor = WATCHDOG_MINOR,
404 .name = "watchdog",
405 .fops = &bfin_wdt_fops,
406};
407
408static struct watchdog_info bfin_wdt_info = {
409 .identity = "Blackfin Watchdog",
410 .options = WDIOF_SETTIMEOUT |
411 WDIOF_KEEPALIVEPING |
412 WDIOF_MAGICCLOSE,
413};
414
415static struct notifier_block bfin_wdt_notifier = {
416 .notifier_call = bfin_wdt_notify_sys,
417};
418
419/**
420 * bfin_wdt_init - Initialize module
421 *
422 * Registers the device and notifier handler. Actual device
423 * initialization is handled by bfin_wdt_open().
424 */
425static int __init bfin_wdt_init(void)
426{
427 int ret;
428
429 stampit();
430
431 /* Check that the timeout value is within range */
432 if (bfin_wdt_set_timeout(timeout))
433 return -EINVAL;
434
435 /* Since this is an on-chip device and needs no board-specific
436 * resources, we'll handle all the platform device stuff here.
437 */
438 ret = platform_device_register(&bfin_wdt_device);
439 if (ret)
440 return ret;
441
442 ret = platform_driver_probe(&bfin_wdt_driver, NULL);
443 if (ret)
444 return ret;
445
446 ret = register_reboot_notifier(&bfin_wdt_notifier);
447 if (ret) {
448 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
449 return ret;
450 }
451
452 ret = misc_register(&bfin_wdt_miscdev);
453 if (ret) {
454 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
455 WATCHDOG_MINOR, ret);
456 unregister_reboot_notifier(&bfin_wdt_notifier);
457 return ret;
458 }
459
460 printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
461 timeout, nowayout);
462
463 return 0;
464}
465
466/**
467 * bfin_wdt_exit - Deinitialize module
468 *
469 * Unregisters the device and notifier handler. Actual device
470 * deinitialization is handled by bfin_wdt_close().
471 */
472static void __exit bfin_wdt_exit(void)
473{
474 misc_deregister(&bfin_wdt_miscdev);
475 unregister_reboot_notifier(&bfin_wdt_notifier);
476}
477
478module_init(bfin_wdt_init);
479module_exit(bfin_wdt_exit);
480
481MODULE_AUTHOR("Michele d'Amico, Mike Frysinger <vapier@gentoo.org>");
482MODULE_DESCRIPTION("Blackfin Watchdog Device Driver");
483MODULE_LICENSE("GPL");
484MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
485
486module_param(timeout, uint, 0);
487MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
488
489module_param(nowayout, int, 0);
490MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index 0f5c77ddd39d..d362f5bf658a 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -144,7 +144,7 @@ static int booke_wdt_open (struct inode *inode, struct file *file)
144 booke_wdt_period); 144 booke_wdt_period);
145 } 145 }
146 146
147 return 0; 147 return nonseekable_open(inode, file);
148} 148}
149 149
150static const struct file_operations booke_wdt_fops = { 150static const struct file_operations booke_wdt_fops = {
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index d0d45a8b09f0..5941ca601a3a 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -162,6 +162,10 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
162 if ( copy_to_user(argp, &value, sizeof(int)) ) 162 if ( copy_to_user(argp, &value, sizeof(int)) )
163 return -EFAULT; 163 return -EFAULT;
164 break; 164 break;
165 case WDIOC_GETBOOTSTATUS:
166 if ( copy_to_user(argp, &value, sizeof(int)) )
167 return -EFAULT;
168 break;
165 case WDIOC_GETSUPPORT: 169 case WDIOC_GETSUPPORT:
166 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 170 if ( copy_to_user(argp, &ident, sizeof(ident)) )
167 return -EFAULT; 171 return -EFAULT;
diff --git a/drivers/char/watchdog/davinci_wdt.c b/drivers/char/watchdog/davinci_wdt.c
new file mode 100644
index 000000000000..19db5302ba6e
--- /dev/null
+++ b/drivers/char/watchdog/davinci_wdt.c
@@ -0,0 +1,281 @@
1/*
2 * drivers/char/watchdog/davinci_wdt.c
3 *
4 * Watchdog driver for DaVinci DM644x/DM646x processors
5 *
6 * Copyright (C) 2006 Texas Instruments.
7 *
8 * 2007 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/fs.h>
19#include <linux/miscdevice.h>
20#include <linux/watchdog.h>
21#include <linux/init.h>
22#include <linux/bitops.h>
23#include <linux/platform_device.h>
24#include <linux/spinlock.h>
25
26#include <asm/hardware.h>
27#include <asm/uaccess.h>
28#include <asm/io.h>
29
30#define MODULE_NAME "DAVINCI-WDT: "
31
32#define DEFAULT_HEARTBEAT 60
33#define MAX_HEARTBEAT 600 /* really the max margin is 264/27MHz*/
34
35/* Timer register set definition */
36#define PID12 (0x0)
37#define EMUMGT (0x4)
38#define TIM12 (0x10)
39#define TIM34 (0x14)
40#define PRD12 (0x18)
41#define PRD34 (0x1C)
42#define TCR (0x20)
43#define TGCR (0x24)
44#define WDTCR (0x28)
45
46/* TCR bit definitions */
47#define ENAMODE12_DISABLED (0 << 6)
48#define ENAMODE12_ONESHOT (1 << 6)
49#define ENAMODE12_PERIODIC (2 << 6)
50
51/* TGCR bit definitions */
52#define TIM12RS_UNRESET (1 << 0)
53#define TIM34RS_UNRESET (1 << 1)
54#define TIMMODE_64BIT_WDOG (2 << 2)
55
56/* WDTCR bit definitions */
57#define WDEN (1 << 14)
58#define WDFLAG (1 << 15)
59#define WDKEY_SEQ0 (0xa5c6 << 16)
60#define WDKEY_SEQ1 (0xda7e << 16)
61
62static int heartbeat = DEFAULT_HEARTBEAT;
63
64static spinlock_t io_lock;
65static unsigned long wdt_status;
66#define WDT_IN_USE 0
67#define WDT_OK_TO_CLOSE 1
68#define WDT_REGION_INITED 2
69#define WDT_DEVICE_INITED 3
70
71static struct resource *wdt_mem;
72static void __iomem *wdt_base;
73
74static void wdt_service(void)
75{
76 spin_lock(&io_lock);
77
78 /* put watchdog in service state */
79 davinci_writel(WDKEY_SEQ0, wdt_base + WDTCR);
80 /* put watchdog in active state */
81 davinci_writel(WDKEY_SEQ1, wdt_base + WDTCR);
82
83 spin_unlock(&io_lock);
84}
85
86static void wdt_enable(void)
87{
88 u32 tgcr;
89 u32 timer_margin;
90
91 spin_lock(&io_lock);
92
93 /* disable, internal clock source */
94 davinci_writel(0, wdt_base + TCR);
95 /* reset timer, set mode to 64-bit watchdog, and unreset */
96 davinci_writel(0, wdt_base + TGCR);
97 tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
98 davinci_writel(tgcr, wdt_base + TGCR);
99 /* clear counter regs */
100 davinci_writel(0, wdt_base + TIM12);
101 davinci_writel(0, wdt_base + TIM34);
102 /* set timeout period */
103 timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) & 0xffffffff);
104 davinci_writel(timer_margin, wdt_base + PRD12);
105 timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) >> 32);
106 davinci_writel(timer_margin, wdt_base + PRD34);
107 /* enable run continuously */
108 davinci_writel(ENAMODE12_PERIODIC, wdt_base + TCR);
109 /* Once the WDT is in pre-active state write to
110 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
111 * write protected (except for the WDKEY field)
112 */
113 /* put watchdog in pre-active state */
114 davinci_writel(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR);
115 /* put watchdog in active state */
116 davinci_writel(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR);
117
118 spin_unlock(&io_lock);
119}
120
121static int davinci_wdt_open(struct inode *inode, struct file *file)
122{
123 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
124 return -EBUSY;
125
126 wdt_enable();
127
128 return nonseekable_open(inode, file);
129}
130
131static ssize_t
132davinci_wdt_write(struct file *file, const char *data, size_t len,
133 loff_t *ppos)
134{
135 if (len)
136 wdt_service();
137
138 return len;
139}
140
141static struct watchdog_info ident = {
142 .options = WDIOF_KEEPALIVEPING,
143 .identity = "DaVinci Watchdog",
144};
145
146static int
147davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
148 unsigned long arg)
149{
150 int ret = -ENOTTY;
151
152 switch (cmd) {
153 case WDIOC_GETSUPPORT:
154 ret = copy_to_user((struct watchdog_info *)arg, &ident,
155 sizeof(ident)) ? -EFAULT : 0;
156 break;
157
158 case WDIOC_GETSTATUS:
159 case WDIOC_GETBOOTSTATUS:
160 ret = put_user(0, (int *)arg);
161 break;
162
163 case WDIOC_GETTIMEOUT:
164 ret = put_user(heartbeat, (int *)arg);
165 break;
166
167 case WDIOC_KEEPALIVE:
168 wdt_service();
169 ret = 0;
170 break;
171 }
172 return ret;
173}
174
175static int davinci_wdt_release(struct inode *inode, struct file *file)
176{
177 wdt_service();
178 clear_bit(WDT_IN_USE, &wdt_status);
179
180 return 0;
181}
182
183static const struct file_operations davinci_wdt_fops = {
184 .owner = THIS_MODULE,
185 .llseek = no_llseek,
186 .write = davinci_wdt_write,
187 .ioctl = davinci_wdt_ioctl,
188 .open = davinci_wdt_open,
189 .release = davinci_wdt_release,
190};
191
192static struct miscdevice davinci_wdt_miscdev = {
193 .minor = WATCHDOG_MINOR,
194 .name = "watchdog",
195 .fops = &davinci_wdt_fops,
196};
197
198static int davinci_wdt_probe(struct platform_device *pdev)
199{
200 int ret = 0, size;
201 struct resource *res;
202
203 spin_lock_init(&io_lock);
204
205 if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
206 heartbeat = DEFAULT_HEARTBEAT;
207
208 printk(KERN_INFO MODULE_NAME
209 "DaVinci Watchdog Timer: heartbeat %d sec\n", heartbeat);
210
211 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
212 if (res == NULL) {
213 printk(KERN_INFO MODULE_NAME
214 "failed to get memory region resource\n");
215 return -ENOENT;
216 }
217
218 size = res->end - res->start + 1;
219 wdt_mem = request_mem_region(res->start, size, pdev->name);
220
221 if (wdt_mem == NULL) {
222 printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
223 return -ENOENT;
224 }
225 wdt_base = (void __iomem *)(res->start);
226
227 ret = misc_register(&davinci_wdt_miscdev);
228 if (ret < 0) {
229 printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
230 release_resource(wdt_mem);
231 kfree(wdt_mem);
232 } else {
233 set_bit(WDT_DEVICE_INITED, &wdt_status);
234 }
235
236 return ret;
237}
238
239static int davinci_wdt_remove(struct platform_device *pdev)
240{
241 misc_deregister(&davinci_wdt_miscdev);
242 if (wdt_mem) {
243 release_resource(wdt_mem);
244 kfree(wdt_mem);
245 wdt_mem = NULL;
246 }
247 return 0;
248}
249
250static struct platform_driver platform_wdt_driver = {
251 .driver = {
252 .name = "watchdog",
253 },
254 .probe = davinci_wdt_probe,
255 .remove = davinci_wdt_remove,
256};
257
258static int __init davinci_wdt_init(void)
259{
260 return platform_driver_register(&platform_wdt_driver);
261}
262
263static void __exit davinci_wdt_exit(void)
264{
265 return platform_driver_unregister(&platform_wdt_driver);
266}
267
268module_init(davinci_wdt_init);
269module_exit(davinci_wdt_exit);
270
271MODULE_AUTHOR("Texas Instruments");
272MODULE_DESCRIPTION("DaVinci Watchdog Driver");
273
274module_param(heartbeat, int, 0);
275MODULE_PARM_DESC(heartbeat,
276 "Watchdog heartbeat period in seconds from 1 to "
277 __MODULE_STRING(MAX_HEARTBEAT) ", default "
278 __MODULE_STRING(DEFAULT_HEARTBEAT));
279
280MODULE_LICENSE("GPL");
281MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index b070324e27a6..b14e9d1f164d 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Eurotech CPU-1220/1410 on board WDT driver 2 * Eurotech CPU-1220/1410/1420 on board WDT driver
3 * 3 *
4 * (c) Copyright 2001 Ascensit <support@ascensit.com> 4 * (c) Copyright 2001 Ascensit <support@ascensit.com>
5 * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com> 5 * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
@@ -25,6 +25,9 @@
25 25
26/* Changelog: 26/* Changelog:
27 * 27 *
28 * 2001 - Rodolfo Giometti
29 * Initial release
30 *
28 * 2002/04/25 - Rob Radez 31 * 2002/04/25 - Rob Radez
29 * clean up #includes 32 * clean up #includes
30 * clean up locking 33 * clean up locking
@@ -33,13 +36,15 @@
33 * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls 36 * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
34 * add expect_close support 37 * add expect_close support
35 * 38 *
36 * 2001 - Rodolfo Giometti
37 * Initial release
38 *
39 * 2002.05.30 - Joel Becker <joel.becker@oracle.com> 39 * 2002.05.30 - Joel Becker <joel.becker@oracle.com>
40 * Added Matt Domsch's nowayout module option. 40 * Added Matt Domsch's nowayout module option.
41 */ 41 */
42 42
43/*
44 * The eurotech CPU-1220/1410/1420's watchdog is a part
45 * of the on-board SUPER I/O device SMSC FDC 37B782.
46 */
47
43#include <linux/interrupt.h> 48#include <linux/interrupt.h>
44#include <linux/module.h> 49#include <linux/module.h>
45#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index eac4f9b9f007..cd5a565bc3a0 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -39,7 +39,12 @@
39 * 82801HR (ICH8R) : document number 313056-002, 313057-004, 39 * 82801HR (ICH8R) : document number 313056-002, 313057-004,
40 * 82801HH (ICH8DH) : document number 313056-002, 313057-004, 40 * 82801HH (ICH8DH) : document number 313056-002, 313057-004,
41 * 82801HO (ICH8DO) : document number 313056-002, 313057-004, 41 * 82801HO (ICH8DO) : document number 313056-002, 313057-004,
42 * 6300ESB (6300ESB) : document number 300641-003 42 * 82801IB (ICH9) : document number 316972-001, 316973-001,
43 * 82801IR (ICH9R) : document number 316972-001, 316973-001,
44 * 82801IH (ICH9DH) : document number 316972-001, 316973-001,
45 * 6300ESB (6300ESB) : document number 300641-003, 300884-010,
46 * 631xESB (631xESB) : document number 313082-001, 313075-005,
47 * 632xESB (632xESB) : document number 313082-001, 313075-005
43 */ 48 */
44 49
45/* 50/*
@@ -48,8 +53,8 @@
48 53
49/* Module and version information */ 54/* Module and version information */
50#define DRV_NAME "iTCO_wdt" 55#define DRV_NAME "iTCO_wdt"
51#define DRV_VERSION "1.01" 56#define DRV_VERSION "1.02"
52#define DRV_RELDATE "21-Jan-2007" 57#define DRV_RELDATE "26-Jul-2007"
53#define PFX DRV_NAME ": " 58#define PFX DRV_NAME ": "
54 59
55/* Includes */ 60/* Includes */
@@ -92,6 +97,10 @@ enum iTCO_chipsets {
92 TCO_ICH8, /* ICH8 & ICH8R */ 97 TCO_ICH8, /* ICH8 & ICH8R */
93 TCO_ICH8DH, /* ICH8DH */ 98 TCO_ICH8DH, /* ICH8DH */
94 TCO_ICH8DO, /* ICH8DO */ 99 TCO_ICH8DO, /* ICH8DO */
100 TCO_ICH9, /* ICH9 */
101 TCO_ICH9R, /* ICH9R */
102 TCO_ICH9DH, /* ICH9DH */
103 TCO_631XESB, /* 631xESB/632xESB */
95}; 104};
96 105
97static struct { 106static struct {
@@ -118,6 +127,10 @@ static struct {
118 {"ICH8 or ICH8R", 2}, 127 {"ICH8 or ICH8R", 2},
119 {"ICH8DH", 2}, 128 {"ICH8DH", 2},
120 {"ICH8DO", 2}, 129 {"ICH8DO", 2},
130 {"ICH9", 2},
131 {"ICH9R", 2},
132 {"ICH9DH", 2},
133 {"631xESB/632xESB", 2},
121 {NULL,0} 134 {NULL,0}
122}; 135};
123 136
@@ -148,6 +161,25 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
148 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 }, 161 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 },
149 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH }, 162 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH },
150 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO }, 163 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO },
164 { PCI_VENDOR_ID_INTEL, 0x2918, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9 },
165 { PCI_VENDOR_ID_INTEL, 0x2916, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9R },
166 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9DH },
167 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
168 { PCI_VENDOR_ID_INTEL, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
169 { PCI_VENDOR_ID_INTEL, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
170 { PCI_VENDOR_ID_INTEL, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
171 { PCI_VENDOR_ID_INTEL, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
172 { PCI_VENDOR_ID_INTEL, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
173 { PCI_VENDOR_ID_INTEL, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
174 { PCI_VENDOR_ID_INTEL, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
175 { PCI_VENDOR_ID_INTEL, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
176 { PCI_VENDOR_ID_INTEL, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
177 { PCI_VENDOR_ID_INTEL, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
178 { PCI_VENDOR_ID_INTEL, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
179 { PCI_VENDOR_ID_INTEL, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
180 { PCI_VENDOR_ID_INTEL, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
181 { PCI_VENDOR_ID_INTEL, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
182 { PCI_VENDOR_ID_INTEL, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
151 { 0, }, /* End of list */ 183 { 0, }, /* End of list */
152}; 184};
153MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); 185MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/char/watchdog/iop_wdt.c
new file mode 100644
index 000000000000..bbbd91af754d
--- /dev/null
+++ b/drivers/char/watchdog/iop_wdt.c
@@ -0,0 +1,262 @@
1/*
2 * drivers/char/watchdog/iop_wdt.c
3 *
4 * WDT driver for Intel I/O Processors
5 * Copyright (C) 2005, Intel Corporation.
6 *
7 * Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 * Place - Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * Curt E Bruns <curt.e.bruns@intel.com>
23 * Peter Milne <peter.milne@d-tacq.com>
24 * Dan Williams <dan.j.williams@intel.com>
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/fs.h>
30#include <linux/init.h>
31#include <linux/device.h>
32#include <linux/miscdevice.h>
33#include <linux/watchdog.h>
34#include <linux/uaccess.h>
35#include <asm/hardware.h>
36
37static int nowayout = WATCHDOG_NOWAYOUT;
38static unsigned long wdt_status;
39static unsigned long boot_status;
40
41#define WDT_IN_USE 0
42#define WDT_OK_TO_CLOSE 1
43#define WDT_ENABLED 2
44
45static unsigned long iop_watchdog_timeout(void)
46{
47 return (0xffffffffUL / get_iop_tick_rate());
48}
49
50/**
51 * wdt_supports_disable - determine if we are accessing a iop13xx watchdog
52 * or iop3xx by whether it has a disable command
53 */
54static int wdt_supports_disable(void)
55{
56 int can_disable;
57
58 if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM)
59 can_disable = 1;
60 else
61 can_disable = 0;
62
63 return can_disable;
64}
65
66static void wdt_enable(void)
67{
68 /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
69 * Takes approx. 10.7s to timeout
70 */
71 write_wdtcr(IOP_WDTCR_EN_ARM);
72 write_wdtcr(IOP_WDTCR_EN);
73}
74
75/* returns 0 if the timer was successfully disabled */
76static int wdt_disable(void)
77{
78 /* Stop Counting */
79 if (wdt_supports_disable()) {
80 write_wdtcr(IOP_WDTCR_DIS_ARM);
81 write_wdtcr(IOP_WDTCR_DIS);
82 clear_bit(WDT_ENABLED, &wdt_status);
83 printk(KERN_INFO "WATCHDOG: Disabled\n");
84 return 0;
85 } else
86 return 1;
87}
88
89static int iop_wdt_open(struct inode *inode, struct file *file)
90{
91 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
92 return -EBUSY;
93
94 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
95
96 wdt_enable();
97
98 set_bit(WDT_ENABLED, &wdt_status);
99
100 return nonseekable_open(inode, file);
101}
102
103static ssize_t
104iop_wdt_write(struct file *file, const char *data, size_t len,
105 loff_t *ppos)
106{
107 if (len) {
108 if (!nowayout) {
109 size_t i;
110
111 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
112
113 for (i = 0; i != len; i++) {
114 char c;
115
116 if (get_user(c, data + i))
117 return -EFAULT;
118 if (c == 'V')
119 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
120 }
121 }
122 wdt_enable();
123 }
124
125 return len;
126}
127
128static struct watchdog_info ident = {
129 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
130 .identity = "iop watchdog",
131};
132
133static int
134iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
135 unsigned long arg)
136{
137 int options;
138 int ret = -ENOTTY;
139
140 switch (cmd) {
141 case WDIOC_GETSUPPORT:
142 if (copy_to_user
143 ((struct watchdog_info *)arg, &ident, sizeof ident))
144 ret = -EFAULT;
145 else
146 ret = 0;
147 break;
148
149 case WDIOC_GETSTATUS:
150 ret = put_user(0, (int *)arg);
151 break;
152
153 case WDIOC_GETBOOTSTATUS:
154 ret = put_user(boot_status, (int *)arg);
155 break;
156
157 case WDIOC_GETTIMEOUT:
158 ret = put_user(iop_watchdog_timeout(), (int *)arg);
159 break;
160
161 case WDIOC_KEEPALIVE:
162 wdt_enable();
163 ret = 0;
164 break;
165
166 case WDIOC_SETOPTIONS:
167 if (get_user(options, (int *)arg))
168 return -EFAULT;
169
170 if (options & WDIOS_DISABLECARD) {
171 if (!nowayout) {
172 if (wdt_disable() == 0) {
173 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
174 ret = 0;
175 } else
176 ret = -ENXIO;
177 } else
178 ret = 0;
179 }
180
181 if (options & WDIOS_ENABLECARD) {
182 wdt_enable();
183 ret = 0;
184 }
185 break;
186 }
187
188 return ret;
189}
190
191static int iop_wdt_release(struct inode *inode, struct file *file)
192{
193 int state = 1;
194 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
195 if (test_bit(WDT_ENABLED, &wdt_status))
196 state = wdt_disable();
197
198 /* if the timer is not disbaled reload and notify that we are still
199 * going down
200 */
201 if (state != 0) {
202 wdt_enable();
203 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
204 "reset in %lu seconds\n", iop_watchdog_timeout());
205 }
206
207 clear_bit(WDT_IN_USE, &wdt_status);
208 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
209
210 return 0;
211}
212
213static const struct file_operations iop_wdt_fops = {
214 .owner = THIS_MODULE,
215 .llseek = no_llseek,
216 .write = iop_wdt_write,
217 .ioctl = iop_wdt_ioctl,
218 .open = iop_wdt_open,
219 .release = iop_wdt_release,
220};
221
222static struct miscdevice iop_wdt_miscdev = {
223 .minor = WATCHDOG_MINOR,
224 .name = "watchdog",
225 .fops = &iop_wdt_fops,
226};
227
228static int __init iop_wdt_init(void)
229{
230 int ret;
231
232 ret = misc_register(&iop_wdt_miscdev);
233 if (ret == 0)
234 printk("iop watchdog timer: timeout %lu sec\n",
235 iop_watchdog_timeout());
236
237 /* check if the reset was caused by the watchdog timer */
238 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
239
240 /* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset
241 * NOTE: An IB Reset will Reset both cores in the IOP342
242 */
243 write_wdtsr(IOP13XX_WDTCR_IB_RESET);
244
245 return ret;
246}
247
248static void __exit iop_wdt_exit(void)
249{
250 misc_deregister(&iop_wdt_miscdev);
251}
252
253module_init(iop_wdt_init);
254module_exit(iop_wdt_exit);
255
256module_param(nowayout, int, 0);
257MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
258
259MODULE_AUTHOR("Curt E Bruns <curt.e.bruns@intel.com>");
260MODULE_DESCRIPTION("iop watchdog timer driver");
261MODULE_LICENSE("GPL");
262MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index a0d27160c80e..6d35bb112a5f 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -321,6 +321,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
321 break; 321 break;
322 322
323 case WDIOC_GETSTATUS: 323 case WDIOC_GETSTATUS:
324 case WDIOC_GETBOOTSTATUS:
324 return put_user(0, p); 325 return put_user(0, p);
325 326
326 case WDIOC_KEEPALIVE: 327 case WDIOC_KEEPALIVE:
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index db2ccb864412..1adf1d56027d 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -215,6 +215,11 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
215 return -EFAULT; 215 return -EFAULT;
216 } 216 }
217 break; 217 break;
218 case WDIOC_GETBOOTSTATUS:
219 if (copy_to_user(p, &status, sizeof(int))) {
220 return -EFAULT;
221 }
222 break;
218 case WDIOC_GETSUPPORT: 223 case WDIOC_GETSUPPORT:
219 if (copy_to_user(argp, &ident, sizeof(ident))) { 224 if (copy_to_user(argp, &ident, sizeof(ident))) {
220 return -EFAULT; 225 return -EFAULT;
diff --git a/drivers/char/watchdog/mpc5200_wdt.c b/drivers/char/watchdog/mpc5200_wdt.c
new file mode 100644
index 000000000000..564143d40610
--- /dev/null
+++ b/drivers/char/watchdog/mpc5200_wdt.c
@@ -0,0 +1,286 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/miscdevice.h>
4#include <linux/watchdog.h>
5#include <linux/io.h>
6#include <linux/spinlock.h>
7#include <asm/of_platform.h>
8#include <asm/uaccess.h>
9#include <asm/mpc52xx.h>
10
11
12#define GPT_MODE_WDT (1<<15)
13#define GPT_MODE_CE (1<<12)
14#define GPT_MODE_MS_TIMER (0x4)
15
16
17struct mpc5200_wdt {
18 unsigned count; /* timer ticks before watchdog kicks in */
19 long ipb_freq;
20 struct miscdevice miscdev;
21 struct resource mem;
22 struct mpc52xx_gpt __iomem *regs;
23 spinlock_t io_lock;
24};
25
26/* is_active stores wether or not the /dev/watchdog device is opened */
27static unsigned long is_active;
28
29/* misc devices don't provide a way, to get back to 'dev' or 'miscdev' from
30 * file operations, which sucks. But there can be max 1 watchdog anyway, so...
31 */
32static struct mpc5200_wdt *wdt_global;
33
34
35/* helper to calculate timeout in timer counts */
36static void mpc5200_wdt_set_timeout(struct mpc5200_wdt *wdt, int timeout)
37{
38 /* use biggest prescaler of 64k */
39 wdt->count = (wdt->ipb_freq + 0xffff) / 0x10000 * timeout;
40
41 if (wdt->count > 0xffff)
42 wdt->count = 0xffff;
43}
44/* return timeout in seconds (calculated from timer count) */
45static int mpc5200_wdt_get_timeout(struct mpc5200_wdt *wdt)
46{
47 return wdt->count * 0x10000 / wdt->ipb_freq;
48}
49
50
51/* watchdog operations */
52static int mpc5200_wdt_start(struct mpc5200_wdt *wdt)
53{
54 spin_lock(&wdt->io_lock);
55 /* disable */
56 out_be32(&wdt->regs->mode, 0);
57 /* set timeout, with maximum prescaler */
58 out_be32(&wdt->regs->count, 0x0 | wdt->count);
59 /* enable watchdog */
60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER);
61 spin_unlock(&wdt->io_lock);
62
63 return 0;
64}
65static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt)
66{
67 spin_lock(&wdt->io_lock);
68 /* writing A5 to OCPW resets the watchdog */
69 out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode)));
70 spin_unlock(&wdt->io_lock);
71 return 0;
72}
73static int mpc5200_wdt_stop(struct mpc5200_wdt *wdt)
74{
75 spin_lock(&wdt->io_lock);
76 /* disable */
77 out_be32(&wdt->regs->mode, 0);
78 spin_unlock(&wdt->io_lock);
79 return 0;
80}
81
82
83/* file operations */
84static ssize_t mpc5200_wdt_write(struct file *file, const char *data,
85 size_t len, loff_t *ppos)
86{
87 struct mpc5200_wdt *wdt = file->private_data;
88 mpc5200_wdt_ping(wdt);
89 return 0;
90}
91static struct watchdog_info mpc5200_wdt_info = {
92 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
93 .identity = "mpc5200 watchdog on GPT0",
94};
95static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
96 unsigned int cmd, unsigned long arg)
97{
98 struct mpc5200_wdt *wdt = file->private_data;
99 int __user *data = (int __user *)arg;
100 int timeout;
101 int ret = 0;
102
103 switch (cmd) {
104 case WDIOC_GETSUPPORT:
105 ret = copy_to_user(data, &mpc5200_wdt_info,
106 sizeof(mpc5200_wdt_info));
107 if (ret)
108 ret = -EFAULT;
109 break;
110
111 case WDIOC_GETSTATUS:
112 case WDIOC_GETBOOTSTATUS:
113 ret = put_user(0, data);
114 break;
115
116 case WDIOC_KEEPALIVE:
117 mpc5200_wdt_ping(wdt);
118 break;
119
120 case WDIOC_SETTIMEOUT:
121 ret = get_user(timeout, data);
122 if (ret)
123 break;
124 mpc5200_wdt_set_timeout(wdt, timeout);
125 mpc5200_wdt_start(wdt);
126 /* fall through and return the timeout */
127
128 case WDIOC_GETTIMEOUT:
129 timeout = mpc5200_wdt_get_timeout(wdt);
130 ret = put_user(timeout, data);
131 break;
132
133 default:
134 ret = -ENOTTY;
135 }
136 return ret;
137}
138static int mpc5200_wdt_open(struct inode *inode, struct file *file)
139{
140 /* /dev/watchdog can only be opened once */
141 if (test_and_set_bit(0, &is_active))
142 return -EBUSY;
143
144 /* Set and activate the watchdog */
145 mpc5200_wdt_set_timeout(wdt_global, 30);
146 mpc5200_wdt_start(wdt_global);
147 file->private_data = wdt_global;
148 return nonseekable_open(inode, file);
149}
150static int mpc5200_wdt_release(struct inode *inode, struct file *file)
151{
152#if WATCHDOG_NOWAYOUT == 0
153 struct mpc5200_wdt *wdt = file->private_data;
154 mpc5200_wdt_stop(wdt);
155 wdt->count = 0; /* == disabled */
156#endif
157 clear_bit(0, &is_active);
158 return 0;
159}
160
161static struct file_operations mpc5200_wdt_fops = {
162 .owner = THIS_MODULE,
163 .write = mpc5200_wdt_write,
164 .ioctl = mpc5200_wdt_ioctl,
165 .open = mpc5200_wdt_open,
166 .release = mpc5200_wdt_release,
167};
168
169/* module operations */
170static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match)
171{
172 struct mpc5200_wdt *wdt;
173 int err;
174 const void *has_wdt;
175 int size;
176
177 has_wdt = of_get_property(op->node, "has-wdt", NULL);
178 if (!has_wdt)
179 return -ENODEV;
180
181 wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
182 if (!wdt)
183 return -ENOMEM;
184
185 wdt->ipb_freq = mpc52xx_find_ipb_freq(op->node);
186
187 err = of_address_to_resource(op->node, 0, &wdt->mem);
188 if (err)
189 goto out_free;
190 size = wdt->mem.end - wdt->mem.start + 1;
191 if (!request_mem_region(wdt->mem.start, size, "mpc5200_wdt")) {
192 err = -ENODEV;
193 goto out_free;
194 }
195 wdt->regs = ioremap(wdt->mem.start, size);
196 if (!wdt->regs) {
197 err = -ENODEV;
198 goto out_release;
199 }
200
201 dev_set_drvdata(&op->dev, wdt);
202 spin_lock_init(&wdt->io_lock);
203
204 wdt->miscdev = (struct miscdevice) {
205 .minor = WATCHDOG_MINOR,
206 .name = "watchdog",
207 .fops = &mpc5200_wdt_fops,
208 .parent = &op->dev,
209 };
210 wdt_global = wdt;
211 err = misc_register(&wdt->miscdev);
212 if (!err)
213 return 0;
214
215 iounmap(wdt->regs);
216 out_release:
217 release_mem_region(wdt->mem.start, size);
218 out_free:
219 kfree(wdt);
220 return err;
221}
222
223static int mpc5200_wdt_remove(struct of_device *op)
224{
225 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
226
227 mpc5200_wdt_stop(wdt);
228 misc_deregister(&wdt->miscdev);
229 iounmap(wdt->regs);
230 release_mem_region(wdt->mem.start, wdt->mem.end - wdt->mem.start + 1);
231 kfree(wdt);
232
233 return 0;
234}
235static int mpc5200_wdt_suspend(struct of_device *op, pm_message_t state)
236{
237 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
238 mpc5200_wdt_stop(wdt);
239 return 0;
240}
241static int mpc5200_wdt_resume(struct of_device *op)
242{
243 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
244 if (wdt->count)
245 mpc5200_wdt_start(wdt);
246 return 0;
247}
248static int mpc5200_wdt_shutdown(struct of_device *op)
249{
250 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
251 mpc5200_wdt_stop(wdt);
252 return 0;
253}
254
255static struct of_device_id mpc5200_wdt_match[] = {
256 { .compatible = "mpc5200-gpt", },
257 {},
258};
259static struct of_platform_driver mpc5200_wdt_driver = {
260 .owner = THIS_MODULE,
261 .name = "mpc5200-gpt-wdt",
262 .match_table = mpc5200_wdt_match,
263 .probe = mpc5200_wdt_probe,
264 .remove = mpc5200_wdt_remove,
265 .suspend = mpc5200_wdt_suspend,
266 .resume = mpc5200_wdt_resume,
267 .shutdown = mpc5200_wdt_shutdown,
268};
269
270
271static int __init mpc5200_wdt_init(void)
272{
273 return of_register_platform_driver(&mpc5200_wdt_driver);
274}
275
276static void __exit mpc5200_wdt_exit(void)
277{
278 of_unregister_platform_driver(&mpc5200_wdt_driver);
279}
280
281module_init(mpc5200_wdt_init);
282module_exit(mpc5200_wdt_exit);
283
284MODULE_AUTHOR("Domen Puncer <domen.puncer@telargo.com>");
285MODULE_LICENSE("Dual BSD/GPL");
286MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
index 18ca752e2f90..a0bf95fb9763 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -119,6 +119,9 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
119 switch (cmd) { 119 switch (cmd) {
120 case WDIOC_GETSUPPORT: 120 case WDIOC_GETSUPPORT:
121 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 121 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
122 case WDIOC_GETSTATUS:
123 case WDIOC_GETBOOTSTATUS:
124 return put_user(0, p);
122 case WDIOC_KEEPALIVE: 125 case WDIOC_KEEPALIVE:
123 mpc83xx_wdt_keepalive(); 126 mpc83xx_wdt_keepalive();
124 return 0; 127 return 0;
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 8aaed10dd499..85b5734403a5 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -57,7 +57,7 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
57 m8xx_wdt_reset(); 57 m8xx_wdt_reset();
58 mpc8xx_wdt_handler_disable(); 58 mpc8xx_wdt_handler_disable();
59 59
60 return 0; 60 return nonseekable_open(inode, file);
61} 61}
62 62
63static int mpc8xx_wdt_release(struct inode *inode, struct file *file) 63static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index e88947f8fe53..0d2b27735419 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -328,12 +328,11 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
328 goto err_out; 328 goto err_out;
329 } 329 }
330 330
331 wdt = kmalloc(sizeof(struct mpcore_wdt), GFP_KERNEL); 331 wdt = kzalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
332 if (!wdt) { 332 if (!wdt) {
333 ret = -ENOMEM; 333 ret = -ENOMEM;
334 goto err_out; 334 goto err_out;
335 } 335 }
336 memset(wdt, 0, sizeof(struct mpcore_wdt));
337 336
338 wdt->dev = &dev->dev; 337 wdt->dev = &dev->dev;
339 wdt->irq = platform_get_irq(dev, 0); 338 wdt->irq = platform_get_irq(dev, 0);
diff --git a/drivers/char/watchdog/mtx-1_wdt.c b/drivers/char/watchdog/mtx-1_wdt.c
index 419ab445c944..dcfd401a7ad7 100644
--- a/drivers/char/watchdog/mtx-1_wdt.c
+++ b/drivers/char/watchdog/mtx-1_wdt.c
@@ -143,6 +143,7 @@ static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int c
143 mtx1_wdt_reset(); 143 mtx1_wdt_reset();
144 break; 144 break;
145 case WDIOC_GETSTATUS: 145 case WDIOC_GETSTATUS:
146 case WDIOC_GETBOOTSTATUS:
146 if ( copy_to_user(argp, &value, sizeof(int)) ) 147 if ( copy_to_user(argp, &value, sizeof(int)) )
147 return -EFAULT; 148 return -EFAULT;
148 break; 149 break;
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index b887cdb01334..0365c317f7e1 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -23,61 +23,101 @@
23#include <linux/watchdog.h> 23#include <linux/watchdog.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/mv64x60.h> 26#include <linux/mv643xx.h>
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <asm/io.h> 28#include <asm/io.h>
29 29
30/* MV64x60 WDC (config) register access definitions */ 30#define MV64x60_WDT_WDC_OFFSET 0
31#define MV64x60_WDC_CTL1_MASK (3 << 24) 31
32#define MV64x60_WDC_CTL1(val) ((val & 3) << 24) 32/*
33#define MV64x60_WDC_CTL2_MASK (3 << 26) 33 * The watchdog configuration register contains a pair of 2-bit fields,
34#define MV64x60_WDC_CTL2(val) ((val & 3) << 26) 34 * 1. a reload field, bits 27-26, which triggers a reload of
35 * the countdown register, and
36 * 2. an enable field, bits 25-24, which toggles between
37 * enabling and disabling the watchdog timer.
38 * Bit 31 is a read-only field which indicates whether the
39 * watchdog timer is currently enabled.
40 *
41 * The low 24 bits contain the timer reload value.
42 */
43#define MV64x60_WDC_ENABLE_SHIFT 24
44#define MV64x60_WDC_SERVICE_SHIFT 26
45#define MV64x60_WDC_ENABLED_SHIFT 31
46
47#define MV64x60_WDC_ENABLED_TRUE 1
48#define MV64x60_WDC_ENABLED_FALSE 0
35 49
36/* Flags bits */ 50/* Flags bits */
37#define MV64x60_WDOG_FLAG_OPENED 0 51#define MV64x60_WDOG_FLAG_OPENED 0
38#define MV64x60_WDOG_FLAG_ENABLED 1
39 52
40static unsigned long wdt_flags; 53static unsigned long wdt_flags;
41static int wdt_status; 54static int wdt_status;
42static void __iomem *mv64x60_regs; 55static void __iomem *mv64x60_wdt_regs;
43static int mv64x60_wdt_timeout; 56static int mv64x60_wdt_timeout;
57static int mv64x60_wdt_count;
58static unsigned int bus_clk;
59static char expect_close;
60static DEFINE_SPINLOCK(mv64x60_wdt_spinlock);
61
62static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 65
45static void mv64x60_wdt_reg_write(u32 val) 66static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift)
46{ 67{
47 /* Allow write only to CTL1 / CTL2 fields, retaining values in 68 u32 data;
48 * other fields. 69 u32 enabled;
49 */ 70 int ret = 0;
50 u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC); 71
51 data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK); 72 spin_lock(&mv64x60_wdt_spinlock);
52 data |= val; 73 data = readl(mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
53 writel(data, mv64x60_regs + MV64x60_WDT_WDC); 74 enabled = (data >> MV64x60_WDC_ENABLED_SHIFT) & 1;
75
76 /* only toggle the requested field if enabled state matches predicate */
77 if ((enabled ^ enabled_predicate) == 0) {
78 /* We write a 1, then a 2 -- to the appropriate field */
79 data = (1 << field_shift) | mv64x60_wdt_count;
80 writel(data, mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
81
82 data = (2 << field_shift) | mv64x60_wdt_count;
83 writel(data, mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
84 ret = 1;
85 }
86 spin_unlock(&mv64x60_wdt_spinlock);
87
88 return ret;
54} 89}
55 90
56static void mv64x60_wdt_service(void) 91static void mv64x60_wdt_service(void)
57{ 92{
58 /* Write 01 followed by 10 to CTL2 */ 93 mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_TRUE,
59 mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01)); 94 MV64x60_WDC_SERVICE_SHIFT);
60 mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02)); 95}
96
97static void mv64x60_wdt_handler_enable(void)
98{
99 if (mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_FALSE,
100 MV64x60_WDC_ENABLE_SHIFT)) {
101 mv64x60_wdt_service();
102 printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
103 }
61} 104}
62 105
63static void mv64x60_wdt_handler_disable(void) 106static void mv64x60_wdt_handler_disable(void)
64{ 107{
65 if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) { 108 if (mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_TRUE,
66 /* Write 01 followed by 10 to CTL1 */ 109 MV64x60_WDC_ENABLE_SHIFT))
67 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
68 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
69 printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n"); 110 printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
70 }
71} 111}
72 112
73static void mv64x60_wdt_handler_enable(void) 113static void mv64x60_wdt_set_timeout(unsigned int timeout)
74{ 114{
75 if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) { 115 /* maximum bus cycle count is 0xFFFFFFFF */
76 /* Write 01 followed by 10 to CTL1 */ 116 if (timeout > 0xFFFFFFFF / bus_clk)
77 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01)); 117 timeout = 0xFFFFFFFF / bus_clk;
78 mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02)); 118
79 printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n"); 119 mv64x60_wdt_count = timeout * bus_clk >> 8;
80 } 120 mv64x60_wdt_timeout = timeout;
81} 121}
82 122
83static int mv64x60_wdt_open(struct inode *inode, struct file *file) 123static int mv64x60_wdt_open(struct inode *inode, struct file *file)
@@ -85,21 +125,24 @@ static int mv64x60_wdt_open(struct inode *inode, struct file *file)
85 if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags)) 125 if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
86 return -EBUSY; 126 return -EBUSY;
87 127
88 mv64x60_wdt_service(); 128 if (nowayout)
89 mv64x60_wdt_handler_enable(); 129 __module_get(THIS_MODULE);
90 130
91 nonseekable_open(inode, file); 131 mv64x60_wdt_handler_enable();
92 132
93 return 0; 133 return nonseekable_open(inode, file);
94} 134}
95 135
96static int mv64x60_wdt_release(struct inode *inode, struct file *file) 136static int mv64x60_wdt_release(struct inode *inode, struct file *file)
97{ 137{
98 mv64x60_wdt_service(); 138 if (expect_close == 42)
99 139 mv64x60_wdt_handler_disable();
100#if !defined(CONFIG_WATCHDOG_NOWAYOUT) 140 else {
101 mv64x60_wdt_handler_disable(); 141 printk(KERN_CRIT
102#endif 142 "mv64x60_wdt: unexpected close, not stopping timer!\n");
143 mv64x60_wdt_service();
144 }
145 expect_close = 0;
103 146
104 clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags); 147 clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
105 148
@@ -109,8 +152,22 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
109static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, 152static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
110 size_t len, loff_t * ppos) 153 size_t len, loff_t * ppos)
111{ 154{
112 if (len) 155 if (len) {
156 if (!nowayout) {
157 size_t i;
158
159 expect_close = 0;
160
161 for (i = 0; i != len; i++) {
162 char c;
163 if(get_user(c, data + i))
164 return -EFAULT;
165 if (c == 'V')
166 expect_close = 42;
167 }
168 }
113 mv64x60_wdt_service(); 169 mv64x60_wdt_service();
170 }
114 171
115 return len; 172 return len;
116} 173}
@@ -119,9 +176,12 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
119 unsigned int cmd, unsigned long arg) 176 unsigned int cmd, unsigned long arg)
120{ 177{
121 int timeout; 178 int timeout;
179 int options;
122 void __user *argp = (void __user *)arg; 180 void __user *argp = (void __user *)arg;
123 static struct watchdog_info info = { 181 static struct watchdog_info info = {
124 .options = WDIOF_KEEPALIVEPING, 182 .options = WDIOF_SETTIMEOUT |
183 WDIOF_MAGICCLOSE |
184 WDIOF_KEEPALIVEPING,
125 .firmware_version = 0, 185 .firmware_version = 0,
126 .identity = "MV64x60 watchdog", 186 .identity = "MV64x60 watchdog",
127 }; 187 };
@@ -143,7 +203,15 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
143 return -EOPNOTSUPP; 203 return -EOPNOTSUPP;
144 204
145 case WDIOC_SETOPTIONS: 205 case WDIOC_SETOPTIONS:
146 return -EOPNOTSUPP; 206 if (get_user(options, (int __user *)argp))
207 return -EFAULT;
208
209 if (options & WDIOS_DISABLECARD)
210 mv64x60_wdt_handler_disable();
211
212 if (options & WDIOS_ENABLECARD)
213 mv64x60_wdt_handler_enable();
214 break;
147 215
148 case WDIOC_KEEPALIVE: 216 case WDIOC_KEEPALIVE:
149 mv64x60_wdt_service(); 217 mv64x60_wdt_service();
@@ -151,11 +219,13 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
151 break; 219 break;
152 220
153 case WDIOC_SETTIMEOUT: 221 case WDIOC_SETTIMEOUT:
154 return -EOPNOTSUPP; 222 if (get_user(timeout, (int __user *)argp))
223 return -EFAULT;
224 mv64x60_wdt_set_timeout(timeout);
225 /* Fall through */
155 226
156 case WDIOC_GETTIMEOUT: 227 case WDIOC_GETTIMEOUT:
157 timeout = mv64x60_wdt_timeout * HZ; 228 if (put_user(mv64x60_wdt_timeout, (int __user *)argp))
158 if (put_user(timeout, (int __user *)argp))
159 return -EFAULT; 229 return -EFAULT;
160 break; 230 break;
161 231
@@ -184,18 +254,33 @@ static struct miscdevice mv64x60_wdt_miscdev = {
184static int __devinit mv64x60_wdt_probe(struct platform_device *dev) 254static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
185{ 255{
186 struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data; 256 struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data;
187 int bus_clk = 133; 257 struct resource *r;
258 int timeout = 10;
188 259
189 mv64x60_wdt_timeout = 10; 260 bus_clk = 133; /* in MHz */
190 if (pdata) { 261 if (pdata) {
191 mv64x60_wdt_timeout = pdata->timeout; 262 timeout = pdata->timeout;
192 bus_clk = pdata->bus_clk; 263 bus_clk = pdata->bus_clk;
193 } 264 }
194 265
195 mv64x60_regs = mv64x60_get_bridge_vbase(); 266 /* Since bus_clk is truncated MHz, actual frequency could be
267 * up to 1MHz higher. Round up, since it's better to time out
268 * too late than too soon.
269 */
270 bus_clk++;
271 bus_clk *= 1000000; /* convert to Hz */
272
273 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
274 if (!r)
275 return -ENODEV;
196 276
197 writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8, 277 mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1);
198 mv64x60_regs + MV64x60_WDT_WDC); 278 if (mv64x60_wdt_regs == NULL)
279 return -ENOMEM;
280
281 mv64x60_wdt_set_timeout(timeout);
282
283 mv64x60_wdt_handler_disable(); /* in case timer was already running */
199 284
200 return misc_register(&mv64x60_wdt_miscdev); 285 return misc_register(&mv64x60_wdt_miscdev);
201} 286}
@@ -204,9 +289,10 @@ static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
204{ 289{
205 misc_deregister(&mv64x60_wdt_miscdev); 290 misc_deregister(&mv64x60_wdt_miscdev);
206 291
207 mv64x60_wdt_service();
208 mv64x60_wdt_handler_disable(); 292 mv64x60_wdt_handler_disable();
209 293
294 iounmap(mv64x60_wdt_regs);
295
210 return 0; 296 return 0;
211} 297}
212 298
@@ -219,40 +305,16 @@ static struct platform_driver mv64x60_wdt_driver = {
219 }, 305 },
220}; 306};
221 307
222static struct platform_device *mv64x60_wdt_dev;
223
224static int __init mv64x60_wdt_init(void) 308static int __init mv64x60_wdt_init(void)
225{ 309{
226 int ret;
227
228 printk(KERN_INFO "MV64x60 watchdog driver\n"); 310 printk(KERN_INFO "MV64x60 watchdog driver\n");
229 311
230 mv64x60_wdt_dev = platform_device_alloc(MV64x60_WDT_NAME, -1); 312 return platform_driver_register(&mv64x60_wdt_driver);
231 if (!mv64x60_wdt_dev) {
232 ret = -ENOMEM;
233 goto out;
234 }
235
236 ret = platform_device_add(mv64x60_wdt_dev);
237 if (ret) {
238 platform_device_put(mv64x60_wdt_dev);
239 goto out;
240 }
241
242 ret = platform_driver_register(&mv64x60_wdt_driver);
243 if (ret) {
244 platform_device_unregister(mv64x60_wdt_dev);
245 goto out;
246 }
247
248 out:
249 return ret;
250} 313}
251 314
252static void __exit mv64x60_wdt_exit(void) 315static void __exit mv64x60_wdt_exit(void)
253{ 316{
254 platform_driver_unregister(&mv64x60_wdt_driver); 317 platform_driver_unregister(&mv64x60_wdt_driver);
255 platform_device_unregister(mv64x60_wdt_dev);
256} 318}
257 319
258module_init(mv64x60_wdt_init); 320module_init(mv64x60_wdt_init);
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
index b36fa8de2131..719b066f73c4 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -142,7 +142,7 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
142 142
143 omap_wdt_set_timeout(); 143 omap_wdt_set_timeout();
144 omap_wdt_enable(); 144 omap_wdt_enable();
145 return 0; 145 return nonseekable_open(inode, file);
146} 146}
147 147
148static int omap_wdt_release(struct inode *inode, struct file *file) 148static int omap_wdt_release(struct inode *inode, struct file *file)
@@ -197,7 +197,7 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
197 197
198 switch (cmd) { 198 switch (cmd) {
199 default: 199 default:
200 return -ENOIOCTLCMD; 200 return -ENOTTY;
201 case WDIOC_GETSUPPORT: 201 case WDIOC_GETSUPPORT:
202 return copy_to_user((struct watchdog_info __user *)arg, &ident, 202 return copy_to_user((struct watchdog_info __user *)arg, &ident,
203 sizeof(ident)); 203 sizeof(ident));
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 1e7a6719d5ba..0f3fd6c9c354 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -626,12 +626,11 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
626 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); 626 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
627 627
628 /* allocate memory for our device and initialize it */ 628 /* allocate memory for our device and initialize it */
629 usb_pcwd = kmalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL); 629 usb_pcwd = kzalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL);
630 if (usb_pcwd == NULL) { 630 if (usb_pcwd == NULL) {
631 printk(KERN_ERR PFX "Out of memory\n"); 631 printk(KERN_ERR PFX "Out of memory\n");
632 goto error; 632 goto error;
633 } 633 }
634 memset (usb_pcwd, 0x00, sizeof (*usb_pcwd));
635 634
636 usb_pcwd_device = usb_pcwd; 635 usb_pcwd_device = usb_pcwd;
637 636
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 50430bced2f2..5d1c15f83d23 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -52,10 +52,10 @@
52 52
53#include <asm/arch/map.h> 53#include <asm/arch/map.h>
54 54
55#undef S3C24XX_VA_WATCHDOG 55#undef S3C_VA_WATCHDOG
56#define S3C24XX_VA_WATCHDOG (0) 56#define S3C_VA_WATCHDOG (0)
57 57
58#include <asm/arch/regs-watchdog.h> 58#include <asm/plat-s3c/regs-watchdog.h>
59 59
60#define PFX "s3c2410-wdt: " 60#define PFX "s3c2410-wdt: "
61 61
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 33c1137f17d6..3475f47aaa45 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -45,7 +45,6 @@ static int boot_status;
45 */ 45 */
46static int sa1100dog_open(struct inode *inode, struct file *file) 46static int sa1100dog_open(struct inode *inode, struct file *file)
47{ 47{
48 nonseekable_open(inode, file);
49 if (test_and_set_bit(1,&sa1100wdt_users)) 48 if (test_and_set_bit(1,&sa1100wdt_users))
50 return -EBUSY; 49 return -EBUSY;
51 50
@@ -54,7 +53,7 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
54 OSSR = OSSR_M3; 53 OSSR = OSSR_M3;
55 OWER = OWER_WME; 54 OWER = OWER_WME;
56 OIER |= OIER_E3; 55 OIER |= OIER_E3;
57 return 0; 56 return nonseekable_open(inode, file);
58} 57}
59 58
60/* 59/*
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index b6282039198c..e4f3cb6090bc 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -191,8 +191,6 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
191 191
192static int fop_open(struct inode * inode, struct file * file) 192static int fop_open(struct inode * inode, struct file * file)
193{ 193{
194 nonseekable_open(inode, file);
195
196 /* Just in case we're already talking to someone... */ 194 /* Just in case we're already talking to someone... */
197 if(test_and_set_bit(0, &wdt_is_open)) 195 if(test_and_set_bit(0, &wdt_is_open))
198 return -EBUSY; 196 return -EBUSY;
@@ -202,7 +200,7 @@ static int fop_open(struct inode * inode, struct file * file)
202 200
203 /* Good, fire up the show */ 201 /* Good, fire up the show */
204 wdt_startup(); 202 wdt_startup();
205 return 0; 203 return nonseekable_open(inode, file);
206} 204}
207 205
208static int fop_close(struct inode * inode, struct file * file) 206static int fop_close(struct inode * inode, struct file * file)
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index 2f7ba7a514fe..9670d47190d0 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -150,8 +150,6 @@ static inline int sc1200wdt_status(void)
150 150
151static int sc1200wdt_open(struct inode *inode, struct file *file) 151static int sc1200wdt_open(struct inode *inode, struct file *file)
152{ 152{
153 nonseekable_open(inode, file);
154
155 /* allow one at a time */ 153 /* allow one at a time */
156 if (down_trylock(&open_sem)) 154 if (down_trylock(&open_sem))
157 return -EBUSY; 155 return -EBUSY;
@@ -162,7 +160,7 @@ static int sc1200wdt_open(struct inode *inode, struct file *file)
162 sc1200wdt_start(); 160 sc1200wdt_start();
163 printk(KERN_INFO PFX "Watchdog enabled, timeout = %d min(s)", timeout); 161 printk(KERN_INFO PFX "Watchdog enabled, timeout = %d min(s)", timeout);
164 162
165 return 0; 163 return nonseekable_open(inode, file);
166} 164}
167 165
168 166
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 2676a43895a7..e8594c64d1e6 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -248,8 +248,6 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
248 248
249static int fop_open(struct inode * inode, struct file * file) 249static int fop_open(struct inode * inode, struct file * file)
250{ 250{
251 nonseekable_open(inode, file);
252
253 /* Just in case we're already talking to someone... */ 251 /* Just in case we're already talking to someone... */
254 if(test_and_set_bit(0, &wdt_is_open)) 252 if(test_and_set_bit(0, &wdt_is_open))
255 return -EBUSY; 253 return -EBUSY;
@@ -258,7 +256,7 @@ static int fop_open(struct inode * inode, struct file * file)
258 256
259 /* Good, fire up the show */ 257 /* Good, fire up the show */
260 wdt_startup(); 258 wdt_startup();
261 return 0; 259 return nonseekable_open(inode, file);
262} 260}
263 261
264static int fop_close(struct inode * inode, struct file * file) 262static int fop_close(struct inode * inode, struct file * file)
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index b46e7f47d705..df33b3b5a53c 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -4,7 +4,7 @@
4 * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com> 4 * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com>
5 * added support for W83627THF. 5 * added support for W83627THF.
6 * 6 *
7 * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com> 7 * (c) Copyright 2003,2007 Pádraig Brady <P@draigBrady.com>
8 * 8 *
9 * Based on advantechwdt.c which is based on wdt.c. 9 * Based on advantechwdt.c which is based on wdt.c.
10 * Original copyright messages: 10 * Original copyright messages:
@@ -42,7 +42,7 @@
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#define WATCHDOG_NAME "w83627hf/thf WDT" 45#define WATCHDOG_NAME "w83627hf/thf/hg WDT"
46#define PFX WATCHDOG_NAME ": " 46#define PFX WATCHDOG_NAME ": "
47#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 47#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
48 48
@@ -57,7 +57,7 @@ MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)");
57 57
58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
59module_param(timeout, int, 0); 59module_param(timeout, int, 0);
60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
61 61
62static int nowayout = WATCHDOG_NOWAYOUT; 62static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 63module_param(nowayout, int, 0);
@@ -78,9 +78,9 @@ w83627hf_select_wd_register(void)
78 outb_p(0x87, WDT_EFER); /* Enter extended function mode */ 78 outb_p(0x87, WDT_EFER); /* Enter extended function mode */
79 outb_p(0x87, WDT_EFER); /* Again according to manual */ 79 outb_p(0x87, WDT_EFER); /* Again according to manual */
80 80
81 outb(0x20, WDT_EFER); /* check chip version */ 81 outb(0x20, WDT_EFER); /* check chip version */
82 c = inb(WDT_EFDR); 82 c = inb(WDT_EFDR);
83 if (c == 0x82) { /* W83627THF */ 83 if (c == 0x82) { /* W83627THF */
84 outb_p(0x2b, WDT_EFER); /* select GPIO3 */ 84 outb_p(0x2b, WDT_EFER); /* select GPIO3 */
85 c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ 85 c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */
86 outb_p(0x2b, WDT_EFER); 86 outb_p(0x2b, WDT_EFER);
@@ -114,11 +114,17 @@ w83627hf_init(void)
114 printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); 114 printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout);
115 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ 115 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */
116 } 116 }
117
117 outb_p(0xF5, WDT_EFER); /* Select CRF5 */ 118 outb_p(0xF5, WDT_EFER); /* Select CRF5 */
118 t=inb_p(WDT_EFDR); /* read CRF5 */ 119 t=inb_p(WDT_EFDR); /* read CRF5 */
119 t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ 120 t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */
120 outb_p(t, WDT_EFDR); /* Write back to CRF5 */ 121 outb_p(t, WDT_EFDR); /* Write back to CRF5 */
121 122
123 outb_p(0xF7, WDT_EFER); /* Select CRF7 */
124 t=inb_p(WDT_EFDR); /* read CRF7 */
125 t&=~0xC0; /* disable keyboard & mouse turning off watchdog */
126 outb_p(t, WDT_EFDR); /* Write back to CRF7 */
127
122 w83627hf_unselect_wd_register(); 128 w83627hf_unselect_wd_register();
123} 129}
124 130
@@ -126,7 +132,7 @@ static void
126wdt_ctrl(int timeout) 132wdt_ctrl(int timeout)
127{ 133{
128 spin_lock(&io_lock); 134 spin_lock(&io_lock);
129 135
130 w83627hf_select_wd_register(); 136 w83627hf_select_wd_register();
131 137
132 outb_p(0xF6, WDT_EFER); /* Select CRF6 */ 138 outb_p(0xF6, WDT_EFER); /* Select CRF6 */
@@ -154,7 +160,7 @@ wdt_disable(void)
154static int 160static int
155wdt_set_heartbeat(int t) 161wdt_set_heartbeat(int t)
156{ 162{
157 if ((t < 1) || (t > 63)) 163 if ((t < 1) || (t > 255))
158 return -EINVAL; 164 return -EINVAL;
159 165
160 timeout = t; 166 timeout = t;
@@ -324,11 +330,11 @@ wdt_init(void)
324 330
325 spin_lock_init(&io_lock); 331 spin_lock_init(&io_lock);
326 332
327 printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF/THF Super I/O chip initialising.\n"); 333 printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF/THF/HG Super I/O chip initialising.\n");
328 334
329 if (wdt_set_heartbeat(timeout)) { 335 if (wdt_set_heartbeat(timeout)) {
330 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 336 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
331 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=63, using %d\n", 337 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n",
332 WATCHDOG_TIMEOUT); 338 WATCHDOG_TIMEOUT);
333 } 339 }
334 340