diff options
Diffstat (limited to 'drivers/char')
39 files changed, 1548 insertions, 562 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index c29365d5b524..fdf4370db994 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -661,7 +661,7 @@ config HW_RANDOM | |||
661 | 661 | ||
662 | config NVRAM | 662 | config NVRAM |
663 | tristate "/dev/nvram support" | 663 | tristate "/dev/nvram support" |
664 | depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM | 664 | depends on ATARI || X86 || ARM || GENERIC_NVRAM |
665 | ---help--- | 665 | ---help--- |
666 | If you say Y here and create a character special file /dev/nvram | 666 | If you say Y here and create a character special file /dev/nvram |
667 | with major number 10 and minor number 144 using mknod ("man mknod"), | 667 | with major number 10 and minor number 144 using mknod ("man mknod"), |
@@ -985,7 +985,7 @@ config MAX_RAW_DEVS | |||
985 | 985 | ||
986 | config HANGCHECK_TIMER | 986 | config HANGCHECK_TIMER |
987 | tristate "Hangcheck timer" | 987 | tristate "Hangcheck timer" |
988 | depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390 | 988 | depends on X86 || IA64 || PPC64 || ARCH_S390 |
989 | help | 989 | help |
990 | The hangcheck-timer module detects when the system has gone | 990 | The hangcheck-timer module detects when the system has gone |
991 | out to lunch past a certain margin. It can reboot the system | 991 | out to lunch past a certain margin. It can reboot the system |
@@ -1001,5 +1001,17 @@ config MMTIMER | |||
1001 | 1001 | ||
1002 | source "drivers/char/tpm/Kconfig" | 1002 | source "drivers/char/tpm/Kconfig" |
1003 | 1003 | ||
1004 | config TELCLOCK | ||
1005 | tristate "Telecom clock driver for MPBL0010 ATCA SBC" | ||
1006 | depends on EXPERIMENTAL | ||
1007 | default n | ||
1008 | help | ||
1009 | The telecom clock device is specific to the MPBL0010 ATCA computer and | ||
1010 | allows direct userspace access to the configuration of the telecom clock | ||
1011 | configuration settings. This device is used for hardware synchronization | ||
1012 | across the ATCA backplane fabric. Upon loading, the driver exports a | ||
1013 | sysfs directory, /sys/devices/platform/telco_clock, with a number of | ||
1014 | files for controlling the behavior of this hardware. | ||
1015 | |||
1004 | endmenu | 1016 | endmenu |
1005 | 1017 | ||
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 08f69287ea36..4aeae687e88a 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -82,6 +82,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o | |||
82 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o | 82 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o |
83 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | 83 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o |
84 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o | 84 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o |
85 | obj-$(CONFIG_TELCLOCK) += tlclk.o | ||
85 | 86 | ||
86 | obj-$(CONFIG_WATCHDOG) += watchdog/ | 87 | obj-$(CONFIG_WATCHDOG) += watchdog/ |
87 | obj-$(CONFIG_MWAVE) += mwave/ | 88 | obj-$(CONFIG_MWAVE) += mwave/ |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 7f8c1b53b754..486ed8a11b59 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -27,7 +27,7 @@ config AGP | |||
27 | 27 | ||
28 | config AGP_ALI | 28 | config AGP_ALI |
29 | tristate "ALI chipset support" | 29 | tristate "ALI chipset support" |
30 | depends on AGP && X86 && !X86_64 | 30 | depends on AGP && X86_32 |
31 | ---help--- | 31 | ---help--- |
32 | This option gives you AGP support for the GLX component of | 32 | This option gives you AGP support for the GLX component of |
33 | XFree86 4.x on the following ALi chipsets. The supported chipsets | 33 | XFree86 4.x on the following ALi chipsets. The supported chipsets |
@@ -45,7 +45,7 @@ config AGP_ALI | |||
45 | 45 | ||
46 | config AGP_ATI | 46 | config AGP_ATI |
47 | tristate "ATI chipset support" | 47 | tristate "ATI chipset support" |
48 | depends on AGP && X86 && !X86_64 | 48 | depends on AGP && X86_32 |
49 | ---help--- | 49 | ---help--- |
50 | This option gives you AGP support for the GLX component of | 50 | This option gives you AGP support for the GLX component of |
51 | XFree86 4.x on the ATI RadeonIGP family of chipsets. | 51 | XFree86 4.x on the ATI RadeonIGP family of chipsets. |
@@ -55,7 +55,7 @@ config AGP_ATI | |||
55 | 55 | ||
56 | config AGP_AMD | 56 | config AGP_AMD |
57 | tristate "AMD Irongate, 761, and 762 chipset support" | 57 | tristate "AMD Irongate, 761, and 762 chipset support" |
58 | depends on AGP && X86 && !X86_64 | 58 | depends on AGP && X86_32 |
59 | help | 59 | help |
60 | This option gives you AGP support for the GLX component of | 60 | This option gives you AGP support for the GLX component of |
61 | XFree86 4.x on AMD Irongate, 761, and 762 chipsets. | 61 | XFree86 4.x on AMD Irongate, 761, and 762 chipsets. |
@@ -91,7 +91,7 @@ config AGP_INTEL | |||
91 | 91 | ||
92 | config AGP_NVIDIA | 92 | config AGP_NVIDIA |
93 | tristate "NVIDIA nForce/nForce2 chipset support" | 93 | tristate "NVIDIA nForce/nForce2 chipset support" |
94 | depends on AGP && X86 && !X86_64 | 94 | depends on AGP && X86_32 |
95 | help | 95 | help |
96 | This option gives you AGP support for the GLX component of | 96 | This option gives you AGP support for the GLX component of |
97 | XFree86 4.x on the following NVIDIA chipsets. The supported chipsets | 97 | XFree86 4.x on the following NVIDIA chipsets. The supported chipsets |
@@ -99,7 +99,7 @@ config AGP_NVIDIA | |||
99 | 99 | ||
100 | config AGP_SIS | 100 | config AGP_SIS |
101 | tristate "SiS chipset support" | 101 | tristate "SiS chipset support" |
102 | depends on AGP && X86 && !X86_64 | 102 | depends on AGP && X86_32 |
103 | help | 103 | help |
104 | This option gives you AGP support for the GLX component of | 104 | This option gives you AGP support for the GLX component of |
105 | XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. | 105 | XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. |
@@ -111,14 +111,14 @@ config AGP_SIS | |||
111 | 111 | ||
112 | config AGP_SWORKS | 112 | config AGP_SWORKS |
113 | tristate "Serverworks LE/HE chipset support" | 113 | tristate "Serverworks LE/HE chipset support" |
114 | depends on AGP && X86 && !X86_64 | 114 | depends on AGP && X86_32 |
115 | help | 115 | help |
116 | Say Y here to support the Serverworks AGP card. See | 116 | Say Y here to support the Serverworks AGP card. See |
117 | <http://www.serverworks.com/> for product descriptions and images. | 117 | <http://www.serverworks.com/> for product descriptions and images. |
118 | 118 | ||
119 | config AGP_VIA | 119 | config AGP_VIA |
120 | tristate "VIA chipset support" | 120 | tristate "VIA chipset support" |
121 | depends on AGP && X86 && !X86_64 | 121 | depends on AGP && X86_32 |
122 | help | 122 | help |
123 | This option gives you AGP support for the GLX component of | 123 | This option gives you AGP support for the GLX component of |
124 | XFree86 4.x on VIA MVP3/Apollo Pro chipsets. | 124 | XFree86 4.x on VIA MVP3/Apollo Pro chipsets. |
@@ -154,7 +154,7 @@ config AGP_UNINORTH | |||
154 | 154 | ||
155 | config AGP_EFFICEON | 155 | config AGP_EFFICEON |
156 | tristate "Transmeta Efficeon support" | 156 | tristate "Transmeta Efficeon support" |
157 | depends on AGP && X86 && !X86_64 | 157 | depends on AGP && X86_32 |
158 | help | 158 | help |
159 | This option gives you AGP support for the Transmeta Efficeon | 159 | This option gives you AGP support for the Transmeta Efficeon |
160 | series processors with integrated northbridges. | 160 | series processors with integrated northbridges. |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 9c9c9c2247ce..b02fc2267159 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/agp_backend.h> | 9 | #include <linux/agp_backend.h> |
10 | #include <asm/page.h> /* PAGE_SIZE */ | ||
10 | #include "agp.h" | 11 | #include "agp.h" |
11 | 12 | ||
12 | #define ALI_AGPCTRL 0xb8 | 13 | #define ALI_AGPCTRL 0xb8 |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 0a7624a9b1c1..0e6c3a31d344 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/agp_backend.h> | 15 | #include <linux/agp_backend.h> |
16 | #include <asm/page.h> /* PAGE_SIZE */ | ||
16 | #include "agp.h" | 17 | #include "agp.h" |
17 | 18 | ||
18 | /* Will need to be increased if AMD64 ever goes >8-way. */ | 19 | /* Will need to be increased if AMD64 ever goes >8-way. */ |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index e572ced9100a..0b6e72642d6e 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/string.h> | ||
10 | #include <linux/slab.h> | ||
9 | #include <linux/agp_backend.h> | 11 | #include <linux/agp_backend.h> |
10 | #include <asm/agp.h> | 12 | #include <asm/agp.h> |
11 | #include "agp.h" | 13 | #include "agp.h" |
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 94943298c03e..a2d9e5e48bbe 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/string.h> | ||
14 | #include <linux/slab.h> | ||
13 | #include <linux/agp_backend.h> | 15 | #include <linux/agp_backend.h> |
14 | 16 | ||
15 | #include "agp.h" | 17 | #include "agp.h" |
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c index c9ac731504f2..40083241804e 100644 --- a/drivers/char/agp/isoch.c +++ b/drivers/char/agp/isoch.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/agp_backend.h> | 7 | #include <linux/agp_backend.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/slab.h> | ||
9 | 10 | ||
10 | #include "agp.h" | 11 | #include "agp.h" |
11 | 12 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index a9fb12c20eb7..71ea59a1dbeb 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/string.h> | ||
9 | #include <linux/slab.h> | ||
8 | #include <linux/agp_backend.h> | 10 | #include <linux/agp_backend.h> |
9 | #include "agp.h" | 11 | #include "agp.h" |
10 | 12 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index cf4c3648463d..c7f818cd7b02 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -281,7 +281,7 @@ static char rcsid[] = | |||
281 | * make sure "cyc" appears in all kernel messages; all soft interrupts | 281 | * make sure "cyc" appears in all kernel messages; all soft interrupts |
282 | * handled by same routine; recognize out-of-band reception; comment | 282 | * handled by same routine; recognize out-of-band reception; comment |
283 | * out some diagnostic messages; leave RTS/CTS flow control to hardware; | 283 | * out some diagnostic messages; leave RTS/CTS flow control to hardware; |
284 | * fix race condition in -Z buffer management; only -Y needs to explictly | 284 | * fix race condition in -Z buffer management; only -Y needs to explicitly |
285 | * flush chars; tidy up some startup messages; | 285 | * flush chars; tidy up some startup messages; |
286 | * | 286 | * |
287 | * Revision 1.36.4.18 1996/07/25 18:57:31 bentson | 287 | * Revision 1.36.4.18 1996/07/25 18:57:31 bentson |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 475cc5e555e1..6d3449761914 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/kdev_t.h> | 16 | #include <linux/kdev_t.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/string.h> | ||
18 | 20 | ||
19 | #include "drm_core.h" | 21 | #include "drm_core.h" |
20 | #include "drmP.h" | 22 | #include "drmP.h" |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 407708a001e4..b7a0e4d6b934 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -3113,6 +3113,7 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl); | |||
3113 | int __init init_PCI (void) | 3113 | int __init init_PCI (void) |
3114 | { /* Begin init_PCI */ | 3114 | { /* Begin init_PCI */ |
3115 | memset (&epca_driver, 0, sizeof (epca_driver)); | 3115 | memset (&epca_driver, 0, sizeof (epca_driver)); |
3116 | epca_driver.owner = THIS_MODULE; | ||
3116 | epca_driver.name = "epca"; | 3117 | epca_driver.name = "epca"; |
3117 | epca_driver.id_table = epca_pci_tbl; | 3118 | epca_driver.id_table = epca_pci_tbl; |
3118 | epca_driver.probe = epca_init_one; | 3119 | epca_driver.probe = epca_init_one; |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index a54bc93353af..66e53dd450ff 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot); | |||
117 | __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); | 117 | __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); |
118 | #endif /* not MODULE */ | 118 | #endif /* not MODULE */ |
119 | 119 | ||
120 | #if defined(CONFIG_X86) || defined(CONFIG_X86_64) | 120 | #if defined(CONFIG_X86) |
121 | # define HAVE_MONOTONIC | 121 | # define HAVE_MONOTONIC |
122 | # define TIMER_FREQ 1000000000ULL | 122 | # define TIMER_FREQ 1000000000ULL |
123 | #elif defined(CONFIG_ARCH_S390) | 123 | #elif defined(CONFIG_ARCH_S390) |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index c055bb630ffc..3808d9572619 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -49,7 +49,9 @@ | |||
49 | #define HPET_USER_FREQ (64) | 49 | #define HPET_USER_FREQ (64) |
50 | #define HPET_DRIFT (500) | 50 | #define HPET_DRIFT (500) |
51 | 51 | ||
52 | static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | 52 | #define HPET_RANGE_SIZE 1024 /* from HPET spec */ |
53 | |||
54 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | ||
53 | 55 | ||
54 | /* A lock for concurrent access by app and isr hpet activity. */ | 56 | /* A lock for concurrent access by app and isr hpet activity. */ |
55 | static DEFINE_SPINLOCK(hpet_lock); | 57 | static DEFINE_SPINLOCK(hpet_lock); |
@@ -78,7 +80,7 @@ struct hpets { | |||
78 | struct hpet __iomem *hp_hpet; | 80 | struct hpet __iomem *hp_hpet; |
79 | unsigned long hp_hpet_phys; | 81 | unsigned long hp_hpet_phys; |
80 | struct time_interpolator *hp_interpolator; | 82 | struct time_interpolator *hp_interpolator; |
81 | unsigned long hp_period; | 83 | unsigned long long hp_tick_freq; |
82 | unsigned long hp_delta; | 84 | unsigned long hp_delta; |
83 | unsigned int hp_ntimer; | 85 | unsigned int hp_ntimer; |
84 | unsigned int hp_which; | 86 | unsigned int hp_which; |
@@ -90,6 +92,7 @@ static struct hpets *hpets; | |||
90 | #define HPET_OPEN 0x0001 | 92 | #define HPET_OPEN 0x0001 |
91 | #define HPET_IE 0x0002 /* interrupt enabled */ | 93 | #define HPET_IE 0x0002 /* interrupt enabled */ |
92 | #define HPET_PERIODIC 0x0004 | 94 | #define HPET_PERIODIC 0x0004 |
95 | #define HPET_SHARED_IRQ 0x0008 | ||
93 | 96 | ||
94 | #if BITS_PER_LONG == 64 | 97 | #if BITS_PER_LONG == 64 |
95 | #define write_counter(V, MC) writeq(V, MC) | 98 | #define write_counter(V, MC) writeq(V, MC) |
@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) | |||
120 | unsigned long isr; | 123 | unsigned long isr; |
121 | 124 | ||
122 | devp = data; | 125 | devp = data; |
126 | isr = 1 << (devp - devp->hd_hpets->hp_dev); | ||
127 | |||
128 | if ((devp->hd_flags & HPET_SHARED_IRQ) && | ||
129 | !(isr & readl(&devp->hd_hpet->hpet_isr))) | ||
130 | return IRQ_NONE; | ||
123 | 131 | ||
124 | spin_lock(&hpet_lock); | 132 | spin_lock(&hpet_lock); |
125 | devp->hd_irqdata++; | 133 | devp->hd_irqdata++; |
@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) | |||
137 | &devp->hd_timer->hpet_compare); | 145 | &devp->hd_timer->hpet_compare); |
138 | } | 146 | } |
139 | 147 | ||
140 | isr = (1 << (devp - devp->hd_hpets->hp_dev)); | 148 | if (devp->hd_flags & HPET_SHARED_IRQ) |
141 | writeq(isr, &devp->hd_hpet->hpet_isr); | 149 | writel(isr, &devp->hd_hpet->hpet_isr); |
142 | spin_unlock(&hpet_lock); | 150 | spin_unlock(&hpet_lock); |
143 | 151 | ||
144 | spin_lock(&hpet_task_lock); | 152 | spin_lock(&hpet_task_lock); |
@@ -276,7 +284,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
276 | 284 | ||
277 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | 285 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, |
278 | PAGE_SIZE, vma->vm_page_prot)) { | 286 | PAGE_SIZE, vma->vm_page_prot)) { |
279 | printk(KERN_ERR "remap_pfn_range failed in hpet.c\n"); | 287 | printk(KERN_ERR "%s: io_remap_pfn_range failed\n", |
288 | __FUNCTION__); | ||
280 | return -EAGAIN; | 289 | return -EAGAIN; |
281 | } | 290 | } |
282 | 291 | ||
@@ -364,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
364 | hpet = devp->hd_hpet; | 373 | hpet = devp->hd_hpet; |
365 | hpetp = devp->hd_hpets; | 374 | hpetp = devp->hd_hpets; |
366 | 375 | ||
367 | v = readq(&timer->hpet_config); | 376 | if (!devp->hd_ireqfreq) |
377 | return -EIO; | ||
378 | |||
368 | spin_lock_irq(&hpet_lock); | 379 | spin_lock_irq(&hpet_lock); |
369 | 380 | ||
370 | if (devp->hd_flags & HPET_IE) { | 381 | if (devp->hd_flags & HPET_IE) { |
@@ -373,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
373 | } | 384 | } |
374 | 385 | ||
375 | devp->hd_flags |= HPET_IE; | 386 | devp->hd_flags |= HPET_IE; |
387 | |||
388 | if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK) | ||
389 | devp->hd_flags |= HPET_SHARED_IRQ; | ||
376 | spin_unlock_irq(&hpet_lock); | 390 | spin_unlock_irq(&hpet_lock); |
377 | 391 | ||
378 | t = readq(&timer->hpet_config); | ||
379 | irq = devp->hd_hdwirq; | 392 | irq = devp->hd_hdwirq; |
380 | 393 | ||
381 | if (irq) { | 394 | if (irq) { |
382 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); | 395 | unsigned long irq_flags; |
383 | 396 | ||
384 | if (request_irq | 397 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); |
385 | (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) { | 398 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ |
399 | ? SA_SHIRQ : SA_INTERRUPT; | ||
400 | if (request_irq(irq, hpet_interrupt, irq_flags, | ||
401 | devp->hd_name, (void *)devp)) { | ||
386 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); | 402 | printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); |
387 | irq = 0; | 403 | irq = 0; |
388 | } | 404 | } |
@@ -416,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
416 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); | 432 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); |
417 | } | 433 | } |
418 | 434 | ||
419 | isr = (1 << (devp - hpets->hp_dev)); | 435 | if (devp->hd_flags & HPET_SHARED_IRQ) { |
420 | writeq(isr, &hpet->hpet_isr); | 436 | isr = 1 << (devp - devp->hd_hpets->hp_dev); |
437 | writel(isr, &hpet->hpet_isr); | ||
438 | } | ||
421 | writeq(g, &timer->hpet_config); | 439 | writeq(g, &timer->hpet_config); |
422 | local_irq_restore(flags); | 440 | local_irq_restore(flags); |
423 | 441 | ||
424 | return 0; | 442 | return 0; |
425 | } | 443 | } |
426 | 444 | ||
427 | static inline unsigned long hpet_time_div(unsigned long dis) | 445 | /* converts Hz to number of timer ticks */ |
446 | static inline unsigned long hpet_time_div(struct hpets *hpets, | ||
447 | unsigned long dis) | ||
428 | { | 448 | { |
429 | unsigned long long m = 1000000000000000ULL; | 449 | unsigned long long m; |
430 | 450 | ||
451 | m = hpets->hp_tick_freq + (dis >> 1); | ||
431 | do_div(m, dis); | 452 | do_div(m, dis); |
432 | |||
433 | return (unsigned long)m; | 453 | return (unsigned long)m; |
434 | } | 454 | } |
435 | 455 | ||
@@ -477,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
477 | { | 497 | { |
478 | struct hpet_info info; | 498 | struct hpet_info info; |
479 | 499 | ||
480 | info.hi_ireqfreq = hpet_time_div(hpetp->hp_period * | 500 | if (devp->hd_ireqfreq) |
481 | devp->hd_ireqfreq); | 501 | info.hi_ireqfreq = |
502 | hpet_time_div(hpetp, devp->hd_ireqfreq); | ||
503 | else | ||
504 | info.hi_ireqfreq = 0; | ||
482 | info.hi_flags = | 505 | info.hi_flags = |
483 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; | 506 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; |
484 | info.hi_hpet = devp->hd_hpets->hp_which; | 507 | info.hi_hpet = hpetp->hp_which; |
485 | info.hi_timer = devp - devp->hd_hpets->hp_dev; | 508 | info.hi_timer = devp - hpetp->hp_dev; |
486 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | 509 | if (kernel) |
487 | err = -EFAULT; | 510 | memcpy((void *)arg, &info, sizeof(info)); |
511 | else | ||
512 | if (copy_to_user((void __user *)arg, &info, | ||
513 | sizeof(info))) | ||
514 | err = -EFAULT; | ||
488 | break; | 515 | break; |
489 | } | 516 | } |
490 | case HPET_EPI: | 517 | case HPET_EPI: |
@@ -516,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
516 | break; | 543 | break; |
517 | } | 544 | } |
518 | 545 | ||
519 | if (arg & (arg - 1)) { | 546 | if (!arg) { |
520 | err = -EINVAL; | 547 | err = -EINVAL; |
521 | break; | 548 | break; |
522 | } | 549 | } |
523 | 550 | ||
524 | devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg); | 551 | devp->hd_ireqfreq = hpet_time_div(hpetp, arg); |
525 | } | 552 | } |
526 | 553 | ||
527 | return err; | 554 | return err; |
@@ -539,6 +566,17 @@ static struct file_operations hpet_fops = { | |||
539 | .mmap = hpet_mmap, | 566 | .mmap = hpet_mmap, |
540 | }; | 567 | }; |
541 | 568 | ||
569 | static int hpet_is_known(struct hpet_data *hdp) | ||
570 | { | ||
571 | struct hpets *hpetp; | ||
572 | |||
573 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | ||
574 | if (hpetp->hp_hpet_phys == hdp->hd_phys_address) | ||
575 | return 1; | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
542 | EXPORT_SYMBOL(hpet_alloc); | 580 | EXPORT_SYMBOL(hpet_alloc); |
543 | EXPORT_SYMBOL(hpet_register); | 581 | EXPORT_SYMBOL(hpet_register); |
544 | EXPORT_SYMBOL(hpet_unregister); | 582 | EXPORT_SYMBOL(hpet_unregister); |
@@ -563,6 +601,8 @@ int hpet_register(struct hpet_task *tp, int periodic) | |||
563 | return -EINVAL; | 601 | return -EINVAL; |
564 | } | 602 | } |
565 | 603 | ||
604 | tp->ht_opaque = NULL; | ||
605 | |||
566 | spin_lock_irq(&hpet_task_lock); | 606 | spin_lock_irq(&hpet_task_lock); |
567 | spin_lock(&hpet_lock); | 607 | spin_lock(&hpet_lock); |
568 | 608 | ||
@@ -702,15 +742,14 @@ static void hpet_register_interpolator(struct hpets *hpetp) | |||
702 | #ifdef CONFIG_TIME_INTERPOLATION | 742 | #ifdef CONFIG_TIME_INTERPOLATION |
703 | struct time_interpolator *ti; | 743 | struct time_interpolator *ti; |
704 | 744 | ||
705 | ti = kmalloc(sizeof(*ti), GFP_KERNEL); | 745 | ti = kzalloc(sizeof(*ti), GFP_KERNEL); |
706 | if (!ti) | 746 | if (!ti) |
707 | return; | 747 | return; |
708 | 748 | ||
709 | memset(ti, 0, sizeof(*ti)); | ||
710 | ti->source = TIME_SOURCE_MMIO64; | 749 | ti->source = TIME_SOURCE_MMIO64; |
711 | ti->shift = 10; | 750 | ti->shift = 10; |
712 | ti->addr = &hpetp->hp_hpet->hpet_mc; | 751 | ti->addr = &hpetp->hp_hpet->hpet_mc; |
713 | ti->frequency = hpet_time_div(hpets->hp_period); | 752 | ti->frequency = hpetp->hp_tick_freq; |
714 | ti->drift = HPET_DRIFT; | 753 | ti->drift = HPET_DRIFT; |
715 | ti->mask = -1; | 754 | ti->mask = -1; |
716 | 755 | ||
@@ -743,11 +782,11 @@ static unsigned long hpet_calibrate(struct hpets *hpetp) | |||
743 | if (!timer) | 782 | if (!timer) |
744 | return 0; | 783 | return 0; |
745 | 784 | ||
746 | hpet = hpets->hp_hpet; | 785 | hpet = hpetp->hp_hpet; |
747 | t = read_counter(&timer->hpet_compare); | 786 | t = read_counter(&timer->hpet_compare); |
748 | 787 | ||
749 | i = 0; | 788 | i = 0; |
750 | count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE); | 789 | count = hpet_time_div(hpetp, TICK_CALIBRATE); |
751 | 790 | ||
752 | local_irq_save(flags); | 791 | local_irq_save(flags); |
753 | 792 | ||
@@ -771,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp) | |||
771 | struct hpets *hpetp; | 810 | struct hpets *hpetp; |
772 | size_t siz; | 811 | size_t siz; |
773 | struct hpet __iomem *hpet; | 812 | struct hpet __iomem *hpet; |
774 | static struct hpets *last = (struct hpets *)0; | 813 | static struct hpets *last = NULL; |
775 | unsigned long ns; | 814 | unsigned long period; |
815 | unsigned long long temp; | ||
776 | 816 | ||
777 | /* | 817 | /* |
778 | * hpet_alloc can be called by platform dependent code. | 818 | * hpet_alloc can be called by platform dependent code. |
779 | * if platform dependent code has allocated the hpet | 819 | * If platform dependent code has allocated the hpet that |
780 | * ACPI also reports hpet, then we catch it here. | 820 | * ACPI has also reported, then we catch it here. |
781 | */ | 821 | */ |
782 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | 822 | if (hpet_is_known(hdp)) { |
783 | if (hpetp->hp_hpet == hdp->hd_address) | 823 | printk(KERN_DEBUG "%s: duplicate HPET ignored\n", |
784 | return 0; | 824 | __FUNCTION__); |
825 | return 0; | ||
826 | } | ||
785 | 827 | ||
786 | siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * | 828 | siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * |
787 | sizeof(struct hpet_dev)); | 829 | sizeof(struct hpet_dev)); |
788 | 830 | ||
789 | hpetp = kmalloc(siz, GFP_KERNEL); | 831 | hpetp = kzalloc(siz, GFP_KERNEL); |
790 | 832 | ||
791 | if (!hpetp) | 833 | if (!hpetp) |
792 | return -ENOMEM; | 834 | return -ENOMEM; |
793 | 835 | ||
794 | memset(hpetp, 0, siz); | ||
795 | |||
796 | hpetp->hp_which = hpet_nhpet++; | 836 | hpetp->hp_which = hpet_nhpet++; |
797 | hpetp->hp_hpet = hdp->hd_address; | 837 | hpetp->hp_hpet = hdp->hd_address; |
798 | hpetp->hp_hpet_phys = hdp->hd_phys_address; | 838 | hpetp->hp_hpet_phys = hdp->hd_phys_address; |
@@ -822,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp) | |||
822 | 862 | ||
823 | last = hpetp; | 863 | last = hpetp; |
824 | 864 | ||
825 | hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> | 865 | period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> |
826 | HPET_COUNTER_CLK_PERIOD_SHIFT; | 866 | HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */ |
867 | temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */ | ||
868 | temp += period >> 1; /* round */ | ||
869 | do_div(temp, period); | ||
870 | hpetp->hp_tick_freq = temp; /* ticks per second */ | ||
827 | 871 | ||
828 | printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s", | 872 | printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s", |
829 | hpetp->hp_which, hdp->hd_phys_address, | 873 | hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address, |
830 | hpetp->hp_ntimer > 1 ? "s" : ""); | 874 | hpetp->hp_ntimer > 1 ? "s" : ""); |
831 | for (i = 0; i < hpetp->hp_ntimer; i++) | 875 | for (i = 0; i < hpetp->hp_ntimer; i++) |
832 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); | 876 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); |
833 | printk("\n"); | 877 | printk("\n"); |
834 | 878 | ||
835 | ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ | 879 | printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", |
836 | ns /= 1000000; /* convert to nanoseconds, 10^-9 */ | 880 | hpetp->hp_which, hpetp->hp_ntimer, |
837 | printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", | 881 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq); |
838 | hpetp->hp_which, ns, hpetp->hp_ntimer, | ||
839 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); | ||
840 | 882 | ||
841 | mcfg = readq(&hpet->hpet_config); | 883 | mcfg = readq(&hpet->hpet_config); |
842 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { | 884 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { |
@@ -845,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp) | |||
845 | writeq(mcfg, &hpet->hpet_config); | 887 | writeq(mcfg, &hpet->hpet_config); |
846 | } | 888 | } |
847 | 889 | ||
848 | for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; | 890 | for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) { |
849 | i++, hpet_ntimer++, devp++) { | ||
850 | unsigned long v; | ||
851 | struct hpet_timer __iomem *timer; | 891 | struct hpet_timer __iomem *timer; |
852 | 892 | ||
853 | timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; | 893 | timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; |
854 | v = readq(&timer->hpet_config); | ||
855 | 894 | ||
856 | devp->hd_hpets = hpetp; | 895 | devp->hd_hpets = hpetp; |
857 | devp->hd_hpet = hpet; | 896 | devp->hd_hpet = hpet; |
@@ -880,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
880 | struct hpet_data *hdp; | 919 | struct hpet_data *hdp; |
881 | acpi_status status; | 920 | acpi_status status; |
882 | struct acpi_resource_address64 addr; | 921 | struct acpi_resource_address64 addr; |
883 | struct hpets *hpetp; | ||
884 | 922 | ||
885 | hdp = data; | 923 | hdp = data; |
886 | 924 | ||
@@ -893,9 +931,29 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
893 | hdp->hd_phys_address = addr.min_address_range; | 931 | hdp->hd_phys_address = addr.min_address_range; |
894 | hdp->hd_address = ioremap(addr.min_address_range, size); | 932 | hdp->hd_address = ioremap(addr.min_address_range, size); |
895 | 933 | ||
896 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | 934 | if (hpet_is_known(hdp)) { |
897 | if (hpetp->hp_hpet == hdp->hd_address) | 935 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
898 | return -EBUSY; | 936 | __FUNCTION__, hdp->hd_phys_address); |
937 | iounmap(hdp->hd_address); | ||
938 | return -EBUSY; | ||
939 | } | ||
940 | } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) { | ||
941 | struct acpi_resource_fixed_mem32 *fixmem32; | ||
942 | |||
943 | fixmem32 = &res->data.fixed_memory32; | ||
944 | if (!fixmem32) | ||
945 | return -EINVAL; | ||
946 | |||
947 | hdp->hd_phys_address = fixmem32->range_base_address; | ||
948 | hdp->hd_address = ioremap(fixmem32->range_base_address, | ||
949 | HPET_RANGE_SIZE); | ||
950 | |||
951 | if (hpet_is_known(hdp)) { | ||
952 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | ||
953 | __FUNCTION__, hdp->hd_phys_address); | ||
954 | iounmap(hdp->hd_address); | ||
955 | return -EBUSY; | ||
956 | } | ||
899 | } else if (res->id == ACPI_RSTYPE_EXT_IRQ) { | 957 | } else if (res->id == ACPI_RSTYPE_EXT_IRQ) { |
900 | struct acpi_resource_ext_irq *irqp; | 958 | struct acpi_resource_ext_irq *irqp; |
901 | int i; | 959 | int i; |
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 78d681dc35a8..f5212eb2b41d 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c | |||
@@ -95,11 +95,11 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static struct vio_driver hvc_vio_driver = { | 97 | static struct vio_driver hvc_vio_driver = { |
98 | .name = hvc_driver_name, | ||
99 | .id_table = hvc_driver_table, | 98 | .id_table = hvc_driver_table, |
100 | .probe = hvc_vio_probe, | 99 | .probe = hvc_vio_probe, |
101 | .remove = hvc_vio_remove, | 100 | .remove = hvc_vio_remove, |
102 | .driver = { | 101 | .driver = { |
102 | .name = hvc_driver_name, | ||
103 | .owner = THIS_MODULE, | 103 | .owner = THIS_MODULE, |
104 | } | 104 | } |
105 | }; | 105 | }; |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index f47f009f9259..53dc77c760fc 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -720,10 +720,13 @@ static int __devexit hvcs_remove(struct vio_dev *dev) | |||
720 | }; | 720 | }; |
721 | 721 | ||
722 | static struct vio_driver hvcs_vio_driver = { | 722 | static struct vio_driver hvcs_vio_driver = { |
723 | .name = hvcs_driver_name, | ||
724 | .id_table = hvcs_driver_table, | 723 | .id_table = hvcs_driver_table, |
725 | .probe = hvcs_probe, | 724 | .probe = hvcs_probe, |
726 | .remove = hvcs_remove, | 725 | .remove = hvcs_remove, |
726 | .driver = { | ||
727 | .name = hvcs_driver_name, | ||
728 | .owner = THIS_MODULE, | ||
729 | } | ||
727 | }; | 730 | }; |
728 | 731 | ||
729 | /* Only called from hvcs_get_pi please */ | 732 | /* Only called from hvcs_get_pi please */ |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 38be4b0dbd1c..91dd669273e0 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -231,9 +231,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
231 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) | 231 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) |
232 | { | 232 | { |
233 | #if defined(__HAVE_PHYS_MEM_ACCESS_PROT) | 233 | #if defined(__HAVE_PHYS_MEM_ACCESS_PROT) |
234 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | 234 | vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, |
235 | |||
236 | vma->vm_page_prot = phys_mem_access_prot(file, offset, | ||
237 | vma->vm_end - vma->vm_start, | 235 | vma->vm_end - vma->vm_start, |
238 | vma->vm_page_prot); | 236 | vma->vm_page_prot); |
239 | #elif defined(pgprot_noncached) | 237 | #elif defined(pgprot_noncached) |
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c index 613aed9e1840..d1fe05e83882 100644 --- a/drivers/char/mwave/3780i.c +++ b/drivers/char/mwave/3780i.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <linux/ioport.h> | 53 | #include <linux/ioport.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/bitops.h> | 55 | #include <linux/bitops.h> |
56 | #include <linux/sched.h> /* cond_resched() */ | ||
57 | |||
56 | #include <asm/io.h> | 58 | #include <asm/io.h> |
57 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
58 | #include <asm/system.h> | 60 | #include <asm/system.h> |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 5b1d3680c8ab..928b850cc679 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -256,7 +256,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | |||
256 | static int sReadAiopID(ByteIO_t io); | 256 | static int sReadAiopID(ByteIO_t io); |
257 | static int sReadAiopNumChan(WordIO_t io); | 257 | static int sReadAiopNumChan(WordIO_t io); |
258 | 258 | ||
259 | #ifdef MODULE | ||
260 | MODULE_AUTHOR("Theodore Ts'o"); | 259 | MODULE_AUTHOR("Theodore Ts'o"); |
261 | MODULE_DESCRIPTION("Comtrol RocketPort driver"); | 260 | MODULE_DESCRIPTION("Comtrol RocketPort driver"); |
262 | module_param(board1, ulong, 0); | 261 | module_param(board1, ulong, 0); |
@@ -288,17 +287,14 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1 | |||
288 | module_param_array(pc104_4, ulong, NULL, 0); | 287 | module_param_array(pc104_4, ulong, NULL, 0); |
289 | MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,..."); | 288 | MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,..."); |
290 | 289 | ||
291 | int rp_init(void); | 290 | static int rp_init(void); |
292 | static void rp_cleanup_module(void); | 291 | static void rp_cleanup_module(void); |
293 | 292 | ||
294 | module_init(rp_init); | 293 | module_init(rp_init); |
295 | module_exit(rp_cleanup_module); | 294 | module_exit(rp_cleanup_module); |
296 | 295 | ||
297 | #endif | ||
298 | 296 | ||
299 | #ifdef MODULE_LICENSE | ||
300 | MODULE_LICENSE("Dual BSD/GPL"); | 297 | MODULE_LICENSE("Dual BSD/GPL"); |
301 | #endif | ||
302 | 298 | ||
303 | /*************************************************************************/ | 299 | /*************************************************************************/ |
304 | /* Module code starts here */ | 300 | /* Module code starts here */ |
@@ -2378,7 +2374,7 @@ static struct tty_operations rocket_ops = { | |||
2378 | /* | 2374 | /* |
2379 | * The module "startup" routine; it's run when the module is loaded. | 2375 | * The module "startup" routine; it's run when the module is loaded. |
2380 | */ | 2376 | */ |
2381 | int __init rp_init(void) | 2377 | static int __init rp_init(void) |
2382 | { | 2378 | { |
2383 | int retval, pci_boards_found, isa_boards_found, i; | 2379 | int retval, pci_boards_found, isa_boards_found, i; |
2384 | 2380 | ||
@@ -2502,7 +2498,6 @@ int __init rp_init(void) | |||
2502 | return 0; | 2498 | return 0; |
2503 | } | 2499 | } |
2504 | 2500 | ||
2505 | #ifdef MODULE | ||
2506 | 2501 | ||
2507 | static void rp_cleanup_module(void) | 2502 | static void rp_cleanup_module(void) |
2508 | { | 2503 | { |
@@ -2530,7 +2525,6 @@ static void rp_cleanup_module(void) | |||
2530 | if (controller) | 2525 | if (controller) |
2531 | release_region(controller, 4); | 2526 | release_region(controller, 4); |
2532 | } | 2527 | } |
2533 | #endif | ||
2534 | 2528 | ||
2535 | /*************************************************************************** | 2529 | /*************************************************************************** |
2536 | Function: sInitController | 2530 | Function: sInitController |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 6b4e9d155f50..dda30e42ec79 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -790,7 +790,7 @@ static int __init a2232board_init(void) | |||
790 | 790 | ||
791 | } | 791 | } |
792 | 792 | ||
793 | printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */ | 793 | printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */ |
794 | 794 | ||
795 | a2232_init_portstructs(); | 795 | a2232_init_portstructs(); |
796 | 796 | ||
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 50e0b612a8a2..352547eabf7b 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -38,19 +38,19 @@ | |||
38 | * | 38 | * |
39 | * Revision 1.0: April 1st 1997. | 39 | * Revision 1.0: April 1st 1997. |
40 | * Initial release for alpha testing. | 40 | * Initial release for alpha testing. |
41 | * Revision 1.1: April 14th 1997. | 41 | * Revision 1.1: April 14th 1997. |
42 | * Incorporated Richard Hudsons suggestions, | 42 | * Incorporated Richard Hudsons suggestions, |
43 | * removed some debugging printk's. | 43 | * removed some debugging printk's. |
44 | * Revision 1.2: April 15th 1997. | 44 | * Revision 1.2: April 15th 1997. |
45 | * Ported to 2.1.x kernels. | 45 | * Ported to 2.1.x kernels. |
46 | * Revision 1.3: April 17th 1997 | 46 | * Revision 1.3: April 17th 1997 |
47 | * Backported to 2.0. (Compatibility macros). | 47 | * Backported to 2.0. (Compatibility macros). |
48 | * Revision 1.4: April 18th 1997 | 48 | * Revision 1.4: April 18th 1997 |
49 | * Fixed DTR/RTS bug that caused the card to indicate | 49 | * Fixed DTR/RTS bug that caused the card to indicate |
50 | * "don't send data" to a modem after the password prompt. | 50 | * "don't send data" to a modem after the password prompt. |
51 | * Fixed bug for premature (fake) interrupts. | 51 | * Fixed bug for premature (fake) interrupts. |
52 | * Revision 1.5: April 19th 1997 | 52 | * Revision 1.5: April 19th 1997 |
53 | * fixed a minor typo in the header file, cleanup a little. | 53 | * fixed a minor typo in the header file, cleanup a little. |
54 | * performance warnings are now MAXed at once per minute. | 54 | * performance warnings are now MAXed at once per minute. |
55 | * Revision 1.6: May 23 1997 | 55 | * Revision 1.6: May 23 1997 |
56 | * Changed the specialix=... format to include interrupt. | 56 | * Changed the specialix=... format to include interrupt. |
@@ -60,10 +60,10 @@ | |||
60 | * port to linux-2.1.43 kernel. | 60 | * port to linux-2.1.43 kernel. |
61 | * Revision 1.9: Oct 9 1998 | 61 | * Revision 1.9: Oct 9 1998 |
62 | * Added stuff for the IO8+/PCI version. | 62 | * Added stuff for the IO8+/PCI version. |
63 | * Revision 1.10: Oct 22 1999 / Jan 21 2000. | 63 | * Revision 1.10: Oct 22 1999 / Jan 21 2000. |
64 | * Added stuff for setserial. | 64 | * Added stuff for setserial. |
65 | * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) | 65 | * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) |
66 | * | 66 | * |
67 | */ | 67 | */ |
68 | 68 | ||
69 | #define VERSION "1.11" | 69 | #define VERSION "1.11" |
@@ -154,7 +154,7 @@ static int sx_poll = HZ; | |||
154 | 154 | ||
155 | 155 | ||
156 | 156 | ||
157 | /* | 157 | /* |
158 | * The following defines are mostly for testing purposes. But if you need | 158 | * The following defines are mostly for testing purposes. But if you need |
159 | * some nice reporting in your syslog, you can define them also. | 159 | * some nice reporting in your syslog, you can define them also. |
160 | */ | 160 | */ |
@@ -188,7 +188,7 @@ static DECLARE_MUTEX(tmp_buf_sem); | |||
188 | 188 | ||
189 | static unsigned long baud_table[] = { | 189 | static unsigned long baud_table[] = { |
190 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 190 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
191 | 9600, 19200, 38400, 57600, 115200, 0, | 191 | 9600, 19200, 38400, 57600, 115200, 0, |
192 | }; | 192 | }; |
193 | 193 | ||
194 | static struct specialix_board sx_board[SX_NBOARD] = { | 194 | static struct specialix_board sx_board[SX_NBOARD] = { |
@@ -216,7 +216,7 @@ static inline int sx_paranoia_check(struct specialix_port const * port, | |||
216 | KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n"; | 216 | KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n"; |
217 | static const char *badinfo = | 217 | static const char *badinfo = |
218 | KERN_ERR "sx: Warning: null specialix port for device %s in %s\n"; | 218 | KERN_ERR "sx: Warning: null specialix port for device %s in %s\n"; |
219 | 219 | ||
220 | if (!port) { | 220 | if (!port) { |
221 | printk(badinfo, name, routine); | 221 | printk(badinfo, name, routine); |
222 | return 1; | 222 | return 1; |
@@ -231,9 +231,9 @@ static inline int sx_paranoia_check(struct specialix_port const * port, | |||
231 | 231 | ||
232 | 232 | ||
233 | /* | 233 | /* |
234 | * | 234 | * |
235 | * Service functions for specialix IO8+ driver. | 235 | * Service functions for specialix IO8+ driver. |
236 | * | 236 | * |
237 | */ | 237 | */ |
238 | 238 | ||
239 | /* Get board number from pointer */ | 239 | /* Get board number from pointer */ |
@@ -246,7 +246,7 @@ static inline int board_No (struct specialix_board * bp) | |||
246 | /* Get port number from pointer */ | 246 | /* Get port number from pointer */ |
247 | static inline int port_No (struct specialix_port const * port) | 247 | static inline int port_No (struct specialix_port const * port) |
248 | { | 248 | { |
249 | return SX_PORT(port - sx_port); | 249 | return SX_PORT(port - sx_port); |
250 | } | 250 | } |
251 | 251 | ||
252 | 252 | ||
@@ -309,7 +309,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp) | |||
309 | return; | 309 | return; |
310 | udelay (1); | 310 | udelay (1); |
311 | } | 311 | } |
312 | 312 | ||
313 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); | 313 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); |
314 | } | 314 | } |
315 | 315 | ||
@@ -329,7 +329,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp) | |||
329 | return; | 329 | return; |
330 | udelay (1); | 330 | udelay (1); |
331 | } | 331 | } |
332 | 332 | ||
333 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); | 333 | printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); |
334 | } | 334 | } |
335 | 335 | ||
@@ -338,34 +338,28 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp) | |||
338 | * specialix IO8+ IO range functions. | 338 | * specialix IO8+ IO range functions. |
339 | */ | 339 | */ |
340 | 340 | ||
341 | static inline int sx_check_io_range(struct specialix_board * bp) | 341 | static inline int sx_request_io_range(struct specialix_board * bp) |
342 | { | 342 | { |
343 | return check_region (bp->base, SX_IO_SPACE); | 343 | return request_region(bp->base, |
344 | } | 344 | bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, |
345 | 345 | "specialix IO8+") == NULL; | |
346 | |||
347 | static inline void sx_request_io_range(struct specialix_board * bp) | ||
348 | { | ||
349 | request_region(bp->base, | ||
350 | bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE, | ||
351 | "specialix IO8+" ); | ||
352 | } | 346 | } |
353 | 347 | ||
354 | 348 | ||
355 | static inline void sx_release_io_range(struct specialix_board * bp) | 349 | static inline void sx_release_io_range(struct specialix_board * bp) |
356 | { | 350 | { |
357 | release_region(bp->base, | 351 | release_region(bp->base, |
358 | bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE); | 352 | bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE); |
359 | } | 353 | } |
360 | 354 | ||
361 | 355 | ||
362 | /* Must be called with enabled interrupts */ | 356 | /* Must be called with enabled interrupts */ |
363 | /* Ugly. Very ugly. Don't use this for anything else than initialization | 357 | /* Ugly. Very ugly. Don't use this for anything else than initialization |
364 | code */ | 358 | code */ |
365 | static inline void sx_long_delay(unsigned long delay) | 359 | static inline void sx_long_delay(unsigned long delay) |
366 | { | 360 | { |
367 | unsigned long i; | 361 | unsigned long i; |
368 | 362 | ||
369 | for (i = jiffies + delay; time_after(i, jiffies); ) ; | 363 | for (i = jiffies + delay; time_after(i, jiffies); ) ; |
370 | } | 364 | } |
371 | 365 | ||
@@ -378,7 +372,7 @@ static int sx_set_irq ( struct specialix_board *bp) | |||
378 | int i; | 372 | int i; |
379 | unsigned long flags; | 373 | unsigned long flags; |
380 | 374 | ||
381 | if (bp->flags & SX_BOARD_IS_PCI) | 375 | if (bp->flags & SX_BOARD_IS_PCI) |
382 | return 1; | 376 | return 1; |
383 | switch (bp->irq) { | 377 | switch (bp->irq) { |
384 | /* In the same order as in the docs... */ | 378 | /* In the same order as in the docs... */ |
@@ -420,7 +414,7 @@ static int sx_init_CD186x(struct specialix_board * bp) | |||
420 | sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ | 414 | sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ |
421 | /* Set RegAckEn */ | 415 | /* Set RegAckEn */ |
422 | sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN); | 416 | sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN); |
423 | 417 | ||
424 | /* Setting up prescaler. We need 4 ticks per 1 ms */ | 418 | /* Setting up prescaler. We need 4 ticks per 1 ms */ |
425 | scaler = SX_OSCFREQ/SPECIALIX_TPS; | 419 | scaler = SX_OSCFREQ/SPECIALIX_TPS; |
426 | 420 | ||
@@ -448,7 +442,7 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit) | |||
448 | spin_lock_irqsave(&bp->lock, flags); | 442 | spin_lock_irqsave(&bp->lock, flags); |
449 | for (i=0, t=0;i<8;i++) { | 443 | for (i=0, t=0;i<8;i++) { |
450 | sx_out_off (bp, CD186x_CAR, i); | 444 | sx_out_off (bp, CD186x_CAR, i); |
451 | if (sx_in_off (bp, reg) & bit) | 445 | if (sx_in_off (bp, reg) & bit) |
452 | t |= 1 << i; | 446 | t |= 1 << i; |
453 | } | 447 | } |
454 | spin_unlock_irqrestore(&bp->lock, flags); | 448 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -472,7 +466,7 @@ void missed_irq (unsigned long data) | |||
472 | spin_unlock_irqrestore(&bp->lock, flags); | 466 | spin_unlock_irqrestore(&bp->lock, flags); |
473 | if (irq) { | 467 | if (irq) { |
474 | printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); | 468 | printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); |
475 | sx_interrupt (((struct specialix_board *)data)->irq, | 469 | sx_interrupt (((struct specialix_board *)data)->irq, |
476 | (void*)data, NULL); | 470 | (void*)data, NULL); |
477 | } | 471 | } |
478 | missed_irq_timer.expires = jiffies + sx_poll; | 472 | missed_irq_timer.expires = jiffies + sx_poll; |
@@ -495,7 +489,7 @@ static int sx_probe(struct specialix_board *bp) | |||
495 | 489 | ||
496 | func_enter(); | 490 | func_enter(); |
497 | 491 | ||
498 | if (sx_check_io_range(bp)) { | 492 | if (sx_request_io_range(bp)) { |
499 | func_exit(); | 493 | func_exit(); |
500 | return 1; | 494 | return 1; |
501 | } | 495 | } |
@@ -509,15 +503,16 @@ static int sx_probe(struct specialix_board *bp) | |||
509 | short_pause (); | 503 | short_pause (); |
510 | val2 = sx_in_off(bp, CD186x_PPRL); | 504 | val2 = sx_in_off(bp, CD186x_PPRL); |
511 | 505 | ||
512 | 506 | ||
513 | if ((val1 != 0x5a) || (val2 != 0xa5)) { | 507 | if ((val1 != 0x5a) || (val2 != 0xa5)) { |
514 | printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n", | 508 | printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n", |
515 | board_No(bp), bp->base); | 509 | board_No(bp), bp->base); |
510 | sx_release_io_range(bp); | ||
516 | func_exit(); | 511 | func_exit(); |
517 | return 1; | 512 | return 1; |
518 | } | 513 | } |
519 | 514 | ||
520 | /* Check the DSR lines that Specialix uses as board | 515 | /* Check the DSR lines that Specialix uses as board |
521 | identification */ | 516 | identification */ |
522 | val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR); | 517 | val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR); |
523 | val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS); | 518 | val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS); |
@@ -532,6 +527,7 @@ static int sx_probe(struct specialix_board *bp) | |||
532 | if (val1 != val2) { | 527 | if (val1 != val2) { |
533 | printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", | 528 | printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", |
534 | board_No(bp), val2, bp->base, val1); | 529 | board_No(bp), val2, bp->base, val1); |
530 | sx_release_io_range(bp); | ||
535 | func_exit(); | 531 | func_exit(); |
536 | return 1; | 532 | return 1; |
537 | } | 533 | } |
@@ -546,7 +542,7 @@ static int sx_probe(struct specialix_board *bp) | |||
546 | sx_wait_CCR(bp); | 542 | sx_wait_CCR(bp); |
547 | sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ | 543 | sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ |
548 | sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ | 544 | sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ |
549 | sx_long_delay(HZ/20); | 545 | sx_long_delay(HZ/20); |
550 | irqs = probe_irq_off(irqs); | 546 | irqs = probe_irq_off(irqs); |
551 | 547 | ||
552 | dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); | 548 | dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); |
@@ -561,14 +557,15 @@ static int sx_probe(struct specialix_board *bp) | |||
561 | } | 557 | } |
562 | 558 | ||
563 | dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n", | 559 | dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n", |
564 | val1, val2, val3); | 560 | val1, val2, val3); |
565 | 561 | ||
566 | } | 562 | } |
567 | 563 | ||
568 | #if 0 | 564 | #if 0 |
569 | if (irqs <= 0) { | 565 | if (irqs <= 0) { |
570 | printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", | 566 | printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", |
571 | board_No(bp), bp->base); | 567 | board_No(bp), bp->base); |
568 | sx_release_io_range(bp); | ||
572 | func_exit(); | 569 | func_exit(); |
573 | return 1; | 570 | return 1; |
574 | } | 571 | } |
@@ -579,19 +576,20 @@ static int sx_probe(struct specialix_board *bp) | |||
579 | #endif | 576 | #endif |
580 | /* Reset CD186x again */ | 577 | /* Reset CD186x again */ |
581 | if (!sx_init_CD186x(bp)) { | 578 | if (!sx_init_CD186x(bp)) { |
579 | sx_release_io_range(bp); | ||
582 | func_exit(); | 580 | func_exit(); |
583 | return -EIO; | 581 | return 1; |
584 | } | 582 | } |
585 | 583 | ||
586 | sx_request_io_range(bp); | 584 | sx_request_io_range(bp); |
587 | bp->flags |= SX_BOARD_PRESENT; | 585 | bp->flags |= SX_BOARD_PRESENT; |
588 | 586 | ||
589 | /* Chip revcode pkgtype | 587 | /* Chip revcode pkgtype |
590 | GFRCR SRCR bit 7 | 588 | GFRCR SRCR bit 7 |
591 | CD180 rev B 0x81 0 | 589 | CD180 rev B 0x81 0 |
592 | CD180 rev C 0x82 0 | 590 | CD180 rev C 0x82 0 |
593 | CD1864 rev A 0x82 1 | 591 | CD1864 rev A 0x82 1 |
594 | CD1865 rev A 0x83 1 -- Do not use!!! Does not work. | 592 | CD1865 rev A 0x83 1 -- Do not use!!! Does not work. |
595 | CD1865 rev B 0x84 1 | 593 | CD1865 rev B 0x84 1 |
596 | -- Thanks to Gwen Wang, Cirrus Logic. | 594 | -- Thanks to Gwen Wang, Cirrus Logic. |
597 | */ | 595 | */ |
@@ -623,8 +621,8 @@ static int sx_probe(struct specialix_board *bp) | |||
623 | return 0; | 621 | return 0; |
624 | } | 622 | } |
625 | 623 | ||
626 | /* | 624 | /* |
627 | * | 625 | * |
628 | * Interrupt processing routines. | 626 | * Interrupt processing routines. |
629 | * */ | 627 | * */ |
630 | 628 | ||
@@ -657,7 +655,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp, | |||
657 | return port; | 655 | return port; |
658 | } | 656 | } |
659 | } | 657 | } |
660 | printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", | 658 | printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", |
661 | board_No(bp), what, channel); | 659 | board_No(bp), what, channel); |
662 | return NULL; | 660 | return NULL; |
663 | } | 661 | } |
@@ -681,7 +679,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
681 | tty = port->tty; | 679 | tty = port->tty; |
682 | dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n", | 680 | dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n", |
683 | port, tty->flip.count, TTY_FLIPBUF_SIZE); | 681 | port, tty->flip.count, TTY_FLIPBUF_SIZE); |
684 | 682 | ||
685 | status = sx_in(bp, CD186x_RCSR); | 683 | status = sx_in(bp, CD186x_RCSR); |
686 | 684 | ||
687 | dprintk (SX_DEBUG_RX, "status: 0x%x\n", status); | 685 | dprintk (SX_DEBUG_RX, "status: 0x%x\n", status); |
@@ -707,30 +705,30 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
707 | return; | 705 | return; |
708 | } | 706 | } |
709 | if (status & RCSR_TOUT) { | 707 | if (status & RCSR_TOUT) { |
710 | printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", | 708 | printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", |
711 | board_No(bp), port_No(port)); | 709 | board_No(bp), port_No(port)); |
712 | func_exit(); | 710 | func_exit(); |
713 | return; | 711 | return; |
714 | 712 | ||
715 | } else if (status & RCSR_BREAK) { | 713 | } else if (status & RCSR_BREAK) { |
716 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", | 714 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", |
717 | board_No(bp), port_No(port)); | 715 | board_No(bp), port_No(port)); |
718 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 716 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; |
719 | if (port->flags & ASYNC_SAK) | 717 | if (port->flags & ASYNC_SAK) |
720 | do_SAK(tty); | 718 | do_SAK(tty); |
721 | 719 | ||
722 | } else if (status & RCSR_PE) | 720 | } else if (status & RCSR_PE) |
723 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 721 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; |
724 | 722 | ||
725 | else if (status & RCSR_FE) | 723 | else if (status & RCSR_FE) |
726 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 724 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; |
727 | 725 | ||
728 | else if (status & RCSR_OE) | 726 | else if (status & RCSR_OE) |
729 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 727 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; |
730 | 728 | ||
731 | else | 729 | else |
732 | *tty->flip.flag_buf_ptr++ = 0; | 730 | *tty->flip.flag_buf_ptr++ = 0; |
733 | 731 | ||
734 | *tty->flip.char_buf_ptr++ = ch; | 732 | *tty->flip.char_buf_ptr++ = ch; |
735 | tty->flip.count++; | 733 | tty->flip.count++; |
736 | schedule_delayed_work(&tty->flip.work, 1); | 734 | schedule_delayed_work(&tty->flip.work, 1); |
@@ -746,18 +744,18 @@ static inline void sx_receive(struct specialix_board * bp) | |||
746 | unsigned char count; | 744 | unsigned char count; |
747 | 745 | ||
748 | func_enter(); | 746 | func_enter(); |
749 | 747 | ||
750 | if (!(port = sx_get_port(bp, "Receive"))) { | 748 | if (!(port = sx_get_port(bp, "Receive"))) { |
751 | dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); | 749 | dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n"); |
752 | func_exit(); | 750 | func_exit(); |
753 | return; | 751 | return; |
754 | } | 752 | } |
755 | tty = port->tty; | 753 | tty = port->tty; |
756 | 754 | ||
757 | count = sx_in(bp, CD186x_RDCR); | 755 | count = sx_in(bp, CD186x_RDCR); |
758 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); | 756 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); |
759 | port->hits[count > 8 ? 9 : count]++; | 757 | port->hits[count > 8 ? 9 : count]++; |
760 | 758 | ||
761 | while (count--) { | 759 | while (count--) { |
762 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 760 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { |
763 | printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", | 761 | printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", |
@@ -787,7 +785,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
787 | } | 785 | } |
788 | dprintk (SX_DEBUG_TX, "port: %p\n", port); | 786 | dprintk (SX_DEBUG_TX, "port: %p\n", port); |
789 | tty = port->tty; | 787 | tty = port->tty; |
790 | 788 | ||
791 | if (port->IER & IER_TXEMPTY) { | 789 | if (port->IER & IER_TXEMPTY) { |
792 | /* FIFO drained */ | 790 | /* FIFO drained */ |
793 | sx_out(bp, CD186x_CAR, port_No(port)); | 791 | sx_out(bp, CD186x_CAR, port_No(port)); |
@@ -796,7 +794,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
796 | func_exit(); | 794 | func_exit(); |
797 | return; | 795 | return; |
798 | } | 796 | } |
799 | 797 | ||
800 | if ((port->xmit_cnt <= 0 && !port->break_length) | 798 | if ((port->xmit_cnt <= 0 && !port->break_length) |
801 | || tty->stopped || tty->hw_stopped) { | 799 | || tty->stopped || tty->hw_stopped) { |
802 | sx_out(bp, CD186x_CAR, port_No(port)); | 800 | sx_out(bp, CD186x_CAR, port_No(port)); |
@@ -805,7 +803,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
805 | func_exit(); | 803 | func_exit(); |
806 | return; | 804 | return; |
807 | } | 805 | } |
808 | 806 | ||
809 | if (port->break_length) { | 807 | if (port->break_length) { |
810 | if (port->break_length > 0) { | 808 | if (port->break_length > 0) { |
811 | if (port->COR2 & COR2_ETC) { | 809 | if (port->COR2 & COR2_ETC) { |
@@ -831,7 +829,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
831 | func_exit(); | 829 | func_exit(); |
832 | return; | 830 | return; |
833 | } | 831 | } |
834 | 832 | ||
835 | count = CD186x_NFIFO; | 833 | count = CD186x_NFIFO; |
836 | do { | 834 | do { |
837 | sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); | 835 | sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); |
@@ -839,7 +837,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
839 | if (--port->xmit_cnt <= 0) | 837 | if (--port->xmit_cnt <= 0) |
840 | break; | 838 | break; |
841 | } while (--count > 0); | 839 | } while (--count > 0); |
842 | 840 | ||
843 | if (port->xmit_cnt <= 0) { | 841 | if (port->xmit_cnt <= 0) { |
844 | sx_out(bp, CD186x_CAR, port_No(port)); | 842 | sx_out(bp, CD186x_CAR, port_No(port)); |
845 | port->IER &= ~IER_TXRDY; | 843 | port->IER &= ~IER_TXRDY; |
@@ -862,9 +860,9 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
862 | dprintk (SX_DEBUG_SIGNALS, "Modem intr. "); | 860 | dprintk (SX_DEBUG_SIGNALS, "Modem intr. "); |
863 | if (!(port = sx_get_port(bp, "Modem"))) | 861 | if (!(port = sx_get_port(bp, "Modem"))) |
864 | return; | 862 | return; |
865 | 863 | ||
866 | tty = port->tty; | 864 | tty = port->tty; |
867 | 865 | ||
868 | mcr = sx_in(bp, CD186x_MCR); | 866 | mcr = sx_in(bp, CD186x_MCR); |
869 | printk ("mcr = %02x.\n", mcr); | 867 | printk ("mcr = %02x.\n", mcr); |
870 | 868 | ||
@@ -879,7 +877,7 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
879 | schedule_work(&port->tqueue_hangup); | 877 | schedule_work(&port->tqueue_hangup); |
880 | } | 878 | } |
881 | } | 879 | } |
882 | 880 | ||
883 | #ifdef SPECIALIX_BRAIN_DAMAGED_CTS | 881 | #ifdef SPECIALIX_BRAIN_DAMAGED_CTS |
884 | if (mcr & MCR_CTSCHG) { | 882 | if (mcr & MCR_CTSCHG) { |
885 | if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) { | 883 | if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) { |
@@ -906,7 +904,7 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
906 | sx_out(bp, CD186x_IER, port->IER); | 904 | sx_out(bp, CD186x_IER, port->IER); |
907 | } | 905 | } |
908 | #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */ | 906 | #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */ |
909 | 907 | ||
910 | /* Clear change bits */ | 908 | /* Clear change bits */ |
911 | sx_out(bp, CD186x_MCR, 0); | 909 | sx_out(bp, CD186x_MCR, 0); |
912 | } | 910 | } |
@@ -940,7 +938,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
940 | while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) & | 938 | while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) & |
941 | (SRSR_RREQint | | 939 | (SRSR_RREQint | |
942 | SRSR_TREQint | | 940 | SRSR_TREQint | |
943 | SRSR_MREQint)))) { | 941 | SRSR_MREQint)))) { |
944 | if (status & SRSR_RREQint) { | 942 | if (status & SRSR_RREQint) { |
945 | ack = sx_in(bp, CD186x_RRAR); | 943 | ack = sx_in(bp, CD186x_RRAR); |
946 | 944 | ||
@@ -951,7 +949,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
951 | else | 949 | else |
952 | printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", | 950 | printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", |
953 | board_No(bp), status, ack); | 951 | board_No(bp), status, ack); |
954 | 952 | ||
955 | } else if (status & SRSR_TREQint) { | 953 | } else if (status & SRSR_TREQint) { |
956 | ack = sx_in(bp, CD186x_TRAR); | 954 | ack = sx_in(bp, CD186x_TRAR); |
957 | 955 | ||
@@ -963,13 +961,13 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
963 | } else if (status & SRSR_MREQint) { | 961 | } else if (status & SRSR_MREQint) { |
964 | ack = sx_in(bp, CD186x_MRAR); | 962 | ack = sx_in(bp, CD186x_MRAR); |
965 | 963 | ||
966 | if (ack == (SX_ID | GIVR_IT_MODEM)) | 964 | if (ack == (SX_ID | GIVR_IT_MODEM)) |
967 | sx_check_modem(bp); | 965 | sx_check_modem(bp); |
968 | else | 966 | else |
969 | printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", | 967 | printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", |
970 | board_No(bp), status, ack); | 968 | board_No(bp), status, ack); |
971 | 969 | ||
972 | } | 970 | } |
973 | 971 | ||
974 | sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ | 972 | sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ |
975 | } | 973 | } |
@@ -1026,7 +1024,7 @@ static inline int sx_setup_board(struct specialix_board * bp) | |||
1026 | { | 1024 | { |
1027 | int error; | 1025 | int error; |
1028 | 1026 | ||
1029 | if (bp->flags & SX_BOARD_ACTIVE) | 1027 | if (bp->flags & SX_BOARD_ACTIVE) |
1030 | return 0; | 1028 | return 0; |
1031 | 1029 | ||
1032 | if (bp->flags & SX_BOARD_IS_PCI) | 1030 | if (bp->flags & SX_BOARD_IS_PCI) |
@@ -1034,7 +1032,7 @@ static inline int sx_setup_board(struct specialix_board * bp) | |||
1034 | else | 1032 | else |
1035 | error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp); | 1033 | error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp); |
1036 | 1034 | ||
1037 | if (error) | 1035 | if (error) |
1038 | return error; | 1036 | return error; |
1039 | 1037 | ||
1040 | turn_ints_on (bp); | 1038 | turn_ints_on (bp); |
@@ -1055,7 +1053,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp) | |||
1055 | } | 1053 | } |
1056 | 1054 | ||
1057 | bp->flags &= ~SX_BOARD_ACTIVE; | 1055 | bp->flags &= ~SX_BOARD_ACTIVE; |
1058 | 1056 | ||
1059 | dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", | 1057 | dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", |
1060 | bp->irq, board_No (bp)); | 1058 | bp->irq, board_No (bp)); |
1061 | free_irq(bp->irq, bp); | 1059 | free_irq(bp->irq, bp); |
@@ -1068,7 +1066,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp) | |||
1068 | 1066 | ||
1069 | 1067 | ||
1070 | /* | 1068 | /* |
1071 | * Setting up port characteristics. | 1069 | * Setting up port characteristics. |
1072 | * Must be called with disabled interrupts | 1070 | * Must be called with disabled interrupts |
1073 | */ | 1071 | */ |
1074 | static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port) | 1072 | static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port) |
@@ -1103,10 +1101,10 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1103 | spin_unlock_irqrestore(&bp->lock, flags); | 1101 | spin_unlock_irqrestore(&bp->lock, flags); |
1104 | dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); | 1102 | dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); |
1105 | baud = C_BAUD(tty); | 1103 | baud = C_BAUD(tty); |
1106 | 1104 | ||
1107 | if (baud & CBAUDEX) { | 1105 | if (baud & CBAUDEX) { |
1108 | baud &= ~CBAUDEX; | 1106 | baud &= ~CBAUDEX; |
1109 | if (baud < 1 || baud > 2) | 1107 | if (baud < 1 || baud > 2) |
1110 | port->tty->termios->c_cflag &= ~CBAUDEX; | 1108 | port->tty->termios->c_cflag &= ~CBAUDEX; |
1111 | else | 1109 | else |
1112 | baud += 15; | 1110 | baud += 15; |
@@ -1117,8 +1115,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1117 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 1115 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
1118 | baud += 2; | 1116 | baud += 2; |
1119 | } | 1117 | } |
1120 | 1118 | ||
1121 | 1119 | ||
1122 | if (!baud_table[baud]) { | 1120 | if (!baud_table[baud]) { |
1123 | /* Drop DTR & exit */ | 1121 | /* Drop DTR & exit */ |
1124 | dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); | 1122 | dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); |
@@ -1127,7 +1125,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1127 | spin_lock_irqsave(&bp->lock, flags); | 1125 | spin_lock_irqsave(&bp->lock, flags); |
1128 | sx_out(bp, CD186x_MSVR, port->MSVR ); | 1126 | sx_out(bp, CD186x_MSVR, port->MSVR ); |
1129 | spin_unlock_irqrestore(&bp->lock, flags); | 1127 | spin_unlock_irqrestore(&bp->lock, flags); |
1130 | } | 1128 | } |
1131 | else | 1129 | else |
1132 | dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); | 1130 | dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); |
1133 | return; | 1131 | return; |
@@ -1137,9 +1135,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1137 | port ->MSVR |= MSVR_DTR; | 1135 | port ->MSVR |= MSVR_DTR; |
1138 | } | 1136 | } |
1139 | } | 1137 | } |
1140 | 1138 | ||
1141 | /* | 1139 | /* |
1142 | * Now we must calculate some speed depended things | 1140 | * Now we must calculate some speed depended things |
1143 | */ | 1141 | */ |
1144 | 1142 | ||
1145 | /* Set baud rate for port */ | 1143 | /* Set baud rate for port */ |
@@ -1152,7 +1150,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1152 | tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + | 1150 | tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + |
1153 | CD186x_TPC/2) / CD186x_TPC); | 1151 | CD186x_TPC/2) / CD186x_TPC); |
1154 | 1152 | ||
1155 | if ((tmp < 0x10) && time_before(again, jiffies)) { | 1153 | if ((tmp < 0x10) && time_before(again, jiffies)) { |
1156 | again = jiffies + HZ * 60; | 1154 | again = jiffies + HZ * 60; |
1157 | /* Page 48 of version 2.0 of the CL-CD1865 databook */ | 1155 | /* Page 48 of version 2.0 of the CL-CD1865 databook */ |
1158 | if (tmp >= 12) { | 1156 | if (tmp >= 12) { |
@@ -1164,27 +1162,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1164 | printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" | 1162 | printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n" |
1165 | "Warning: overstressing Cirrus chip. " | 1163 | "Warning: overstressing Cirrus chip. " |
1166 | "This might not work.\n" | 1164 | "This might not work.\n" |
1167 | "Read specialix.txt for more info.\n", | 1165 | "Read specialix.txt for more info.\n", |
1168 | port_No (port), tmp); | 1166 | port_No (port), tmp); |
1169 | } | 1167 | } |
1170 | } | 1168 | } |
1171 | spin_lock_irqsave(&bp->lock, flags); | 1169 | spin_lock_irqsave(&bp->lock, flags); |
1172 | sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); | 1170 | sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); |
1173 | sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); | 1171 | sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); |
1174 | sx_out(bp, CD186x_RBPRL, tmp & 0xff); | 1172 | sx_out(bp, CD186x_RBPRL, tmp & 0xff); |
1175 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); | 1173 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); |
1176 | spin_unlock_irqrestore(&bp->lock, flags); | 1174 | spin_unlock_irqrestore(&bp->lock, flags); |
1177 | if (port->custom_divisor) { | 1175 | if (port->custom_divisor) { |
1178 | baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; | 1176 | baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; |
1179 | baud = ( baud + 5 ) / 10; | 1177 | baud = ( baud + 5 ) / 10; |
1180 | } else | 1178 | } else |
1181 | baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ | 1179 | baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ |
1182 | 1180 | ||
1183 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | 1181 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ |
1184 | tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; | 1182 | tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; |
1185 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? | 1183 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? |
1186 | SERIAL_XMIT_SIZE - 1 : tmp); | 1184 | SERIAL_XMIT_SIZE - 1 : tmp); |
1187 | 1185 | ||
1188 | /* Receiver timeout will be transmission time for 1.5 chars */ | 1186 | /* Receiver timeout will be transmission time for 1.5 chars */ |
1189 | tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud; | 1187 | tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud; |
1190 | tmp = (tmp > 0xff) ? 0xff : tmp; | 1188 | tmp = (tmp > 0xff) ? 0xff : tmp; |
@@ -1205,29 +1203,29 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1205 | cor1 |= COR1_8BITS; | 1203 | cor1 |= COR1_8BITS; |
1206 | break; | 1204 | break; |
1207 | } | 1205 | } |
1208 | 1206 | ||
1209 | if (C_CSTOPB(tty)) | 1207 | if (C_CSTOPB(tty)) |
1210 | cor1 |= COR1_2SB; | 1208 | cor1 |= COR1_2SB; |
1211 | 1209 | ||
1212 | cor1 |= COR1_IGNORE; | 1210 | cor1 |= COR1_IGNORE; |
1213 | if (C_PARENB(tty)) { | 1211 | if (C_PARENB(tty)) { |
1214 | cor1 |= COR1_NORMPAR; | 1212 | cor1 |= COR1_NORMPAR; |
1215 | if (C_PARODD(tty)) | 1213 | if (C_PARODD(tty)) |
1216 | cor1 |= COR1_ODDP; | 1214 | cor1 |= COR1_ODDP; |
1217 | if (I_INPCK(tty)) | 1215 | if (I_INPCK(tty)) |
1218 | cor1 &= ~COR1_IGNORE; | 1216 | cor1 &= ~COR1_IGNORE; |
1219 | } | 1217 | } |
1220 | /* Set marking of some errors */ | 1218 | /* Set marking of some errors */ |
1221 | port->mark_mask = RCSR_OE | RCSR_TOUT; | 1219 | port->mark_mask = RCSR_OE | RCSR_TOUT; |
1222 | if (I_INPCK(tty)) | 1220 | if (I_INPCK(tty)) |
1223 | port->mark_mask |= RCSR_FE | RCSR_PE; | 1221 | port->mark_mask |= RCSR_FE | RCSR_PE; |
1224 | if (I_BRKINT(tty) || I_PARMRK(tty)) | 1222 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
1225 | port->mark_mask |= RCSR_BREAK; | 1223 | port->mark_mask |= RCSR_BREAK; |
1226 | if (I_IGNPAR(tty)) | 1224 | if (I_IGNPAR(tty)) |
1227 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); | 1225 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); |
1228 | if (I_IGNBRK(tty)) { | 1226 | if (I_IGNBRK(tty)) { |
1229 | port->mark_mask &= ~RCSR_BREAK; | 1227 | port->mark_mask &= ~RCSR_BREAK; |
1230 | if (I_IGNPAR(tty)) | 1228 | if (I_IGNPAR(tty)) |
1231 | /* Real raw mode. Ignore all */ | 1229 | /* Real raw mode. Ignore all */ |
1232 | port->mark_mask &= ~RCSR_OE; | 1230 | port->mark_mask &= ~RCSR_OE; |
1233 | } | 1231 | } |
@@ -1241,7 +1239,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1241 | tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR)); | 1239 | tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR)); |
1242 | spin_unlock_irqrestore(&bp->lock, flags); | 1240 | spin_unlock_irqrestore(&bp->lock, flags); |
1243 | #else | 1241 | #else |
1244 | port->COR2 |= COR2_CTSAE; | 1242 | port->COR2 |= COR2_CTSAE; |
1245 | #endif | 1243 | #endif |
1246 | } | 1244 | } |
1247 | /* Enable Software Flow Control. FIXME: I'm not sure about this */ | 1245 | /* Enable Software Flow Control. FIXME: I'm not sure about this */ |
@@ -1264,11 +1262,11 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1264 | mcor1 |= MCOR1_CDZD; | 1262 | mcor1 |= MCOR1_CDZD; |
1265 | mcor2 |= MCOR2_CDOD; | 1263 | mcor2 |= MCOR2_CDOD; |
1266 | } | 1264 | } |
1267 | 1265 | ||
1268 | if (C_CREAD(tty)) | 1266 | if (C_CREAD(tty)) |
1269 | /* Enable receiver */ | 1267 | /* Enable receiver */ |
1270 | port->IER |= IER_RXD; | 1268 | port->IER |= IER_RXD; |
1271 | 1269 | ||
1272 | /* Set input FIFO size (1-8 bytes) */ | 1270 | /* Set input FIFO size (1-8 bytes) */ |
1273 | cor3 |= sx_rxfifo; | 1271 | cor3 |= sx_rxfifo; |
1274 | /* Setting up CD186x channel registers */ | 1272 | /* Setting up CD186x channel registers */ |
@@ -1311,11 +1309,11 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port | |||
1311 | func_exit(); | 1309 | func_exit(); |
1312 | return 0; | 1310 | return 0; |
1313 | } | 1311 | } |
1314 | 1312 | ||
1315 | if (!port->xmit_buf) { | 1313 | if (!port->xmit_buf) { |
1316 | /* We may sleep in get_zeroed_page() */ | 1314 | /* We may sleep in get_zeroed_page() */ |
1317 | unsigned long tmp; | 1315 | unsigned long tmp; |
1318 | 1316 | ||
1319 | if (!(tmp = get_zeroed_page(GFP_KERNEL))) { | 1317 | if (!(tmp = get_zeroed_page(GFP_KERNEL))) { |
1320 | func_exit(); | 1318 | func_exit(); |
1321 | return -ENOMEM; | 1319 | return -ENOMEM; |
@@ -1328,10 +1326,10 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port | |||
1328 | } | 1326 | } |
1329 | port->xmit_buf = (unsigned char *) tmp; | 1327 | port->xmit_buf = (unsigned char *) tmp; |
1330 | } | 1328 | } |
1331 | 1329 | ||
1332 | spin_lock_irqsave(&port->lock, flags); | 1330 | spin_lock_irqsave(&port->lock, flags); |
1333 | 1331 | ||
1334 | if (port->tty) | 1332 | if (port->tty) |
1335 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 1333 | clear_bit(TTY_IO_ERROR, &port->tty->flags); |
1336 | 1334 | ||
1337 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 1335 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
@@ -1340,7 +1338,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port | |||
1340 | 1338 | ||
1341 | spin_unlock_irqrestore(&port->lock, flags); | 1339 | spin_unlock_irqrestore(&port->lock, flags); |
1342 | 1340 | ||
1343 | 1341 | ||
1344 | func_exit(); | 1342 | func_exit(); |
1345 | return 0; | 1343 | return 0; |
1346 | } | 1344 | } |
@@ -1352,14 +1350,14 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * | |||
1352 | struct tty_struct *tty; | 1350 | struct tty_struct *tty; |
1353 | int i; | 1351 | int i; |
1354 | unsigned long flags; | 1352 | unsigned long flags; |
1355 | 1353 | ||
1356 | func_enter(); | 1354 | func_enter(); |
1357 | 1355 | ||
1358 | if (!(port->flags & ASYNC_INITIALIZED)) { | 1356 | if (!(port->flags & ASYNC_INITIALIZED)) { |
1359 | func_exit(); | 1357 | func_exit(); |
1360 | return; | 1358 | return; |
1361 | } | 1359 | } |
1362 | 1360 | ||
1363 | if (sx_debug & SX_DEBUG_FIFO) { | 1361 | if (sx_debug & SX_DEBUG_FIFO) { |
1364 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ", | 1362 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ", |
1365 | board_No(bp), port_No(port), port->overrun); | 1363 | board_No(bp), port_No(port), port->overrun); |
@@ -1394,13 +1392,13 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port * | |||
1394 | if (tty) | 1392 | if (tty) |
1395 | set_bit(TTY_IO_ERROR, &tty->flags); | 1393 | set_bit(TTY_IO_ERROR, &tty->flags); |
1396 | port->flags &= ~ASYNC_INITIALIZED; | 1394 | port->flags &= ~ASYNC_INITIALIZED; |
1397 | 1395 | ||
1398 | if (!bp->count) | 1396 | if (!bp->count) |
1399 | sx_shutdown_board(bp); | 1397 | sx_shutdown_board(bp); |
1400 | func_exit(); | 1398 | func_exit(); |
1401 | } | 1399 | } |
1402 | 1400 | ||
1403 | 1401 | ||
1404 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | 1402 | static int block_til_ready(struct tty_struct *tty, struct file * filp, |
1405 | struct specialix_port *port) | 1403 | struct specialix_port *port) |
1406 | { | 1404 | { |
@@ -1427,7 +1425,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1427 | return -ERESTARTSYS; | 1425 | return -ERESTARTSYS; |
1428 | } | 1426 | } |
1429 | } | 1427 | } |
1430 | 1428 | ||
1431 | /* | 1429 | /* |
1432 | * If non-blocking mode is set, or the port is not enabled, | 1430 | * If non-blocking mode is set, or the port is not enabled, |
1433 | * then make the check up front and then exit. | 1431 | * then make the check up front and then exit. |
@@ -1477,7 +1475,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1477 | if (port->flags & ASYNC_HUP_NOTIFY) | 1475 | if (port->flags & ASYNC_HUP_NOTIFY) |
1478 | retval = -EAGAIN; | 1476 | retval = -EAGAIN; |
1479 | else | 1477 | else |
1480 | retval = -ERESTARTSYS; | 1478 | retval = -ERESTARTSYS; |
1481 | break; | 1479 | break; |
1482 | } | 1480 | } |
1483 | if (!(port->flags & ASYNC_CLOSING) && | 1481 | if (!(port->flags & ASYNC_CLOSING) && |
@@ -1506,7 +1504,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1506 | port->flags |= ASYNC_NORMAL_ACTIVE; | 1504 | port->flags |= ASYNC_NORMAL_ACTIVE; |
1507 | func_exit(); | 1505 | func_exit(); |
1508 | return 0; | 1506 | return 0; |
1509 | } | 1507 | } |
1510 | 1508 | ||
1511 | 1509 | ||
1512 | static int sx_open(struct tty_struct * tty, struct file * filp) | 1510 | static int sx_open(struct tty_struct * tty, struct file * filp) |
@@ -1526,7 +1524,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1526 | func_exit(); | 1524 | func_exit(); |
1527 | return -ENODEV; | 1525 | return -ENODEV; |
1528 | } | 1526 | } |
1529 | 1527 | ||
1530 | bp = &sx_board[board]; | 1528 | bp = &sx_board[board]; |
1531 | port = sx_port + board * SX_NPORT + SX_PORT(tty->index); | 1529 | port = sx_port + board * SX_NPORT + SX_PORT(tty->index); |
1532 | port->overrun = 0; | 1530 | port->overrun = 0; |
@@ -1557,7 +1555,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1557 | func_enter(); | 1555 | func_enter(); |
1558 | return error; | 1556 | return error; |
1559 | } | 1557 | } |
1560 | 1558 | ||
1561 | if ((error = block_til_ready(tty, filp, port))) { | 1559 | if ((error = block_til_ready(tty, filp, port))) { |
1562 | func_enter(); | 1560 | func_enter(); |
1563 | return error; | 1561 | return error; |
@@ -1574,7 +1572,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1574 | struct specialix_board *bp; | 1572 | struct specialix_board *bp; |
1575 | unsigned long flags; | 1573 | unsigned long flags; |
1576 | unsigned long timeout; | 1574 | unsigned long timeout; |
1577 | 1575 | ||
1578 | func_enter(); | 1576 | func_enter(); |
1579 | if (!port || sx_paranoia_check(port, tty->name, "close")) { | 1577 | if (!port || sx_paranoia_check(port, tty->name, "close")) { |
1580 | func_exit(); | 1578 | func_exit(); |
@@ -1587,7 +1585,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1587 | func_exit(); | 1585 | func_exit(); |
1588 | return; | 1586 | return; |
1589 | } | 1587 | } |
1590 | 1588 | ||
1591 | bp = port_Board(port); | 1589 | bp = port_Board(port); |
1592 | if ((tty->count == 1) && (port->count != 1)) { | 1590 | if ((tty->count == 1) && (port->count != 1)) { |
1593 | printk(KERN_ERR "sx%d: sx_close: bad port count;" | 1591 | printk(KERN_ERR "sx%d: sx_close: bad port count;" |
@@ -1607,7 +1605,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1607 | } | 1605 | } |
1608 | port->flags |= ASYNC_CLOSING; | 1606 | port->flags |= ASYNC_CLOSING; |
1609 | /* | 1607 | /* |
1610 | * Now we wait for the transmit buffer to clear; and we notify | 1608 | * Now we wait for the transmit buffer to clear; and we notify |
1611 | * the line discipline to only process XON/XOFF characters. | 1609 | * the line discipline to only process XON/XOFF characters. |
1612 | */ | 1610 | */ |
1613 | tty->closing = 1; | 1611 | tty->closing = 1; |
@@ -1681,7 +1679,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1681 | } | 1679 | } |
1682 | 1680 | ||
1683 | 1681 | ||
1684 | static int sx_write(struct tty_struct * tty, | 1682 | static int sx_write(struct tty_struct * tty, |
1685 | const unsigned char *buf, int count) | 1683 | const unsigned char *buf, int count) |
1686 | { | 1684 | { |
1687 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1685 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
@@ -1694,7 +1692,7 @@ static int sx_write(struct tty_struct * tty, | |||
1694 | func_exit(); | 1692 | func_exit(); |
1695 | return 0; | 1693 | return 0; |
1696 | } | 1694 | } |
1697 | 1695 | ||
1698 | bp = port_Board(port); | 1696 | bp = port_Board(port); |
1699 | 1697 | ||
1700 | if (!tty || !port->xmit_buf || !tmp_buf) { | 1698 | if (!tty || !port->xmit_buf || !tmp_buf) { |
@@ -1824,7 +1822,7 @@ static int sx_chars_in_buffer(struct tty_struct *tty) | |||
1824 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1822 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1825 | 1823 | ||
1826 | func_enter(); | 1824 | func_enter(); |
1827 | 1825 | ||
1828 | if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) { | 1826 | if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) { |
1829 | func_exit(); | 1827 | func_exit(); |
1830 | return 0; | 1828 | return 0; |
@@ -1881,13 +1879,13 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) | |||
1881 | port_No(port), status, sx_in (bp, CD186x_CAR)); | 1879 | port_No(port), status, sx_in (bp, CD186x_CAR)); |
1882 | dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); | 1880 | dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); |
1883 | if (SX_CRTSCTS(port->tty)) { | 1881 | if (SX_CRTSCTS(port->tty)) { |
1884 | result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ | 1882 | result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ |
1885 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) | 1883 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) |
1886 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1884 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1887 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | 1885 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |
1888 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); | 1886 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); |
1889 | } else { | 1887 | } else { |
1890 | result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ | 1888 | result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ |
1891 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) | 1889 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) |
1892 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1890 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1893 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | 1891 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ |
@@ -1955,7 +1953,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len | |||
1955 | { | 1953 | { |
1956 | struct specialix_board *bp = port_Board(port); | 1954 | struct specialix_board *bp = port_Board(port); |
1957 | unsigned long flags; | 1955 | unsigned long flags; |
1958 | 1956 | ||
1959 | func_enter(); | 1957 | func_enter(); |
1960 | 1958 | ||
1961 | spin_lock_irqsave (&port->lock, flags); | 1959 | spin_lock_irqsave (&port->lock, flags); |
@@ -1996,8 +1994,8 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1996 | func_enter(); | 1994 | func_enter(); |
1997 | return -EFAULT; | 1995 | return -EFAULT; |
1998 | } | 1996 | } |
1999 | 1997 | ||
2000 | #if 0 | 1998 | #if 0 |
2001 | if ((tmp.irq != bp->irq) || | 1999 | if ((tmp.irq != bp->irq) || |
2002 | (tmp.port != bp->base) || | 2000 | (tmp.port != bp->base) || |
2003 | (tmp.type != PORT_CIRRUS) || | 2001 | (tmp.type != PORT_CIRRUS) || |
@@ -2008,12 +2006,12 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
2008 | func_exit(); | 2006 | func_exit(); |
2009 | return -EINVAL; | 2007 | return -EINVAL; |
2010 | } | 2008 | } |
2011 | #endif | 2009 | #endif |
2012 | 2010 | ||
2013 | change_speed = ((port->flags & ASYNC_SPD_MASK) != | 2011 | change_speed = ((port->flags & ASYNC_SPD_MASK) != |
2014 | (tmp.flags & ASYNC_SPD_MASK)); | 2012 | (tmp.flags & ASYNC_SPD_MASK)); |
2015 | change_speed |= (tmp.custom_divisor != port->custom_divisor); | 2013 | change_speed |= (tmp.custom_divisor != port->custom_divisor); |
2016 | 2014 | ||
2017 | if (!capable(CAP_SYS_ADMIN)) { | 2015 | if (!capable(CAP_SYS_ADMIN)) { |
2018 | if ((tmp.close_delay != port->close_delay) || | 2016 | if ((tmp.close_delay != port->close_delay) || |
2019 | (tmp.closing_wait != port->closing_wait) || | 2017 | (tmp.closing_wait != port->closing_wait) || |
@@ -2045,7 +2043,7 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
2045 | { | 2043 | { |
2046 | struct serial_struct tmp; | 2044 | struct serial_struct tmp; |
2047 | struct specialix_board *bp = port_Board(port); | 2045 | struct specialix_board *bp = port_Board(port); |
2048 | 2046 | ||
2049 | func_enter(); | 2047 | func_enter(); |
2050 | 2048 | ||
2051 | /* | 2049 | /* |
@@ -2074,7 +2072,7 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
2074 | } | 2072 | } |
2075 | 2073 | ||
2076 | 2074 | ||
2077 | static int sx_ioctl(struct tty_struct * tty, struct file * filp, | 2075 | static int sx_ioctl(struct tty_struct * tty, struct file * filp, |
2078 | unsigned int cmd, unsigned long arg) | 2076 | unsigned int cmd, unsigned long arg) |
2079 | { | 2077 | { |
2080 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2078 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
@@ -2087,7 +2085,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2087 | func_exit(); | 2085 | func_exit(); |
2088 | return -ENODEV; | 2086 | return -ENODEV; |
2089 | } | 2087 | } |
2090 | 2088 | ||
2091 | switch (cmd) { | 2089 | switch (cmd) { |
2092 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 2090 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
2093 | retval = tty_check_change(tty); | 2091 | retval = tty_check_change(tty); |
@@ -2129,7 +2127,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2129 | case TIOCGSERIAL: | 2127 | case TIOCGSERIAL: |
2130 | func_exit(); | 2128 | func_exit(); |
2131 | return sx_get_serial_info(port, argp); | 2129 | return sx_get_serial_info(port, argp); |
2132 | case TIOCSSERIAL: | 2130 | case TIOCSSERIAL: |
2133 | func_exit(); | 2131 | func_exit(); |
2134 | return sx_set_serial_info(port, argp); | 2132 | return sx_set_serial_info(port, argp); |
2135 | default: | 2133 | default: |
@@ -2153,16 +2151,16 @@ static void sx_throttle(struct tty_struct * tty) | |||
2153 | func_exit(); | 2151 | func_exit(); |
2154 | return; | 2152 | return; |
2155 | } | 2153 | } |
2156 | 2154 | ||
2157 | bp = port_Board(port); | 2155 | bp = port_Board(port); |
2158 | 2156 | ||
2159 | /* Use DTR instead of RTS ! */ | 2157 | /* Use DTR instead of RTS ! */ |
2160 | if (SX_CRTSCTS (tty)) | 2158 | if (SX_CRTSCTS (tty)) |
2161 | port->MSVR &= ~MSVR_DTR; | 2159 | port->MSVR &= ~MSVR_DTR; |
2162 | else { | 2160 | else { |
2163 | /* Auch!!! I think the system shouldn't call this then. */ | 2161 | /* Auch!!! I think the system shouldn't call this then. */ |
2164 | /* Or maybe we're supposed (allowed?) to do our side of hw | 2162 | /* Or maybe we're supposed (allowed?) to do our side of hw |
2165 | handshake anyway, even when hardware handshake is off. | 2163 | handshake anyway, even when hardware handshake is off. |
2166 | When you see this in your logs, please report.... */ | 2164 | When you see this in your logs, please report.... */ |
2167 | printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n", | 2165 | printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n", |
2168 | port_No (port)); | 2166 | port_No (port)); |
@@ -2193,14 +2191,14 @@ static void sx_unthrottle(struct tty_struct * tty) | |||
2193 | unsigned long flags; | 2191 | unsigned long flags; |
2194 | 2192 | ||
2195 | func_enter(); | 2193 | func_enter(); |
2196 | 2194 | ||
2197 | if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) { | 2195 | if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) { |
2198 | func_exit(); | 2196 | func_exit(); |
2199 | return; | 2197 | return; |
2200 | } | 2198 | } |
2201 | 2199 | ||
2202 | bp = port_Board(port); | 2200 | bp = port_Board(port); |
2203 | 2201 | ||
2204 | spin_lock_irqsave(&port->lock, flags); | 2202 | spin_lock_irqsave(&port->lock, flags); |
2205 | /* XXXX Use DTR INSTEAD???? */ | 2203 | /* XXXX Use DTR INSTEAD???? */ |
2206 | if (SX_CRTSCTS(tty)) { | 2204 | if (SX_CRTSCTS(tty)) { |
@@ -2234,14 +2232,14 @@ static void sx_stop(struct tty_struct * tty) | |||
2234 | unsigned long flags; | 2232 | unsigned long flags; |
2235 | 2233 | ||
2236 | func_enter(); | 2234 | func_enter(); |
2237 | 2235 | ||
2238 | if (sx_paranoia_check(port, tty->name, "sx_stop")) { | 2236 | if (sx_paranoia_check(port, tty->name, "sx_stop")) { |
2239 | func_exit(); | 2237 | func_exit(); |
2240 | return; | 2238 | return; |
2241 | } | 2239 | } |
2242 | 2240 | ||
2243 | bp = port_Board(port); | 2241 | bp = port_Board(port); |
2244 | 2242 | ||
2245 | spin_lock_irqsave(&port->lock, flags); | 2243 | spin_lock_irqsave(&port->lock, flags); |
2246 | port->IER &= ~IER_TXRDY; | 2244 | port->IER &= ~IER_TXRDY; |
2247 | spin_lock_irqsave(&bp->lock, flags); | 2245 | spin_lock_irqsave(&bp->lock, flags); |
@@ -2261,14 +2259,14 @@ static void sx_start(struct tty_struct * tty) | |||
2261 | unsigned long flags; | 2259 | unsigned long flags; |
2262 | 2260 | ||
2263 | func_enter(); | 2261 | func_enter(); |
2264 | 2262 | ||
2265 | if (sx_paranoia_check(port, tty->name, "sx_start")) { | 2263 | if (sx_paranoia_check(port, tty->name, "sx_start")) { |
2266 | func_exit(); | 2264 | func_exit(); |
2267 | return; | 2265 | return; |
2268 | } | 2266 | } |
2269 | 2267 | ||
2270 | bp = port_Board(port); | 2268 | bp = port_Board(port); |
2271 | 2269 | ||
2272 | spin_lock_irqsave(&port->lock, flags); | 2270 | spin_lock_irqsave(&port->lock, flags); |
2273 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 2271 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
2274 | port->IER |= IER_TXRDY; | 2272 | port->IER |= IER_TXRDY; |
@@ -2290,13 +2288,13 @@ static void sx_start(struct tty_struct * tty) | |||
2290 | * | 2288 | * |
2291 | * serial interrupt routine -> (workqueue) -> | 2289 | * serial interrupt routine -> (workqueue) -> |
2292 | * do_sx_hangup() -> tty->hangup() -> sx_hangup() | 2290 | * do_sx_hangup() -> tty->hangup() -> sx_hangup() |
2293 | * | 2291 | * |
2294 | */ | 2292 | */ |
2295 | static void do_sx_hangup(void *private_) | 2293 | static void do_sx_hangup(void *private_) |
2296 | { | 2294 | { |
2297 | struct specialix_port *port = (struct specialix_port *) private_; | 2295 | struct specialix_port *port = (struct specialix_port *) private_; |
2298 | struct tty_struct *tty; | 2296 | struct tty_struct *tty; |
2299 | 2297 | ||
2300 | func_enter(); | 2298 | func_enter(); |
2301 | 2299 | ||
2302 | tty = port->tty; | 2300 | tty = port->tty; |
@@ -2319,9 +2317,9 @@ static void sx_hangup(struct tty_struct * tty) | |||
2319 | func_exit(); | 2317 | func_exit(); |
2320 | return; | 2318 | return; |
2321 | } | 2319 | } |
2322 | 2320 | ||
2323 | bp = port_Board(port); | 2321 | bp = port_Board(port); |
2324 | 2322 | ||
2325 | sx_shutdown_port(bp, port); | 2323 | sx_shutdown_port(bp, port); |
2326 | spin_lock_irqsave(&port->lock, flags); | 2324 | spin_lock_irqsave(&port->lock, flags); |
2327 | port->event = 0; | 2325 | port->event = 0; |
@@ -2346,10 +2344,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios | |||
2346 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2344 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2347 | unsigned long flags; | 2345 | unsigned long flags; |
2348 | struct specialix_board * bp; | 2346 | struct specialix_board * bp; |
2349 | 2347 | ||
2350 | if (sx_paranoia_check(port, tty->name, "sx_set_termios")) | 2348 | if (sx_paranoia_check(port, tty->name, "sx_set_termios")) |
2351 | return; | 2349 | return; |
2352 | 2350 | ||
2353 | if (tty->termios->c_cflag == old_termios->c_cflag && | 2351 | if (tty->termios->c_cflag == old_termios->c_cflag && |
2354 | tty->termios->c_iflag == old_termios->c_iflag) | 2352 | tty->termios->c_iflag == old_termios->c_iflag) |
2355 | return; | 2353 | return; |
@@ -2420,7 +2418,7 @@ static int sx_init_drivers(void) | |||
2420 | func_exit(); | 2418 | func_exit(); |
2421 | return 1; | 2419 | return 1; |
2422 | } | 2420 | } |
2423 | 2421 | ||
2424 | if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) { | 2422 | if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) { |
2425 | printk(KERN_ERR "sx: Couldn't get free page.\n"); | 2423 | printk(KERN_ERR "sx: Couldn't get free page.\n"); |
2426 | put_tty_driver(specialix_driver); | 2424 | put_tty_driver(specialix_driver); |
@@ -2457,7 +2455,7 @@ static int sx_init_drivers(void) | |||
2457 | init_waitqueue_head(&sx_port[i].close_wait); | 2455 | init_waitqueue_head(&sx_port[i].close_wait); |
2458 | spin_lock_init(&sx_port[i].lock); | 2456 | spin_lock_init(&sx_port[i].lock); |
2459 | } | 2457 | } |
2460 | 2458 | ||
2461 | func_exit(); | 2459 | func_exit(); |
2462 | return 0; | 2460 | return 0; |
2463 | } | 2461 | } |
@@ -2472,8 +2470,8 @@ static void sx_release_drivers(void) | |||
2472 | func_exit(); | 2470 | func_exit(); |
2473 | } | 2471 | } |
2474 | 2472 | ||
2475 | /* | 2473 | /* |
2476 | * This routine must be called by kernel at boot time | 2474 | * This routine must be called by kernel at boot time |
2477 | */ | 2475 | */ |
2478 | static int __init specialix_init(void) | 2476 | static int __init specialix_init(void) |
2479 | { | 2477 | { |
@@ -2489,7 +2487,7 @@ static int __init specialix_init(void) | |||
2489 | #else | 2487 | #else |
2490 | printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); | 2488 | printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); |
2491 | #endif | 2489 | #endif |
2492 | 2490 | ||
2493 | for (i = 0; i < SX_NBOARD; i++) | 2491 | for (i = 0; i < SX_NBOARD; i++) |
2494 | sx_board[i].lock = SPIN_LOCK_UNLOCKED; | 2492 | sx_board[i].lock = SPIN_LOCK_UNLOCKED; |
2495 | 2493 | ||
@@ -2498,7 +2496,7 @@ static int __init specialix_init(void) | |||
2498 | return -EIO; | 2496 | return -EIO; |
2499 | } | 2497 | } |
2500 | 2498 | ||
2501 | for (i = 0; i < SX_NBOARD; i++) | 2499 | for (i = 0; i < SX_NBOARD; i++) |
2502 | if (sx_board[i].base && !sx_probe(&sx_board[i])) | 2500 | if (sx_board[i].base && !sx_probe(&sx_board[i])) |
2503 | found++; | 2501 | found++; |
2504 | 2502 | ||
@@ -2512,8 +2510,8 @@ static int __init specialix_init(void) | |||
2512 | i++; | 2510 | i++; |
2513 | continue; | 2511 | continue; |
2514 | } | 2512 | } |
2515 | pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, | 2513 | pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, |
2516 | PCI_DEVICE_ID_SPECIALIX_IO8, | 2514 | PCI_DEVICE_ID_SPECIALIX_IO8, |
2517 | pdev); | 2515 | pdev); |
2518 | if (!pdev) break; | 2516 | if (!pdev) break; |
2519 | 2517 | ||
@@ -2557,10 +2555,10 @@ module_param(sx_poll, int, 0); | |||
2557 | /* | 2555 | /* |
2558 | * You can setup up to 4 boards. | 2556 | * You can setup up to 4 boards. |
2559 | * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter. | 2557 | * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter. |
2560 | * You should specify the IRQs too in that case "irq=....,...". | 2558 | * You should specify the IRQs too in that case "irq=....,...". |
2561 | * | 2559 | * |
2562 | * More than 4 boards in one computer is not possible, as the card can | 2560 | * More than 4 boards in one computer is not possible, as the card can |
2563 | * only use 4 different interrupts. | 2561 | * only use 4 different interrupts. |
2564 | * | 2562 | * |
2565 | */ | 2563 | */ |
2566 | static int __init specialix_init_module(void) | 2564 | static int __init specialix_init_module(void) |
@@ -2583,16 +2581,16 @@ static int __init specialix_init_module(void) | |||
2583 | 2581 | ||
2584 | return specialix_init(); | 2582 | return specialix_init(); |
2585 | } | 2583 | } |
2586 | 2584 | ||
2587 | static void __exit specialix_exit_module(void) | 2585 | static void __exit specialix_exit_module(void) |
2588 | { | 2586 | { |
2589 | int i; | 2587 | int i; |
2590 | 2588 | ||
2591 | func_enter(); | 2589 | func_enter(); |
2592 | 2590 | ||
2593 | sx_release_drivers(); | 2591 | sx_release_drivers(); |
2594 | for (i = 0; i < SX_NBOARD; i++) | 2592 | for (i = 0; i < SX_NBOARD; i++) |
2595 | if (sx_board[i].flags & SX_BOARD_PRESENT) | 2593 | if (sx_board[i].flags & SX_BOARD_PRESENT) |
2596 | sx_release_io_range(&sx_board[i]); | 2594 | sx_release_io_range(&sx_board[i]); |
2597 | #ifdef SPECIALIX_TIMER | 2595 | #ifdef SPECIALIX_TIMER |
2598 | del_timer (&missed_irq_timer); | 2596 | del_timer (&missed_irq_timer); |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index ea2d54be4843..0133dc0e25d0 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -912,6 +912,7 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); | |||
912 | MODULE_LICENSE("GPL"); | 912 | MODULE_LICENSE("GPL"); |
913 | 913 | ||
914 | static struct pci_driver synclink_pci_driver = { | 914 | static struct pci_driver synclink_pci_driver = { |
915 | .owner = THIS_MODULE, | ||
915 | .name = "synclink", | 916 | .name = "synclink", |
916 | .id_table = synclink_pci_tbl, | 917 | .id_table = synclink_pci_tbl, |
917 | .probe = synclink_init_one, | 918 | .probe = synclink_init_one, |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 6fb165cf8a61..f185724448b1 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -500,6 +500,7 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl); | |||
500 | MODULE_LICENSE("GPL"); | 500 | MODULE_LICENSE("GPL"); |
501 | 501 | ||
502 | static struct pci_driver synclinkmp_pci_driver = { | 502 | static struct pci_driver synclinkmp_pci_driver = { |
503 | .owner = THIS_MODULE, | ||
503 | .name = "synclinkmp", | 504 | .name = "synclinkmp", |
504 | .id_table = synclinkmp_pci_tbl, | 505 | .id_table = synclinkmp_pci_tbl, |
505 | .probe = synclinkmp_init_one, | 506 | .probe = synclinkmp_init_one, |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c new file mode 100644 index 000000000000..18cdd4361dc6 --- /dev/null +++ b/drivers/char/tlclk.c | |||
@@ -0,0 +1,896 @@ | |||
1 | /* | ||
2 | * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010 | ||
3 | * | ||
4 | * Copyright (C) 2005 Kontron Canada | ||
5 | * | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
16 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
17 | * details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * Send feedback to <sebastien.bouchard@ca.kontron.com> and the current | ||
24 | * Maintainer <mark.gross@intel.com> | ||
25 | * | ||
26 | * Description : This is the TELECOM CLOCK module driver for the ATCA | ||
27 | * MPCBL0010 ATCA computer. | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/sched.h> | ||
34 | #include <linux/kernel.h> /* printk() */ | ||
35 | #include <linux/fs.h> /* everything... */ | ||
36 | #include <linux/errno.h> /* error codes */ | ||
37 | #include <linux/delay.h> /* udelay */ | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/ioport.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/spinlock.h> | ||
42 | #include <linux/timer.h> | ||
43 | #include <linux/sysfs.h> | ||
44 | #include <linux/device.h> | ||
45 | #include <linux/miscdevice.h> | ||
46 | #include <asm/io.h> /* inb/outb */ | ||
47 | #include <asm/uaccess.h> | ||
48 | |||
49 | MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>"); | ||
50 | MODULE_LICENSE("GPL"); | ||
51 | |||
52 | /*Hardware Reset of the PLL */ | ||
53 | #define RESET_ON 0x00 | ||
54 | #define RESET_OFF 0x01 | ||
55 | |||
56 | /* MODE SELECT */ | ||
57 | #define NORMAL_MODE 0x00 | ||
58 | #define HOLDOVER_MODE 0x10 | ||
59 | #define FREERUN_MODE 0x20 | ||
60 | |||
61 | /* FILTER SELECT */ | ||
62 | #define FILTER_6HZ 0x04 | ||
63 | #define FILTER_12HZ 0x00 | ||
64 | |||
65 | /* SELECT REFERENCE FREQUENCY */ | ||
66 | #define REF_CLK1_8kHz 0x00 | ||
67 | #define REF_CLK2_19_44MHz 0x02 | ||
68 | |||
69 | /* Select primary or secondary redundant clock */ | ||
70 | #define PRIMARY_CLOCK 0x00 | ||
71 | #define SECONDARY_CLOCK 0x01 | ||
72 | |||
73 | /* CLOCK TRANSMISSION DEFINE */ | ||
74 | #define CLK_8kHz 0xff | ||
75 | #define CLK_16_384MHz 0xfb | ||
76 | |||
77 | #define CLK_1_544MHz 0x00 | ||
78 | #define CLK_2_048MHz 0x01 | ||
79 | #define CLK_4_096MHz 0x02 | ||
80 | #define CLK_6_312MHz 0x03 | ||
81 | #define CLK_8_192MHz 0x04 | ||
82 | #define CLK_19_440MHz 0x06 | ||
83 | |||
84 | #define CLK_8_592MHz 0x08 | ||
85 | #define CLK_11_184MHz 0x09 | ||
86 | #define CLK_34_368MHz 0x0b | ||
87 | #define CLK_44_736MHz 0x0a | ||
88 | |||
89 | /* RECEIVED REFERENCE */ | ||
90 | #define AMC_B1 0 | ||
91 | #define AMC_B2 1 | ||
92 | |||
93 | /* HARDWARE SWITCHING DEFINE */ | ||
94 | #define HW_ENABLE 0x80 | ||
95 | #define HW_DISABLE 0x00 | ||
96 | |||
97 | /* HARDWARE SWITCHING MODE DEFINE */ | ||
98 | #define PLL_HOLDOVER 0x40 | ||
99 | #define LOST_CLOCK 0x00 | ||
100 | |||
101 | /* ALARMS DEFINE */ | ||
102 | #define UNLOCK_MASK 0x10 | ||
103 | #define HOLDOVER_MASK 0x20 | ||
104 | #define SEC_LOST_MASK 0x40 | ||
105 | #define PRI_LOST_MASK 0x80 | ||
106 | |||
107 | /* INTERRUPT CAUSE DEFINE */ | ||
108 | |||
109 | #define PRI_LOS_01_MASK 0x01 | ||
110 | #define PRI_LOS_10_MASK 0x02 | ||
111 | |||
112 | #define SEC_LOS_01_MASK 0x04 | ||
113 | #define SEC_LOS_10_MASK 0x08 | ||
114 | |||
115 | #define HOLDOVER_01_MASK 0x10 | ||
116 | #define HOLDOVER_10_MASK 0x20 | ||
117 | |||
118 | #define UNLOCK_01_MASK 0x40 | ||
119 | #define UNLOCK_10_MASK 0x80 | ||
120 | |||
121 | struct tlclk_alarms { | ||
122 | __u32 lost_clocks; | ||
123 | __u32 lost_primary_clock; | ||
124 | __u32 lost_secondary_clock; | ||
125 | __u32 primary_clock_back; | ||
126 | __u32 secondary_clock_back; | ||
127 | __u32 switchover_primary; | ||
128 | __u32 switchover_secondary; | ||
129 | __u32 pll_holdover; | ||
130 | __u32 pll_end_holdover; | ||
131 | __u32 pll_lost_sync; | ||
132 | __u32 pll_sync; | ||
133 | }; | ||
134 | /* Telecom clock I/O register definition */ | ||
135 | #define TLCLK_BASE 0xa08 | ||
136 | #define TLCLK_REG0 TLCLK_BASE | ||
137 | #define TLCLK_REG1 (TLCLK_BASE+1) | ||
138 | #define TLCLK_REG2 (TLCLK_BASE+2) | ||
139 | #define TLCLK_REG3 (TLCLK_BASE+3) | ||
140 | #define TLCLK_REG4 (TLCLK_BASE+4) | ||
141 | #define TLCLK_REG5 (TLCLK_BASE+5) | ||
142 | #define TLCLK_REG6 (TLCLK_BASE+6) | ||
143 | #define TLCLK_REG7 (TLCLK_BASE+7) | ||
144 | |||
145 | #define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port) | ||
146 | |||
147 | /* 0 = Dynamic allocation of the major device number */ | ||
148 | #define TLCLK_MAJOR 0 | ||
149 | |||
150 | /* sysfs interface definition: | ||
151 | Upon loading the driver will create a sysfs directory under | ||
152 | /sys/devices/platform/telco_clock. | ||
153 | |||
154 | This directory exports the following interfaces. There operation is | ||
155 | documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4. | ||
156 | alarms : | ||
157 | current_ref : | ||
158 | enable_clk3a_output : | ||
159 | enable_clk3b_output : | ||
160 | enable_clka0_output : | ||
161 | enable_clka1_output : | ||
162 | enable_clkb0_output : | ||
163 | enable_clkb1_output : | ||
164 | filter_select : | ||
165 | hardware_switching : | ||
166 | hardware_switching_mode : | ||
167 | interrupt_switch : | ||
168 | mode_select : | ||
169 | refalign : | ||
170 | reset : | ||
171 | select_amcb1_transmit_clock : | ||
172 | select_amcb2_transmit_clock : | ||
173 | select_redundant_clock : | ||
174 | select_ref_frequency : | ||
175 | test_mode : | ||
176 | |||
177 | All sysfs interfaces are integers in hex format, i.e echo 99 > refalign | ||
178 | has the same effect as echo 0x99 > refalign. | ||
179 | */ | ||
180 | |||
181 | static unsigned int telclk_interrupt; | ||
182 | |||
183 | static int int_events; /* Event that generate a interrupt */ | ||
184 | static int got_event; /* if events processing have been done */ | ||
185 | |||
186 | static void switchover_timeout(unsigned long data); | ||
187 | static struct timer_list switchover_timer = | ||
188 | TIMER_INITIALIZER(switchover_timeout , 0, 0); | ||
189 | |||
190 | static struct tlclk_alarms *alarm_events; | ||
191 | |||
192 | static DEFINE_SPINLOCK(event_lock); | ||
193 | |||
194 | static int tlclk_major = TLCLK_MAJOR; | ||
195 | |||
196 | static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs); | ||
197 | |||
198 | static DECLARE_WAIT_QUEUE_HEAD(wq); | ||
199 | |||
200 | static int tlclk_open(struct inode *inode, struct file *filp) | ||
201 | { | ||
202 | int result; | ||
203 | |||
204 | /* Make sure there is no interrupt pending while | ||
205 | * initialising interrupt handler */ | ||
206 | inb(TLCLK_REG6); | ||
207 | |||
208 | /* This device is wired through the FPGA IO space of the ATCA blade | ||
209 | * we can't share this IRQ */ | ||
210 | result = request_irq(telclk_interrupt, &tlclk_interrupt, | ||
211 | SA_INTERRUPT, "telco_clock", tlclk_interrupt); | ||
212 | if (result == -EBUSY) { | ||
213 | printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n"); | ||
214 | return -EBUSY; | ||
215 | } | ||
216 | inb(TLCLK_REG6); /* Clear interrupt events */ | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int tlclk_release(struct inode *inode, struct file *filp) | ||
222 | { | ||
223 | free_irq(telclk_interrupt, tlclk_interrupt); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, | ||
229 | loff_t *f_pos) | ||
230 | { | ||
231 | if (count < sizeof(struct tlclk_alarms)) | ||
232 | return -EIO; | ||
233 | |||
234 | wait_event_interruptible(wq, got_event); | ||
235 | if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) | ||
236 | return -EFAULT; | ||
237 | |||
238 | memset(alarm_events, 0, sizeof(struct tlclk_alarms)); | ||
239 | got_event = 0; | ||
240 | |||
241 | return sizeof(struct tlclk_alarms); | ||
242 | } | ||
243 | |||
244 | ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, | ||
245 | loff_t *f_pos) | ||
246 | { | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static struct file_operations tlclk_fops = { | ||
251 | .read = tlclk_read, | ||
252 | .write = tlclk_write, | ||
253 | .open = tlclk_open, | ||
254 | .release = tlclk_release, | ||
255 | |||
256 | }; | ||
257 | |||
258 | static struct miscdevice tlclk_miscdev = { | ||
259 | .minor = MISC_DYNAMIC_MINOR, | ||
260 | .name = "telco_clock", | ||
261 | .fops = &tlclk_fops, | ||
262 | }; | ||
263 | |||
264 | static ssize_t show_current_ref(struct device *d, | ||
265 | struct device_attribute *attr, char *buf) | ||
266 | { | ||
267 | unsigned long ret_val; | ||
268 | unsigned long flags; | ||
269 | |||
270 | spin_lock_irqsave(&event_lock, flags); | ||
271 | ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3); | ||
272 | spin_unlock_irqrestore(&event_lock, flags); | ||
273 | |||
274 | return sprintf(buf, "0x%lX\n", ret_val); | ||
275 | } | ||
276 | |||
277 | static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL); | ||
278 | |||
279 | |||
280 | static ssize_t show_interrupt_switch(struct device *d, | ||
281 | struct device_attribute *attr, char *buf) | ||
282 | { | ||
283 | unsigned long ret_val; | ||
284 | unsigned long flags; | ||
285 | |||
286 | spin_lock_irqsave(&event_lock, flags); | ||
287 | ret_val = inb(TLCLK_REG6); | ||
288 | spin_unlock_irqrestore(&event_lock, flags); | ||
289 | |||
290 | return sprintf(buf, "0x%lX\n", ret_val); | ||
291 | } | ||
292 | |||
293 | static DEVICE_ATTR(interrupt_switch, S_IRUGO, | ||
294 | show_interrupt_switch, NULL); | ||
295 | |||
296 | static ssize_t show_alarms(struct device *d, | ||
297 | struct device_attribute *attr, char *buf) | ||
298 | { | ||
299 | unsigned long ret_val; | ||
300 | unsigned long flags; | ||
301 | |||
302 | spin_lock_irqsave(&event_lock, flags); | ||
303 | ret_val = (inb(TLCLK_REG2) & 0xf0); | ||
304 | spin_unlock_irqrestore(&event_lock, flags); | ||
305 | |||
306 | return sprintf(buf, "0x%lX\n", ret_val); | ||
307 | } | ||
308 | |||
309 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
310 | |||
311 | static ssize_t store_enable_clk3b_output(struct device *d, | ||
312 | struct device_attribute *attr, const char *buf, size_t count) | ||
313 | { | ||
314 | unsigned long tmp; | ||
315 | unsigned char val; | ||
316 | unsigned long flags; | ||
317 | |||
318 | sscanf(buf, "%lX", &tmp); | ||
319 | dev_dbg(d, ": tmp = 0x%lX\n", tmp); | ||
320 | |||
321 | val = (unsigned char)tmp; | ||
322 | spin_lock_irqsave(&event_lock, flags); | ||
323 | SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7); | ||
324 | spin_unlock_irqrestore(&event_lock, flags); | ||
325 | |||
326 | return strnlen(buf, count); | ||
327 | } | ||
328 | |||
329 | static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, | ||
330 | store_enable_clk3b_output); | ||
331 | |||
332 | static ssize_t store_enable_clk3a_output(struct device *d, | ||
333 | struct device_attribute *attr, const char *buf, size_t count) | ||
334 | { | ||
335 | unsigned long flags; | ||
336 | unsigned long tmp; | ||
337 | unsigned char val; | ||
338 | |||
339 | sscanf(buf, "%lX", &tmp); | ||
340 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
341 | |||
342 | val = (unsigned char)tmp; | ||
343 | spin_lock_irqsave(&event_lock, flags); | ||
344 | SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6); | ||
345 | spin_unlock_irqrestore(&event_lock, flags); | ||
346 | |||
347 | return strnlen(buf, count); | ||
348 | } | ||
349 | |||
350 | static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, | ||
351 | store_enable_clk3a_output); | ||
352 | |||
353 | static ssize_t store_enable_clkb1_output(struct device *d, | ||
354 | struct device_attribute *attr, const char *buf, size_t count) | ||
355 | { | ||
356 | unsigned long flags; | ||
357 | unsigned long tmp; | ||
358 | unsigned char val; | ||
359 | |||
360 | sscanf(buf, "%lX", &tmp); | ||
361 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
362 | |||
363 | val = (unsigned char)tmp; | ||
364 | spin_lock_irqsave(&event_lock, flags); | ||
365 | SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3); | ||
366 | spin_unlock_irqrestore(&event_lock, flags); | ||
367 | |||
368 | return strnlen(buf, count); | ||
369 | } | ||
370 | |||
371 | static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, | ||
372 | store_enable_clkb1_output); | ||
373 | |||
374 | |||
375 | static ssize_t store_enable_clka1_output(struct device *d, | ||
376 | struct device_attribute *attr, const char *buf, size_t count) | ||
377 | { | ||
378 | unsigned long flags; | ||
379 | unsigned long tmp; | ||
380 | unsigned char val; | ||
381 | |||
382 | sscanf(buf, "%lX", &tmp); | ||
383 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
384 | |||
385 | val = (unsigned char)tmp; | ||
386 | spin_lock_irqsave(&event_lock, flags); | ||
387 | SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2); | ||
388 | spin_unlock_irqrestore(&event_lock, flags); | ||
389 | |||
390 | return strnlen(buf, count); | ||
391 | } | ||
392 | |||
393 | static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, | ||
394 | store_enable_clka1_output); | ||
395 | |||
396 | static ssize_t store_enable_clkb0_output(struct device *d, | ||
397 | struct device_attribute *attr, const char *buf, size_t count) | ||
398 | { | ||
399 | unsigned long flags; | ||
400 | unsigned long tmp; | ||
401 | unsigned char val; | ||
402 | |||
403 | sscanf(buf, "%lX", &tmp); | ||
404 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
405 | |||
406 | val = (unsigned char)tmp; | ||
407 | spin_lock_irqsave(&event_lock, flags); | ||
408 | SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1); | ||
409 | spin_unlock_irqrestore(&event_lock, flags); | ||
410 | |||
411 | return strnlen(buf, count); | ||
412 | } | ||
413 | |||
414 | static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, | ||
415 | store_enable_clkb0_output); | ||
416 | |||
417 | static ssize_t store_enable_clka0_output(struct device *d, | ||
418 | struct device_attribute *attr, const char *buf, size_t count) | ||
419 | { | ||
420 | unsigned long flags; | ||
421 | unsigned long tmp; | ||
422 | unsigned char val; | ||
423 | |||
424 | sscanf(buf, "%lX", &tmp); | ||
425 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
426 | |||
427 | val = (unsigned char)tmp; | ||
428 | spin_lock_irqsave(&event_lock, flags); | ||
429 | SET_PORT_BITS(TLCLK_REG2, 0xfe, val); | ||
430 | spin_unlock_irqrestore(&event_lock, flags); | ||
431 | |||
432 | return strnlen(buf, count); | ||
433 | } | ||
434 | |||
435 | static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, | ||
436 | store_enable_clka0_output); | ||
437 | |||
438 | static ssize_t store_test_mode(struct device *d, | ||
439 | struct device_attribute *attr, const char *buf, size_t count) | ||
440 | { | ||
441 | unsigned long flags; | ||
442 | unsigned long tmp; | ||
443 | unsigned char val; | ||
444 | |||
445 | sscanf(buf, "%lX", &tmp); | ||
446 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
447 | |||
448 | val = (unsigned char)tmp; | ||
449 | spin_lock_irqsave(&event_lock, flags); | ||
450 | SET_PORT_BITS(TLCLK_REG4, 0xfd, 2); | ||
451 | spin_unlock_irqrestore(&event_lock, flags); | ||
452 | |||
453 | return strnlen(buf, count); | ||
454 | } | ||
455 | |||
456 | static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode); | ||
457 | |||
458 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, | ||
459 | struct device_attribute *attr, const char *buf, size_t count) | ||
460 | { | ||
461 | unsigned long flags; | ||
462 | unsigned long tmp; | ||
463 | unsigned char val; | ||
464 | |||
465 | sscanf(buf, "%lX", &tmp); | ||
466 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
467 | |||
468 | val = (unsigned char)tmp; | ||
469 | spin_lock_irqsave(&event_lock, flags); | ||
470 | if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { | ||
471 | SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28); | ||
472 | SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); | ||
473 | } else if (val >= CLK_8_592MHz) { | ||
474 | SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); | ||
475 | switch (val) { | ||
476 | case CLK_8_592MHz: | ||
477 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); | ||
478 | break; | ||
479 | case CLK_11_184MHz: | ||
480 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); | ||
481 | break; | ||
482 | case CLK_34_368MHz: | ||
483 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); | ||
484 | break; | ||
485 | case CLK_44_736MHz: | ||
486 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); | ||
487 | break; | ||
488 | } | ||
489 | } else | ||
490 | SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3); | ||
491 | |||
492 | spin_unlock_irqrestore(&event_lock, flags); | ||
493 | |||
494 | return strnlen(buf, count); | ||
495 | } | ||
496 | |||
497 | static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, | ||
498 | store_select_amcb2_transmit_clock); | ||
499 | |||
500 | static ssize_t store_select_amcb1_transmit_clock(struct device *d, | ||
501 | struct device_attribute *attr, const char *buf, size_t count) | ||
502 | { | ||
503 | unsigned long tmp; | ||
504 | unsigned char val; | ||
505 | unsigned long flags; | ||
506 | |||
507 | sscanf(buf, "%lX", &tmp); | ||
508 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
509 | |||
510 | val = (unsigned char)tmp; | ||
511 | spin_lock_irqsave(&event_lock, flags); | ||
512 | if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { | ||
513 | SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5); | ||
514 | SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); | ||
515 | } else if (val >= CLK_8_592MHz) { | ||
516 | SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); | ||
517 | switch (val) { | ||
518 | case CLK_8_592MHz: | ||
519 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); | ||
520 | break; | ||
521 | case CLK_11_184MHz: | ||
522 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); | ||
523 | break; | ||
524 | case CLK_34_368MHz: | ||
525 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); | ||
526 | break; | ||
527 | case CLK_44_736MHz: | ||
528 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); | ||
529 | break; | ||
530 | } | ||
531 | } else | ||
532 | SET_PORT_BITS(TLCLK_REG3, 0xf8, val); | ||
533 | spin_unlock_irqrestore(&event_lock, flags); | ||
534 | |||
535 | return strnlen(buf, count); | ||
536 | } | ||
537 | |||
538 | static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, | ||
539 | store_select_amcb1_transmit_clock); | ||
540 | |||
541 | static ssize_t store_select_redundant_clock(struct device *d, | ||
542 | struct device_attribute *attr, const char *buf, size_t count) | ||
543 | { | ||
544 | unsigned long tmp; | ||
545 | unsigned char val; | ||
546 | unsigned long flags; | ||
547 | |||
548 | sscanf(buf, "%lX", &tmp); | ||
549 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
550 | |||
551 | val = (unsigned char)tmp; | ||
552 | spin_lock_irqsave(&event_lock, flags); | ||
553 | SET_PORT_BITS(TLCLK_REG1, 0xfe, val); | ||
554 | spin_unlock_irqrestore(&event_lock, flags); | ||
555 | |||
556 | return strnlen(buf, count); | ||
557 | } | ||
558 | |||
559 | static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, | ||
560 | store_select_redundant_clock); | ||
561 | |||
562 | static ssize_t store_select_ref_frequency(struct device *d, | ||
563 | struct device_attribute *attr, const char *buf, size_t count) | ||
564 | { | ||
565 | unsigned long tmp; | ||
566 | unsigned char val; | ||
567 | unsigned long flags; | ||
568 | |||
569 | sscanf(buf, "%lX", &tmp); | ||
570 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
571 | |||
572 | val = (unsigned char)tmp; | ||
573 | spin_lock_irqsave(&event_lock, flags); | ||
574 | SET_PORT_BITS(TLCLK_REG1, 0xfd, val); | ||
575 | spin_unlock_irqrestore(&event_lock, flags); | ||
576 | |||
577 | return strnlen(buf, count); | ||
578 | } | ||
579 | |||
580 | static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, | ||
581 | store_select_ref_frequency); | ||
582 | |||
583 | static ssize_t store_filter_select(struct device *d, | ||
584 | struct device_attribute *attr, const char *buf, size_t count) | ||
585 | { | ||
586 | unsigned long tmp; | ||
587 | unsigned char val; | ||
588 | unsigned long flags; | ||
589 | |||
590 | sscanf(buf, "%lX", &tmp); | ||
591 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
592 | |||
593 | val = (unsigned char)tmp; | ||
594 | spin_lock_irqsave(&event_lock, flags); | ||
595 | SET_PORT_BITS(TLCLK_REG0, 0xfb, val); | ||
596 | spin_unlock_irqrestore(&event_lock, flags); | ||
597 | |||
598 | return strnlen(buf, count); | ||
599 | } | ||
600 | |||
601 | static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); | ||
602 | |||
603 | static ssize_t store_hardware_switching_mode(struct device *d, | ||
604 | struct device_attribute *attr, const char *buf, size_t count) | ||
605 | { | ||
606 | unsigned long tmp; | ||
607 | unsigned char val; | ||
608 | unsigned long flags; | ||
609 | |||
610 | sscanf(buf, "%lX", &tmp); | ||
611 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
612 | |||
613 | val = (unsigned char)tmp; | ||
614 | spin_lock_irqsave(&event_lock, flags); | ||
615 | SET_PORT_BITS(TLCLK_REG0, 0xbf, val); | ||
616 | spin_unlock_irqrestore(&event_lock, flags); | ||
617 | |||
618 | return strnlen(buf, count); | ||
619 | } | ||
620 | |||
621 | static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, | ||
622 | store_hardware_switching_mode); | ||
623 | |||
624 | static ssize_t store_hardware_switching(struct device *d, | ||
625 | struct device_attribute *attr, const char *buf, size_t count) | ||
626 | { | ||
627 | unsigned long tmp; | ||
628 | unsigned char val; | ||
629 | unsigned long flags; | ||
630 | |||
631 | sscanf(buf, "%lX", &tmp); | ||
632 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
633 | |||
634 | val = (unsigned char)tmp; | ||
635 | spin_lock_irqsave(&event_lock, flags); | ||
636 | SET_PORT_BITS(TLCLK_REG0, 0x7f, val); | ||
637 | spin_unlock_irqrestore(&event_lock, flags); | ||
638 | |||
639 | return strnlen(buf, count); | ||
640 | } | ||
641 | |||
642 | static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, | ||
643 | store_hardware_switching); | ||
644 | |||
645 | static ssize_t store_refalign (struct device *d, | ||
646 | struct device_attribute *attr, const char *buf, size_t count) | ||
647 | { | ||
648 | unsigned long tmp; | ||
649 | unsigned long flags; | ||
650 | |||
651 | sscanf(buf, "%lX", &tmp); | ||
652 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
653 | spin_lock_irqsave(&event_lock, flags); | ||
654 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); | ||
655 | udelay(2); | ||
656 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08); | ||
657 | udelay(2); | ||
658 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); | ||
659 | spin_unlock_irqrestore(&event_lock, flags); | ||
660 | |||
661 | return strnlen(buf, count); | ||
662 | } | ||
663 | |||
664 | static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); | ||
665 | |||
666 | static ssize_t store_mode_select (struct device *d, | ||
667 | struct device_attribute *attr, const char *buf, size_t count) | ||
668 | { | ||
669 | unsigned long tmp; | ||
670 | unsigned char val; | ||
671 | unsigned long flags; | ||
672 | |||
673 | sscanf(buf, "%lX", &tmp); | ||
674 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
675 | |||
676 | val = (unsigned char)tmp; | ||
677 | spin_lock_irqsave(&event_lock, flags); | ||
678 | SET_PORT_BITS(TLCLK_REG0, 0xcf, val); | ||
679 | spin_unlock_irqrestore(&event_lock, flags); | ||
680 | |||
681 | return strnlen(buf, count); | ||
682 | } | ||
683 | |||
684 | static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); | ||
685 | |||
686 | static ssize_t store_reset (struct device *d, | ||
687 | struct device_attribute *attr, const char *buf, size_t count) | ||
688 | { | ||
689 | unsigned long tmp; | ||
690 | unsigned char val; | ||
691 | unsigned long flags; | ||
692 | |||
693 | sscanf(buf, "%lX", &tmp); | ||
694 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
695 | |||
696 | val = (unsigned char)tmp; | ||
697 | spin_lock_irqsave(&event_lock, flags); | ||
698 | SET_PORT_BITS(TLCLK_REG4, 0xfd, val); | ||
699 | spin_unlock_irqrestore(&event_lock, flags); | ||
700 | |||
701 | return strnlen(buf, count); | ||
702 | } | ||
703 | |||
704 | static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); | ||
705 | |||
706 | static struct attribute *tlclk_sysfs_entries[] = { | ||
707 | &dev_attr_current_ref.attr, | ||
708 | &dev_attr_interrupt_switch.attr, | ||
709 | &dev_attr_alarms.attr, | ||
710 | &dev_attr_enable_clk3a_output.attr, | ||
711 | &dev_attr_enable_clk3b_output.attr, | ||
712 | &dev_attr_enable_clkb1_output.attr, | ||
713 | &dev_attr_enable_clka1_output.attr, | ||
714 | &dev_attr_enable_clkb0_output.attr, | ||
715 | &dev_attr_enable_clka0_output.attr, | ||
716 | &dev_attr_test_mode.attr, | ||
717 | &dev_attr_select_amcb1_transmit_clock.attr, | ||
718 | &dev_attr_select_amcb2_transmit_clock.attr, | ||
719 | &dev_attr_select_redundant_clock.attr, | ||
720 | &dev_attr_select_ref_frequency.attr, | ||
721 | &dev_attr_filter_select.attr, | ||
722 | &dev_attr_hardware_switching_mode.attr, | ||
723 | &dev_attr_hardware_switching.attr, | ||
724 | &dev_attr_refalign.attr, | ||
725 | &dev_attr_mode_select.attr, | ||
726 | &dev_attr_reset.attr, | ||
727 | NULL | ||
728 | }; | ||
729 | |||
730 | static struct attribute_group tlclk_attribute_group = { | ||
731 | .name = NULL, /* put in device directory */ | ||
732 | .attrs = tlclk_sysfs_entries, | ||
733 | }; | ||
734 | |||
735 | static struct platform_device *tlclk_device; | ||
736 | |||
737 | static int __init tlclk_init(void) | ||
738 | { | ||
739 | int ret; | ||
740 | |||
741 | ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops); | ||
742 | if (ret < 0) { | ||
743 | printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major); | ||
744 | return ret; | ||
745 | } | ||
746 | alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); | ||
747 | if (!alarm_events) | ||
748 | goto out1; | ||
749 | |||
750 | /* Read telecom clock IRQ number (Set by BIOS) */ | ||
751 | if (!request_region(TLCLK_BASE, 8, "telco_clock")) { | ||
752 | printk(KERN_ERR "tlclk: request_region failed! 0x%X\n", | ||
753 | TLCLK_BASE); | ||
754 | ret = -EBUSY; | ||
755 | goto out2; | ||
756 | } | ||
757 | telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); | ||
758 | |||
759 | if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ | ||
760 | printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n", | ||
761 | telclk_interrupt); | ||
762 | ret = -ENXIO; | ||
763 | goto out3; | ||
764 | } | ||
765 | |||
766 | init_timer(&switchover_timer); | ||
767 | |||
768 | ret = misc_register(&tlclk_miscdev); | ||
769 | if (ret < 0) { | ||
770 | printk(KERN_ERR " misc_register retruns %d\n", ret); | ||
771 | ret = -EBUSY; | ||
772 | goto out3; | ||
773 | } | ||
774 | |||
775 | tlclk_device = platform_device_register_simple("telco_clock", | ||
776 | -1, NULL, 0); | ||
777 | if (!tlclk_device) { | ||
778 | printk(KERN_ERR " platform_device_register retruns 0x%X\n", | ||
779 | (unsigned int) tlclk_device); | ||
780 | ret = -EBUSY; | ||
781 | goto out4; | ||
782 | } | ||
783 | |||
784 | ret = sysfs_create_group(&tlclk_device->dev.kobj, | ||
785 | &tlclk_attribute_group); | ||
786 | if (ret) { | ||
787 | printk(KERN_ERR "failed to create sysfs device attributes\n"); | ||
788 | sysfs_remove_group(&tlclk_device->dev.kobj, | ||
789 | &tlclk_attribute_group); | ||
790 | goto out5; | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | out5: | ||
795 | platform_device_unregister(tlclk_device); | ||
796 | out4: | ||
797 | misc_deregister(&tlclk_miscdev); | ||
798 | out3: | ||
799 | release_region(TLCLK_BASE, 8); | ||
800 | out2: | ||
801 | kfree(alarm_events); | ||
802 | out1: | ||
803 | unregister_chrdev(tlclk_major, "telco_clock"); | ||
804 | return ret; | ||
805 | } | ||
806 | |||
807 | static void __exit tlclk_cleanup(void) | ||
808 | { | ||
809 | sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group); | ||
810 | platform_device_unregister(tlclk_device); | ||
811 | misc_deregister(&tlclk_miscdev); | ||
812 | unregister_chrdev(tlclk_major, "telco_clock"); | ||
813 | |||
814 | release_region(TLCLK_BASE, 8); | ||
815 | del_timer_sync(&switchover_timer); | ||
816 | kfree(alarm_events); | ||
817 | |||
818 | } | ||
819 | |||
820 | static void switchover_timeout(unsigned long data) | ||
821 | { | ||
822 | if ((data & 1)) { | ||
823 | if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) | ||
824 | alarm_events->switchover_primary++; | ||
825 | } else { | ||
826 | if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) | ||
827 | alarm_events->switchover_secondary++; | ||
828 | } | ||
829 | |||
830 | /* Alarm processing is done, wake up read task */ | ||
831 | del_timer(&switchover_timer); | ||
832 | got_event = 1; | ||
833 | wake_up(&wq); | ||
834 | } | ||
835 | |||
836 | static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
837 | { | ||
838 | unsigned long flags; | ||
839 | |||
840 | spin_lock_irqsave(&event_lock, flags); | ||
841 | /* Read and clear interrupt events */ | ||
842 | int_events = inb(TLCLK_REG6); | ||
843 | |||
844 | /* Primary_Los changed from 0 to 1 ? */ | ||
845 | if (int_events & PRI_LOS_01_MASK) { | ||
846 | if (inb(TLCLK_REG2) & SEC_LOST_MASK) | ||
847 | alarm_events->lost_clocks++; | ||
848 | else | ||
849 | alarm_events->lost_primary_clock++; | ||
850 | } | ||
851 | |||
852 | /* Primary_Los changed from 1 to 0 ? */ | ||
853 | if (int_events & PRI_LOS_10_MASK) { | ||
854 | alarm_events->primary_clock_back++; | ||
855 | SET_PORT_BITS(TLCLK_REG1, 0xFE, 1); | ||
856 | } | ||
857 | /* Secondary_Los changed from 0 to 1 ? */ | ||
858 | if (int_events & SEC_LOS_01_MASK) { | ||
859 | if (inb(TLCLK_REG2) & PRI_LOST_MASK) | ||
860 | alarm_events->lost_clocks++; | ||
861 | else | ||
862 | alarm_events->lost_secondary_clock++; | ||
863 | } | ||
864 | /* Secondary_Los changed from 1 to 0 ? */ | ||
865 | if (int_events & SEC_LOS_10_MASK) { | ||
866 | alarm_events->secondary_clock_back++; | ||
867 | SET_PORT_BITS(TLCLK_REG1, 0xFE, 0); | ||
868 | } | ||
869 | if (int_events & HOLDOVER_10_MASK) | ||
870 | alarm_events->pll_end_holdover++; | ||
871 | |||
872 | if (int_events & UNLOCK_01_MASK) | ||
873 | alarm_events->pll_lost_sync++; | ||
874 | |||
875 | if (int_events & UNLOCK_10_MASK) | ||
876 | alarm_events->pll_sync++; | ||
877 | |||
878 | /* Holdover changed from 0 to 1 ? */ | ||
879 | if (int_events & HOLDOVER_01_MASK) { | ||
880 | alarm_events->pll_holdover++; | ||
881 | |||
882 | /* TIMEOUT in ~10ms */ | ||
883 | switchover_timer.expires = jiffies + msecs_to_jiffies(10); | ||
884 | switchover_timer.data = inb(TLCLK_REG1); | ||
885 | add_timer(&switchover_timer); | ||
886 | } else { | ||
887 | got_event = 1; | ||
888 | wake_up(&wq); | ||
889 | } | ||
890 | spin_unlock_irqrestore(&event_lock, flags); | ||
891 | |||
892 | return IRQ_HANDLED; | ||
893 | } | ||
894 | |||
895 | module_init(tlclk_init); | ||
896 | module_exit(tlclk_cleanup); | ||
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 049d128ae7f0..303f15880466 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
64 | if (count == 0) | 64 | if (count == 0) |
65 | return -ENODATA; | 65 | return -ENODATA; |
66 | if (count > bufsiz) { | 66 | if (count > bufsiz) { |
67 | dev_err(&chip->pci_dev->dev, | 67 | dev_err(chip->dev, |
68 | "invalid count value %x %zx \n", count, bufsiz); | 68 | "invalid count value %x %zx \n", count, bufsiz); |
69 | return -E2BIG; | 69 | return -E2BIG; |
70 | } | 70 | } |
@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
72 | down(&chip->tpm_mutex); | 72 | down(&chip->tpm_mutex); |
73 | 73 | ||
74 | if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { | 74 | if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { |
75 | dev_err(&chip->pci_dev->dev, | 75 | dev_err(chip->dev, |
76 | "tpm_transmit: tpm_send: error %zd\n", rc); | 76 | "tpm_transmit: tpm_send: error %zd\n", rc); |
77 | goto out; | 77 | goto out; |
78 | } | 78 | } |
79 | 79 | ||
80 | stop = jiffies + 2 * 60 * HZ; | 80 | stop = jiffies + 2 * 60 * HZ; |
81 | do { | 81 | do { |
82 | u8 status = inb(chip->vendor->base + 1); | 82 | u8 status = chip->vendor->status(chip); |
83 | if ((status & chip->vendor->req_complete_mask) == | 83 | if ((status & chip->vendor->req_complete_mask) == |
84 | chip->vendor->req_complete_val) { | 84 | chip->vendor->req_complete_val) { |
85 | goto out_recv; | 85 | goto out_recv; |
86 | } | 86 | } |
87 | 87 | ||
88 | if ((status == chip->vendor->req_canceled)) { | 88 | if ((status == chip->vendor->req_canceled)) { |
89 | dev_err(&chip->pci_dev->dev, "Operation Canceled\n"); | 89 | dev_err(chip->dev, "Operation Canceled\n"); |
90 | rc = -ECANCELED; | 90 | rc = -ECANCELED; |
91 | goto out; | 91 | goto out; |
92 | } | 92 | } |
@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
97 | 97 | ||
98 | 98 | ||
99 | chip->vendor->cancel(chip); | 99 | chip->vendor->cancel(chip); |
100 | dev_err(&chip->pci_dev->dev, "Operation Timed out\n"); | 100 | dev_err(chip->dev, "Operation Timed out\n"); |
101 | rc = -ETIME; | 101 | rc = -ETIME; |
102 | goto out; | 102 | goto out; |
103 | 103 | ||
104 | out_recv: | 104 | out_recv: |
105 | rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); | 105 | rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); |
106 | if (rc < 0) | 106 | if (rc < 0) |
107 | dev_err(&chip->pci_dev->dev, | 107 | dev_err(chip->dev, |
108 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 108 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
109 | out: | 109 | out: |
110 | up(&chip->tpm_mutex); | 110 | up(&chip->tpm_mutex); |
@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
139 | __be32 index; | 139 | __be32 index; |
140 | char *str = buf; | 140 | char *str = buf; |
141 | 141 | ||
142 | struct tpm_chip *chip = | 142 | struct tpm_chip *chip = dev_get_drvdata(dev); |
143 | pci_get_drvdata(to_pci_dev(dev)); | ||
144 | if (chip == NULL) | 143 | if (chip == NULL) |
145 | return -ENODEV; | 144 | return -ENODEV; |
146 | 145 | ||
147 | memcpy(data, cap_pcr, sizeof(cap_pcr)); | 146 | memcpy(data, cap_pcr, sizeof(cap_pcr)); |
148 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 147 | if ((len = tpm_transmit(chip, data, sizeof(data))) |
149 | < CAP_PCR_RESULT_SIZE) { | 148 | < CAP_PCR_RESULT_SIZE) { |
150 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " | 149 | dev_dbg(chip->dev, "A TPM error (%d) occurred " |
151 | "attempting to determine the number of PCRS\n", | 150 | "attempting to determine the number of PCRS\n", |
152 | be32_to_cpu(*((__be32 *) (data + 6)))); | 151 | be32_to_cpu(*((__be32 *) (data + 6)))); |
153 | return 0; | 152 | return 0; |
@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
161 | memcpy(data + 10, &index, 4); | 160 | memcpy(data + 10, &index, 4); |
162 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 161 | if ((len = tpm_transmit(chip, data, sizeof(data))) |
163 | < READ_PCR_RESULT_SIZE){ | 162 | < READ_PCR_RESULT_SIZE){ |
164 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred" | 163 | dev_dbg(chip->dev, "A TPM error (%d) occurred" |
165 | " attempting to read PCR %d of %d\n", | 164 | " attempting to read PCR %d of %d\n", |
166 | be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs); | 165 | be32_to_cpu(*((__be32 *) (data + 6))), |
166 | i, num_pcrs); | ||
167 | goto out; | 167 | goto out; |
168 | } | 168 | } |
169 | str += sprintf(str, "PCR-%02d: ", i); | 169 | str += sprintf(str, "PCR-%02d: ", i); |
@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
191 | int i, rc; | 191 | int i, rc; |
192 | char *str = buf; | 192 | char *str = buf; |
193 | 193 | ||
194 | struct tpm_chip *chip = | 194 | struct tpm_chip *chip = dev_get_drvdata(dev); |
195 | pci_get_drvdata(to_pci_dev(dev)); | ||
196 | if (chip == NULL) | 195 | if (chip == NULL) |
197 | return -ENODEV; | 196 | return -ENODEV; |
198 | 197 | ||
199 | data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); | 198 | data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); |
200 | if (!data) | 199 | if (!data) |
201 | return -ENOMEM; | 200 | return -ENOMEM; |
202 | 201 | ||
203 | memcpy(data, readpubek, sizeof(readpubek)); | 202 | memcpy(data, readpubek, sizeof(readpubek)); |
204 | memset(data + sizeof(readpubek), 0, 20); /* zero nonce */ | ||
205 | 203 | ||
206 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < | 204 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < |
207 | READ_PUBEK_RESULT_SIZE) { | 205 | READ_PUBEK_RESULT_SIZE) { |
208 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " | 206 | dev_dbg(chip->dev, "A TPM error (%d) occurred " |
209 | "attempting to read the PUBEK\n", | 207 | "attempting to read the PUBEK\n", |
210 | be32_to_cpu(*((__be32 *) (data + 6)))); | 208 | be32_to_cpu(*((__be32 *) (data + 6)))); |
211 | rc = 0; | 209 | rc = 0; |
@@ -245,7 +243,6 @@ out: | |||
245 | kfree(data); | 243 | kfree(data); |
246 | return rc; | 244 | return rc; |
247 | } | 245 | } |
248 | |||
249 | EXPORT_SYMBOL_GPL(tpm_show_pubek); | 246 | EXPORT_SYMBOL_GPL(tpm_show_pubek); |
250 | 247 | ||
251 | #define CAP_VER_RESULT_SIZE 18 | 248 | #define CAP_VER_RESULT_SIZE 18 |
@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | |||
274 | ssize_t len; | 271 | ssize_t len; |
275 | char *str = buf; | 272 | char *str = buf; |
276 | 273 | ||
277 | struct tpm_chip *chip = | 274 | struct tpm_chip *chip = dev_get_drvdata(dev); |
278 | pci_get_drvdata(to_pci_dev(dev)); | ||
279 | if (chip == NULL) | 275 | if (chip == NULL) |
280 | return -ENODEV; | 276 | return -ENODEV; |
281 | 277 | ||
@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | |||
315 | } | 311 | } |
316 | EXPORT_SYMBOL_GPL(tpm_store_cancel); | 312 | EXPORT_SYMBOL_GPL(tpm_store_cancel); |
317 | 313 | ||
318 | |||
319 | /* | 314 | /* |
320 | * Device file system interface to the TPM | 315 | * Device file system interface to the TPM |
321 | */ | 316 | */ |
@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct file *file) | |||
339 | } | 334 | } |
340 | 335 | ||
341 | if (chip->num_opens) { | 336 | if (chip->num_opens) { |
342 | dev_dbg(&chip->pci_dev->dev, | 337 | dev_dbg(chip->dev, "Another process owns this TPM\n"); |
343 | "Another process owns this TPM\n"); | ||
344 | rc = -EBUSY; | 338 | rc = -EBUSY; |
345 | goto err_out; | 339 | goto err_out; |
346 | } | 340 | } |
347 | 341 | ||
348 | chip->num_opens++; | 342 | chip->num_opens++; |
349 | pci_dev_get(chip->pci_dev); | 343 | get_device(chip->dev); |
350 | 344 | ||
351 | spin_unlock(&driver_lock); | 345 | spin_unlock(&driver_lock); |
352 | 346 | ||
353 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); | 347 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); |
354 | if (chip->data_buffer == NULL) { | 348 | if (chip->data_buffer == NULL) { |
355 | chip->num_opens--; | 349 | chip->num_opens--; |
356 | pci_dev_put(chip->pci_dev); | 350 | put_device(chip->dev); |
357 | return -ENOMEM; | 351 | return -ENOMEM; |
358 | } | 352 | } |
359 | 353 | ||
@@ -366,7 +360,6 @@ err_out: | |||
366 | spin_unlock(&driver_lock); | 360 | spin_unlock(&driver_lock); |
367 | return rc; | 361 | return rc; |
368 | } | 362 | } |
369 | |||
370 | EXPORT_SYMBOL_GPL(tpm_open); | 363 | EXPORT_SYMBOL_GPL(tpm_open); |
371 | 364 | ||
372 | int tpm_release(struct inode *inode, struct file *file) | 365 | int tpm_release(struct inode *inode, struct file *file) |
@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, struct file *file) | |||
378 | chip->num_opens--; | 371 | chip->num_opens--; |
379 | del_singleshot_timer_sync(&chip->user_read_timer); | 372 | del_singleshot_timer_sync(&chip->user_read_timer); |
380 | atomic_set(&chip->data_pending, 0); | 373 | atomic_set(&chip->data_pending, 0); |
381 | pci_dev_put(chip->pci_dev); | 374 | put_device(chip->dev); |
382 | kfree(chip->data_buffer); | 375 | kfree(chip->data_buffer); |
383 | spin_unlock(&driver_lock); | 376 | spin_unlock(&driver_lock); |
384 | return 0; | 377 | return 0; |
385 | } | 378 | } |
386 | |||
387 | EXPORT_SYMBOL_GPL(tpm_release); | 379 | EXPORT_SYMBOL_GPL(tpm_release); |
388 | 380 | ||
389 | ssize_t tpm_write(struct file * file, const char __user * buf, | 381 | ssize_t tpm_write(struct file *file, const char __user *buf, |
390 | size_t size, loff_t * off) | 382 | size_t size, loff_t * off) |
391 | { | 383 | { |
392 | struct tpm_chip *chip = file->private_data; | 384 | struct tpm_chip *chip = file->private_data; |
@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf, | |||
422 | 414 | ||
423 | EXPORT_SYMBOL_GPL(tpm_write); | 415 | EXPORT_SYMBOL_GPL(tpm_write); |
424 | 416 | ||
425 | ssize_t tpm_read(struct file * file, char __user * buf, | 417 | ssize_t tpm_read(struct file * file, char __user *buf, |
426 | size_t size, loff_t * off) | 418 | size_t size, loff_t * off) |
427 | { | 419 | { |
428 | struct tpm_chip *chip = file->private_data; | 420 | struct tpm_chip *chip = file->private_data; |
@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, char __user * buf, | |||
444 | 436 | ||
445 | return ret_size; | 437 | return ret_size; |
446 | } | 438 | } |
447 | |||
448 | EXPORT_SYMBOL_GPL(tpm_read); | 439 | EXPORT_SYMBOL_GPL(tpm_read); |
449 | 440 | ||
450 | void __devexit tpm_remove(struct pci_dev *pci_dev) | 441 | void tpm_remove_hardware(struct device *dev) |
451 | { | 442 | { |
452 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 443 | struct tpm_chip *chip = dev_get_drvdata(dev); |
453 | 444 | ||
454 | if (chip == NULL) { | 445 | if (chip == NULL) { |
455 | dev_err(&pci_dev->dev, "No device data found\n"); | 446 | dev_err(dev, "No device data found\n"); |
456 | return; | 447 | return; |
457 | } | 448 | } |
458 | 449 | ||
@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) | |||
462 | 453 | ||
463 | spin_unlock(&driver_lock); | 454 | spin_unlock(&driver_lock); |
464 | 455 | ||
465 | pci_set_drvdata(pci_dev, NULL); | 456 | dev_set_drvdata(dev, NULL); |
466 | misc_deregister(&chip->vendor->miscdev); | 457 | misc_deregister(&chip->vendor->miscdev); |
467 | kfree(chip->vendor->miscdev.name); | 458 | kfree(chip->vendor->miscdev.name); |
468 | 459 | ||
469 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 460 | sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); |
470 | 461 | ||
471 | pci_disable_device(pci_dev); | 462 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= |
472 | 463 | !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | |
473 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | ||
474 | 464 | ||
475 | kfree(chip); | 465 | kfree(chip); |
476 | 466 | ||
477 | pci_dev_put(pci_dev); | 467 | put_device(dev); |
478 | } | 468 | } |
479 | 469 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); | |
480 | EXPORT_SYMBOL_GPL(tpm_remove); | ||
481 | 470 | ||
482 | static u8 savestate[] = { | 471 | static u8 savestate[] = { |
483 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 472 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
@@ -489,32 +478,30 @@ static u8 savestate[] = { | |||
489 | * We are about to suspend. Save the TPM state | 478 | * We are about to suspend. Save the TPM state |
490 | * so that it can be restored. | 479 | * so that it can be restored. |
491 | */ | 480 | */ |
492 | int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state) | 481 | int tpm_pm_suspend(struct device *dev, pm_message_t pm_state) |
493 | { | 482 | { |
494 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 483 | struct tpm_chip *chip = dev_get_drvdata(dev); |
495 | if (chip == NULL) | 484 | if (chip == NULL) |
496 | return -ENODEV; | 485 | return -ENODEV; |
497 | 486 | ||
498 | tpm_transmit(chip, savestate, sizeof(savestate)); | 487 | tpm_transmit(chip, savestate, sizeof(savestate)); |
499 | return 0; | 488 | return 0; |
500 | } | 489 | } |
501 | |||
502 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); | 490 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); |
503 | 491 | ||
504 | /* | 492 | /* |
505 | * Resume from a power safe. The BIOS already restored | 493 | * Resume from a power safe. The BIOS already restored |
506 | * the TPM state. | 494 | * the TPM state. |
507 | */ | 495 | */ |
508 | int tpm_pm_resume(struct pci_dev *pci_dev) | 496 | int tpm_pm_resume(struct device *dev) |
509 | { | 497 | { |
510 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 498 | struct tpm_chip *chip = dev_get_drvdata(dev); |
511 | 499 | ||
512 | if (chip == NULL) | 500 | if (chip == NULL) |
513 | return -ENODEV; | 501 | return -ENODEV; |
514 | 502 | ||
515 | return 0; | 503 | return 0; |
516 | } | 504 | } |
517 | |||
518 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 505 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
519 | 506 | ||
520 | /* | 507 | /* |
@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); | |||
524 | * upon errant exit from this function specific probe function should call | 511 | * upon errant exit from this function specific probe function should call |
525 | * pci_disable_device | 512 | * pci_disable_device |
526 | */ | 513 | */ |
527 | int tpm_register_hardware(struct pci_dev *pci_dev, | 514 | int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) |
528 | struct tpm_vendor_specific *entry) | ||
529 | { | 515 | { |
530 | #define DEVNAME_SIZE 7 | 516 | #define DEVNAME_SIZE 7 |
531 | 517 | ||
@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev *pci_dev, | |||
534 | int i, j; | 520 | int i, j; |
535 | 521 | ||
536 | /* Driver specific per-device data */ | 522 | /* Driver specific per-device data */ |
537 | chip = kmalloc(sizeof(*chip), GFP_KERNEL); | 523 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
538 | if (chip == NULL) | 524 | if (chip == NULL) |
539 | return -ENOMEM; | 525 | return -ENOMEM; |
540 | 526 | ||
541 | memset(chip, 0, sizeof(struct tpm_chip)); | ||
542 | |||
543 | init_MUTEX(&chip->buffer_mutex); | 527 | init_MUTEX(&chip->buffer_mutex); |
544 | init_MUTEX(&chip->tpm_mutex); | 528 | init_MUTEX(&chip->tpm_mutex); |
545 | INIT_LIST_HEAD(&chip->list); | 529 | INIT_LIST_HEAD(&chip->list); |
@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev *pci_dev, | |||
563 | 547 | ||
564 | dev_num_search_complete: | 548 | dev_num_search_complete: |
565 | if (chip->dev_num < 0) { | 549 | if (chip->dev_num < 0) { |
566 | dev_err(&pci_dev->dev, | 550 | dev_err(dev, "No available tpm device numbers\n"); |
567 | "No available tpm device numbers\n"); | ||
568 | kfree(chip); | 551 | kfree(chip); |
569 | return -ENODEV; | 552 | return -ENODEV; |
570 | } else if (chip->dev_num == 0) | 553 | } else if (chip->dev_num == 0) |
@@ -576,15 +559,15 @@ dev_num_search_complete: | |||
576 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 559 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
577 | chip->vendor->miscdev.name = devname; | 560 | chip->vendor->miscdev.name = devname; |
578 | 561 | ||
579 | chip->vendor->miscdev.dev = &(pci_dev->dev); | 562 | chip->vendor->miscdev.dev = dev; |
580 | chip->pci_dev = pci_dev_get(pci_dev); | 563 | chip->dev = get_device(dev); |
581 | 564 | ||
582 | if (misc_register(&chip->vendor->miscdev)) { | 565 | if (misc_register(&chip->vendor->miscdev)) { |
583 | dev_err(&chip->pci_dev->dev, | 566 | dev_err(chip->dev, |
584 | "unable to misc_register %s, minor %d\n", | 567 | "unable to misc_register %s, minor %d\n", |
585 | chip->vendor->miscdev.name, | 568 | chip->vendor->miscdev.name, |
586 | chip->vendor->miscdev.minor); | 569 | chip->vendor->miscdev.minor); |
587 | pci_dev_put(pci_dev); | 570 | put_device(dev); |
588 | kfree(chip); | 571 | kfree(chip); |
589 | dev_mask[i] &= !(1 << j); | 572 | dev_mask[i] &= !(1 << j); |
590 | return -ENODEV; | 573 | return -ENODEV; |
@@ -592,17 +575,16 @@ dev_num_search_complete: | |||
592 | 575 | ||
593 | spin_lock(&driver_lock); | 576 | spin_lock(&driver_lock); |
594 | 577 | ||
595 | pci_set_drvdata(pci_dev, chip); | 578 | dev_set_drvdata(dev, chip); |
596 | 579 | ||
597 | list_add(&chip->list, &tpm_chip_list); | 580 | list_add(&chip->list, &tpm_chip_list); |
598 | 581 | ||
599 | spin_unlock(&driver_lock); | 582 | spin_unlock(&driver_lock); |
600 | 583 | ||
601 | sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 584 | sysfs_create_group(&dev->kobj, chip->vendor->attr_group); |
602 | 585 | ||
603 | return 0; | 586 | return 0; |
604 | } | 587 | } |
605 | |||
606 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 588 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
607 | 589 | ||
608 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); | 590 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 373b41f6b460..024814b50c3c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -55,12 +55,13 @@ struct tpm_vendor_specific { | |||
55 | int (*recv) (struct tpm_chip *, u8 *, size_t); | 55 | int (*recv) (struct tpm_chip *, u8 *, size_t); |
56 | int (*send) (struct tpm_chip *, u8 *, size_t); | 56 | int (*send) (struct tpm_chip *, u8 *, size_t); |
57 | void (*cancel) (struct tpm_chip *); | 57 | void (*cancel) (struct tpm_chip *); |
58 | u8 (*status) (struct tpm_chip *); | ||
58 | struct miscdevice miscdev; | 59 | struct miscdevice miscdev; |
59 | struct attribute_group *attr_group; | 60 | struct attribute_group *attr_group; |
60 | }; | 61 | }; |
61 | 62 | ||
62 | struct tpm_chip { | 63 | struct tpm_chip { |
63 | struct pci_dev *pci_dev; /* PCI device stuff */ | 64 | struct device *dev; /* Device stuff */ |
64 | 65 | ||
65 | int dev_num; /* /dev/tpm# */ | 66 | int dev_num; /* /dev/tpm# */ |
66 | int num_opens; /* only one allowed */ | 67 | int num_opens; /* only one allowed */ |
@@ -91,13 +92,13 @@ static inline void tpm_write_index(int base, int index, int value) | |||
91 | outb(value & 0xFF, base+1); | 92 | outb(value & 0xFF, base+1); |
92 | } | 93 | } |
93 | 94 | ||
94 | extern int tpm_register_hardware(struct pci_dev *, | 95 | extern int tpm_register_hardware(struct device *, |
95 | struct tpm_vendor_specific *); | 96 | struct tpm_vendor_specific *); |
96 | extern int tpm_open(struct inode *, struct file *); | 97 | extern int tpm_open(struct inode *, struct file *); |
97 | extern int tpm_release(struct inode *, struct file *); | 98 | extern int tpm_release(struct inode *, struct file *); |
98 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 99 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, |
99 | loff_t *); | 100 | loff_t *); |
100 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | 101 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); |
101 | extern void __devexit tpm_remove(struct pci_dev *); | 102 | extern void tpm_remove_hardware(struct device *); |
102 | extern int tpm_pm_suspend(struct pci_dev *, pm_message_t); | 103 | extern int tpm_pm_suspend(struct device *, pm_message_t); |
103 | extern int tpm_pm_resume(struct pci_dev *); | 104 | extern int tpm_pm_resume(struct device *); |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index c0d64914595f..8cb42e84723c 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -40,7 +40,7 @@ enum tpm_atmel_read_status { | |||
40 | ATML_STATUS_READY = 0x08 | 40 | ATML_STATUS_READY = 0x08 |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | 43 | static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) |
44 | { | 44 | { |
45 | u8 status, *hdr = buf; | 45 | u8 status, *hdr = buf; |
46 | u32 size; | 46 | u32 size; |
@@ -54,7 +54,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
54 | for (i = 0; i < 6; i++) { | 54 | for (i = 0; i < 6; i++) { |
55 | status = inb(chip->vendor->base + 1); | 55 | status = inb(chip->vendor->base + 1); |
56 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 56 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
57 | dev_err(&chip->pci_dev->dev, | 57 | dev_err(chip->dev, |
58 | "error reading header\n"); | 58 | "error reading header\n"); |
59 | return -EIO; | 59 | return -EIO; |
60 | } | 60 | } |
@@ -66,12 +66,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
66 | size = be32_to_cpu(*native_size); | 66 | size = be32_to_cpu(*native_size); |
67 | 67 | ||
68 | if (count < size) { | 68 | if (count < size) { |
69 | dev_err(&chip->pci_dev->dev, | 69 | dev_err(chip->dev, |
70 | "Recv size(%d) less than available space\n", size); | 70 | "Recv size(%d) less than available space\n", size); |
71 | for (; i < size; i++) { /* clear the waiting data anyway */ | 71 | for (; i < size; i++) { /* clear the waiting data anyway */ |
72 | status = inb(chip->vendor->base + 1); | 72 | status = inb(chip->vendor->base + 1); |
73 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 73 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
74 | dev_err(&chip->pci_dev->dev, | 74 | dev_err(chip->dev, |
75 | "error reading data\n"); | 75 | "error reading data\n"); |
76 | return -EIO; | 76 | return -EIO; |
77 | } | 77 | } |
@@ -83,7 +83,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
83 | for (; i < size; i++) { | 83 | for (; i < size; i++) { |
84 | status = inb(chip->vendor->base + 1); | 84 | status = inb(chip->vendor->base + 1); |
85 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 85 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
86 | dev_err(&chip->pci_dev->dev, | 86 | dev_err(chip->dev, |
87 | "error reading data\n"); | 87 | "error reading data\n"); |
88 | return -EIO; | 88 | return -EIO; |
89 | } | 89 | } |
@@ -93,20 +93,20 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
93 | /* make sure data available is gone */ | 93 | /* make sure data available is gone */ |
94 | status = inb(chip->vendor->base + 1); | 94 | status = inb(chip->vendor->base + 1); |
95 | if (status & ATML_STATUS_DATA_AVAIL) { | 95 | if (status & ATML_STATUS_DATA_AVAIL) { |
96 | dev_err(&chip->pci_dev->dev, "data available is stuck\n"); | 96 | dev_err(chip->dev, "data available is stuck\n"); |
97 | return -EIO; | 97 | return -EIO; |
98 | } | 98 | } |
99 | 99 | ||
100 | return size; | 100 | return size; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count) | 103 | static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) |
104 | { | 104 | { |
105 | int i; | 105 | int i; |
106 | 106 | ||
107 | dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: "); | 107 | dev_dbg(chip->dev, "tpm_atml_send:\n"); |
108 | for (i = 0; i < count; i++) { | 108 | for (i = 0; i < count; i++) { |
109 | dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]); | 109 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); |
110 | outb(buf[i], chip->vendor->base); | 110 | outb(buf[i], chip->vendor->base); |
111 | } | 111 | } |
112 | 112 | ||
@@ -118,6 +118,11 @@ static void tpm_atml_cancel(struct tpm_chip *chip) | |||
118 | outb(ATML_STATUS_ABORT, chip->vendor->base + 1); | 118 | outb(ATML_STATUS_ABORT, chip->vendor->base + 1); |
119 | } | 119 | } |
120 | 120 | ||
121 | static u8 tpm_atml_status(struct tpm_chip *chip) | ||
122 | { | ||
123 | return inb(chip->vendor->base + 1); | ||
124 | } | ||
125 | |||
121 | static struct file_operations atmel_ops = { | 126 | static struct file_operations atmel_ops = { |
122 | .owner = THIS_MODULE, | 127 | .owner = THIS_MODULE, |
123 | .llseek = no_llseek, | 128 | .llseek = no_llseek, |
@@ -137,7 +142,7 @@ static struct attribute* atmel_attrs[] = { | |||
137 | &dev_attr_pcrs.attr, | 142 | &dev_attr_pcrs.attr, |
138 | &dev_attr_caps.attr, | 143 | &dev_attr_caps.attr, |
139 | &dev_attr_cancel.attr, | 144 | &dev_attr_cancel.attr, |
140 | 0, | 145 | NULL, |
141 | }; | 146 | }; |
142 | 147 | ||
143 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; | 148 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; |
@@ -146,6 +151,7 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
146 | .recv = tpm_atml_recv, | 151 | .recv = tpm_atml_recv, |
147 | .send = tpm_atml_send, | 152 | .send = tpm_atml_send, |
148 | .cancel = tpm_atml_cancel, | 153 | .cancel = tpm_atml_cancel, |
154 | .status = tpm_atml_status, | ||
149 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, | 155 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, |
150 | .req_complete_val = ATML_STATUS_DATA_AVAIL, | 156 | .req_complete_val = ATML_STATUS_DATA_AVAIL, |
151 | .req_canceled = ATML_STATUS_READY, | 157 | .req_canceled = ATML_STATUS_READY, |
@@ -153,86 +159,94 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
153 | .miscdev = { .fops = &atmel_ops, }, | 159 | .miscdev = { .fops = &atmel_ops, }, |
154 | }; | 160 | }; |
155 | 161 | ||
156 | static int __devinit tpm_atml_init(struct pci_dev *pci_dev, | 162 | static struct platform_device *pdev; |
157 | const struct pci_device_id *pci_id) | 163 | |
164 | static void __devexit tpm_atml_remove(struct device *dev) | ||
165 | { | ||
166 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
167 | if (chip) { | ||
168 | release_region(chip->vendor->base, 2); | ||
169 | tpm_remove_hardware(chip->dev); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static struct device_driver atml_drv = { | ||
174 | .name = "tpm_atmel", | ||
175 | .bus = &platform_bus_type, | ||
176 | .owner = THIS_MODULE, | ||
177 | .suspend = tpm_pm_suspend, | ||
178 | .resume = tpm_pm_resume, | ||
179 | }; | ||
180 | |||
181 | static int __init init_atmel(void) | ||
158 | { | 182 | { |
159 | u8 version[4]; | ||
160 | int rc = 0; | 183 | int rc = 0; |
161 | int lo, hi; | 184 | int lo, hi; |
162 | 185 | ||
163 | if (pci_enable_device(pci_dev)) | 186 | driver_register(&atml_drv); |
164 | return -EIO; | ||
165 | 187 | ||
166 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | 188 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); |
167 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | 189 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); |
168 | 190 | ||
169 | tpm_atmel.base = (hi<<8)|lo; | 191 | tpm_atmel.base = (hi<<8)|lo; |
170 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); | ||
171 | 192 | ||
172 | /* verify that it is an Atmel part */ | 193 | /* verify that it is an Atmel part */ |
173 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' | 194 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' |
174 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { | 195 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { |
175 | rc = -ENODEV; | 196 | return -ENODEV; |
176 | goto out_err; | ||
177 | } | 197 | } |
178 | 198 | ||
179 | /* query chip for its version number */ | 199 | /* verify chip version number is 1.1 */ |
180 | if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) { | 200 | if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || |
181 | version[1] = tpm_read_index(TPM_ADDR, 0x01); | 201 | (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) |
182 | version[2] = tpm_read_index(TPM_ADDR, 0x02); | 202 | return -ENODEV; |
183 | version[3] = tpm_read_index(TPM_ADDR, 0x03); | 203 | |
184 | } else { | 204 | pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); |
185 | dev_info(&pci_dev->dev, "version query failed\n"); | 205 | if ( !pdev ) |
186 | rc = -ENODEV; | 206 | return -ENOMEM; |
187 | goto out_err; | 207 | |
208 | pdev->name = "tpm_atmel0"; | ||
209 | pdev->id = -1; | ||
210 | pdev->num_resources = 0; | ||
211 | pdev->dev.release = tpm_atml_remove; | ||
212 | pdev->dev.driver = &atml_drv; | ||
213 | |||
214 | if ((rc = platform_device_register(pdev)) < 0) { | ||
215 | kfree(pdev); | ||
216 | pdev = NULL; | ||
217 | return rc; | ||
188 | } | 218 | } |
189 | 219 | ||
190 | if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0) | 220 | if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { |
191 | goto out_err; | 221 | platform_device_unregister(pdev); |
222 | kfree(pdev); | ||
223 | pdev = NULL; | ||
224 | return -EBUSY; | ||
225 | } | ||
192 | 226 | ||
193 | dev_info(&pci_dev->dev, | 227 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { |
194 | "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1], | 228 | release_region(tpm_atmel.base, 2); |
195 | version[2], version[3]); | 229 | platform_device_unregister(pdev); |
230 | kfree(pdev); | ||
231 | pdev = NULL; | ||
232 | return rc; | ||
233 | } | ||
196 | 234 | ||
235 | dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n", | ||
236 | tpm_atmel.base); | ||
197 | return 0; | 237 | return 0; |
198 | out_err: | ||
199 | pci_disable_device(pci_dev); | ||
200 | return rc; | ||
201 | } | ||
202 | |||
203 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
204 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
205 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
206 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
207 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
208 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
209 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
210 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
211 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
212 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
213 | {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)}, | ||
214 | {0,} | ||
215 | }; | ||
216 | |||
217 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | ||
218 | |||
219 | static struct pci_driver atmel_pci_driver = { | ||
220 | .name = "tpm_atmel", | ||
221 | .id_table = tpm_pci_tbl, | ||
222 | .probe = tpm_atml_init, | ||
223 | .remove = __devexit_p(tpm_remove), | ||
224 | .suspend = tpm_pm_suspend, | ||
225 | .resume = tpm_pm_resume, | ||
226 | }; | ||
227 | |||
228 | static int __init init_atmel(void) | ||
229 | { | ||
230 | return pci_register_driver(&atmel_pci_driver); | ||
231 | } | 238 | } |
232 | 239 | ||
233 | static void __exit cleanup_atmel(void) | 240 | static void __exit cleanup_atmel(void) |
234 | { | 241 | { |
235 | pci_unregister_driver(&atmel_pci_driver); | 242 | if (pdev) { |
243 | tpm_atml_remove(&pdev->dev); | ||
244 | platform_device_unregister(pdev); | ||
245 | kfree(pdev); | ||
246 | pdev = NULL; | ||
247 | } | ||
248 | |||
249 | driver_unregister(&atml_drv); | ||
236 | } | 250 | } |
237 | 251 | ||
238 | module_init(init_atmel); | 252 | module_init(init_atmel); |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 939e51e119e6..8198dbb7370f 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Specifications at www.trustedcomputinggroup.org | 5 | * Specifications at www.trustedcomputinggroup.org |
6 | * | 6 | * |
7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> | 7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> |
8 | * Sirrix AG - security technologies, http://www.sirrix.com and | ||
8 | * Applied Data Security Group, Ruhr-University Bochum, Germany | 9 | * Applied Data Security Group, Ruhr-University Bochum, Germany |
9 | * Project-Homepage: http://www.prosec.rub.de/tpm | 10 | * Project-Homepage: http://www.prosec.rub.de/tpm |
10 | * | 11 | * |
@@ -29,9 +30,10 @@ | |||
29 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 | 30 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
30 | 31 | ||
31 | /* These values will be filled after PnP-call */ | 32 | /* These values will be filled after PnP-call */ |
32 | static int TPM_INF_DATA = 0; | 33 | static int TPM_INF_DATA; |
33 | static int TPM_INF_ADDR = 0; | 34 | static int TPM_INF_ADDR; |
34 | static int pnp_registered = 0; | 35 | static int TPM_INF_BASE; |
36 | static int TPM_INF_PORT_LEN; | ||
35 | 37 | ||
36 | /* TPM header definitions */ | 38 | /* TPM header definitions */ |
37 | enum infineon_tpm_header { | 39 | enum infineon_tpm_header { |
@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
143 | } | 145 | } |
144 | if (i == TPM_MAX_TRIES) { /* timeout occurs */ | 146 | if (i == TPM_MAX_TRIES) { /* timeout occurs */ |
145 | if (wait_for_bit == STAT_XFE) | 147 | if (wait_for_bit == STAT_XFE) |
146 | dev_err(&chip->pci_dev->dev, | 148 | dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n"); |
147 | "Timeout in wait(STAT_XFE)\n"); | ||
148 | if (wait_for_bit == STAT_RDA) | 149 | if (wait_for_bit == STAT_RDA) |
149 | dev_err(&chip->pci_dev->dev, | 150 | dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n"); |
150 | "Timeout in wait(STAT_RDA)\n"); | ||
151 | return -EIO; | 151 | return -EIO; |
152 | } | 152 | } |
153 | return 0; | 153 | return 0; |
@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | |||
170 | static void tpm_wtx(struct tpm_chip *chip) | 170 | static void tpm_wtx(struct tpm_chip *chip) |
171 | { | 171 | { |
172 | number_of_wtx++; | 172 | number_of_wtx++; |
173 | dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n", | 173 | dev_info(chip->dev, "Granting WTX (%02d / %02d)\n", |
174 | number_of_wtx, TPM_MAX_WTX_PACKAGES); | 174 | number_of_wtx, TPM_MAX_WTX_PACKAGES); |
175 | wait_and_send(chip, TPM_VL_VER); | 175 | wait_and_send(chip, TPM_VL_VER); |
176 | wait_and_send(chip, TPM_CTRL_WTX); | 176 | wait_and_send(chip, TPM_CTRL_WTX); |
@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chip) | |||
181 | 181 | ||
182 | static void tpm_wtx_abort(struct tpm_chip *chip) | 182 | static void tpm_wtx_abort(struct tpm_chip *chip) |
183 | { | 183 | { |
184 | dev_info(&chip->pci_dev->dev, "Aborting WTX\n"); | 184 | dev_info(chip->dev, "Aborting WTX\n"); |
185 | wait_and_send(chip, TPM_VL_VER); | 185 | wait_and_send(chip, TPM_VL_VER); |
186 | wait_and_send(chip, TPM_CTRL_WTX_ABORT); | 186 | wait_and_send(chip, TPM_CTRL_WTX_ABORT); |
187 | wait_and_send(chip, 0x00); | 187 | wait_and_send(chip, 0x00); |
@@ -206,7 +206,7 @@ recv_begin: | |||
206 | } | 206 | } |
207 | 207 | ||
208 | if (buf[0] != TPM_VL_VER) { | 208 | if (buf[0] != TPM_VL_VER) { |
209 | dev_err(&chip->pci_dev->dev, | 209 | dev_err(chip->dev, |
210 | "Wrong transport protocol implementation!\n"); | 210 | "Wrong transport protocol implementation!\n"); |
211 | return -EIO; | 211 | return -EIO; |
212 | } | 212 | } |
@@ -221,8 +221,7 @@ recv_begin: | |||
221 | } | 221 | } |
222 | 222 | ||
223 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 223 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
224 | dev_err(&chip->pci_dev->dev, | 224 | dev_err(chip->dev, "Error handling on vendor layer!\n"); |
225 | "Error handling on vendor layer!\n"); | ||
226 | return -EIO; | 225 | return -EIO; |
227 | } | 226 | } |
228 | 227 | ||
@@ -234,7 +233,7 @@ recv_begin: | |||
234 | } | 233 | } |
235 | 234 | ||
236 | if (buf[1] == TPM_CTRL_WTX) { | 235 | if (buf[1] == TPM_CTRL_WTX) { |
237 | dev_info(&chip->pci_dev->dev, "WTX-package received\n"); | 236 | dev_info(chip->dev, "WTX-package received\n"); |
238 | if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { | 237 | if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { |
239 | tpm_wtx(chip); | 238 | tpm_wtx(chip); |
240 | goto recv_begin; | 239 | goto recv_begin; |
@@ -245,14 +244,14 @@ recv_begin: | |||
245 | } | 244 | } |
246 | 245 | ||
247 | if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { | 246 | if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { |
248 | dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n"); | 247 | dev_info(chip->dev, "WTX-abort acknowledged\n"); |
249 | return size; | 248 | return size; |
250 | } | 249 | } |
251 | 250 | ||
252 | if (buf[1] == TPM_CTRL_ERROR) { | 251 | if (buf[1] == TPM_CTRL_ERROR) { |
253 | dev_err(&chip->pci_dev->dev, "ERROR-package received:\n"); | 252 | dev_err(chip->dev, "ERROR-package received:\n"); |
254 | if (buf[4] == TPM_INF_NAK) | 253 | if (buf[4] == TPM_INF_NAK) |
255 | dev_err(&chip->pci_dev->dev, | 254 | dev_err(chip->dev, |
256 | "-> Negative acknowledgement" | 255 | "-> Negative acknowledgement" |
257 | " - retransmit command!\n"); | 256 | " - retransmit command!\n"); |
258 | return -EIO; | 257 | return -EIO; |
@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
271 | 270 | ||
272 | ret = empty_fifo(chip, 1); | 271 | ret = empty_fifo(chip, 1); |
273 | if (ret) { | 272 | if (ret) { |
274 | dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n"); | 273 | dev_err(chip->dev, "Timeout while clearing FIFO\n"); |
275 | return -EIO; | 274 | return -EIO; |
276 | } | 275 | } |
277 | 276 | ||
@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
316 | */ | 315 | */ |
317 | } | 316 | } |
318 | 317 | ||
318 | static u8 tpm_inf_status(struct tpm_chip *chip) | ||
319 | { | ||
320 | return inb(chip->vendor->base + STAT); | ||
321 | } | ||
322 | |||
319 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 323 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
320 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | 324 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); |
321 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | 325 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_inf = { | |||
344 | .recv = tpm_inf_recv, | 348 | .recv = tpm_inf_recv, |
345 | .send = tpm_inf_send, | 349 | .send = tpm_inf_send, |
346 | .cancel = tpm_inf_cancel, | 350 | .cancel = tpm_inf_cancel, |
351 | .status = tpm_inf_status, | ||
347 | .req_complete_mask = 0, | 352 | .req_complete_mask = 0, |
348 | .req_complete_val = 0, | 353 | .req_complete_val = 0, |
349 | .attr_group = &inf_attr_grp, | 354 | .attr_group = &inf_attr_grp, |
@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pnp_tbl[] = { | |||
356 | {"IFX0102", 0}, | 361 | {"IFX0102", 0}, |
357 | {"", 0} | 362 | {"", 0} |
358 | }; | 363 | }; |
364 | |||
359 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | 365 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); |
360 | 366 | ||
361 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | 367 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, |
362 | const struct pnp_device_id *dev_id) | 368 | const struct pnp_device_id *dev_id) |
363 | { | ||
364 | if (pnp_port_valid(dev, 0)) { | ||
365 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); | ||
366 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); | ||
367 | tpm_inf.base = pnp_port_start(dev, 1); | ||
368 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
369 | dev->name, dev_id->id); | ||
370 | return 0; | ||
371 | } | ||
372 | return -ENODEV; | ||
373 | } | ||
374 | |||
375 | static struct pnp_driver tpm_inf_pnp = { | ||
376 | .name = "tpm_inf_pnp", | ||
377 | .id_table = tpm_pnp_tbl, | ||
378 | .probe = tpm_inf_pnp_probe, | ||
379 | }; | ||
380 | |||
381 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | ||
382 | const struct pci_device_id *pci_id) | ||
383 | { | 369 | { |
384 | int rc = 0; | 370 | int rc = 0; |
385 | u8 iol, ioh; | 371 | u8 iol, ioh; |
@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
388 | int productid[2]; | 374 | int productid[2]; |
389 | char chipname[20]; | 375 | char chipname[20]; |
390 | 376 | ||
391 | rc = pci_enable_device(pci_dev); | 377 | /* read IO-ports through PnP */ |
392 | if (rc) | 378 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
393 | return rc; | 379 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
394 | 380 | TPM_INF_ADDR = pnp_port_start(dev, 0); | |
395 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); | 381 | TPM_INF_DATA = (TPM_INF_ADDR + 1); |
396 | 382 | TPM_INF_BASE = pnp_port_start(dev, 1); | |
397 | /* read IO-ports from PnP */ | 383 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); |
398 | rc = pnp_register_driver(&tpm_inf_pnp); | 384 | if (!TPM_INF_PORT_LEN) |
399 | if (rc < 0) { | 385 | return -EINVAL; |
400 | dev_err(&pci_dev->dev, | 386 | dev_info(&dev->dev, "Found %s with ID %s\n", |
401 | "Error %x from pnp_register_driver!\n",rc); | 387 | dev->name, dev_id->id); |
402 | goto error2; | 388 | if (!((TPM_INF_BASE >> 8) & 0xff)) |
403 | } | 389 | return -EINVAL; |
404 | if (!rc) { | 390 | /* publish my base address and request region */ |
405 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | 391 | tpm_inf.base = TPM_INF_BASE; |
406 | goto error; | 392 | if (request_region |
393 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | ||
394 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | ||
395 | return -EINVAL; | ||
396 | } | ||
407 | } else { | 397 | } else { |
408 | pnp_registered = 1; | 398 | return -EINVAL; |
409 | } | ||
410 | |||
411 | /* Make sure, we have received valid config ports */ | ||
412 | if (!TPM_INF_ADDR) { | ||
413 | dev_err(&pci_dev->dev, "No valid IO-ports received!\n"); | ||
414 | goto error; | ||
415 | } | 399 | } |
416 | 400 | ||
417 | /* query chip for its vendor, its version number a.s.o. */ | 401 | /* query chip for its vendor, its version number a.s.o. */ |
@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
443 | 427 | ||
444 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | 428 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { |
445 | 429 | ||
446 | if (tpm_inf.base == 0) { | ||
447 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); | ||
448 | goto error; | ||
449 | } | ||
450 | /* configure TPM with IO-ports */ | 430 | /* configure TPM with IO-ports */ |
451 | outb(IOLIMH, TPM_INF_ADDR); | 431 | outb(IOLIMH, TPM_INF_ADDR); |
452 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | 432 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); |
@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
460 | iol = inb(TPM_INF_DATA); | 440 | iol = inb(TPM_INF_DATA); |
461 | 441 | ||
462 | if ((ioh << 8 | iol) != tpm_inf.base) { | 442 | if ((ioh << 8 | iol) != tpm_inf.base) { |
463 | dev_err(&pci_dev->dev, | 443 | dev_err(&dev->dev, |
464 | "Could not set IO-ports to %04x\n", | 444 | "Could not set IO-ports to %04x\n", |
465 | tpm_inf.base); | 445 | tpm_inf.base); |
466 | goto error; | 446 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); |
447 | return -EIO; | ||
467 | } | 448 | } |
468 | 449 | ||
469 | /* activate register */ | 450 | /* activate register */ |
@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
475 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 456 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); |
476 | 457 | ||
477 | /* Finally, we're done, print some infos */ | 458 | /* Finally, we're done, print some infos */ |
478 | dev_info(&pci_dev->dev, "TPM found: " | 459 | dev_info(&dev->dev, "TPM found: " |
479 | "config base 0x%x, " | 460 | "config base 0x%x, " |
480 | "io base 0x%x, " | 461 | "io base 0x%x, " |
481 | "chip version %02x%02x, " | 462 | "chip version %02x%02x, " |
@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
483 | "product id %02x%02x" | 464 | "product id %02x%02x" |
484 | "%s\n", | 465 | "%s\n", |
485 | TPM_INF_ADDR, | 466 | TPM_INF_ADDR, |
486 | tpm_inf.base, | 467 | TPM_INF_BASE, |
487 | version[0], version[1], | 468 | version[0], version[1], |
488 | vendorid[0], vendorid[1], | 469 | vendorid[0], vendorid[1], |
489 | productid[0], productid[1], chipname); | 470 | productid[0], productid[1], chipname); |
490 | 471 | ||
491 | rc = tpm_register_hardware(pci_dev, &tpm_inf); | 472 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); |
492 | if (rc < 0) | 473 | if (rc < 0) { |
493 | goto error; | 474 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); |
475 | return -ENODEV; | ||
476 | } | ||
494 | return 0; | 477 | return 0; |
495 | } else { | 478 | } else { |
496 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | 479 | dev_info(&dev->dev, "No Infineon TPM found!\n"); |
497 | error: | ||
498 | pnp_unregister_driver(&tpm_inf_pnp); | ||
499 | error2: | ||
500 | pci_disable_device(pci_dev); | ||
501 | pnp_registered = 0; | ||
502 | return -ENODEV; | 480 | return -ENODEV; |
503 | } | 481 | } |
504 | } | 482 | } |
505 | 483 | ||
506 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | 484 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) |
507 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | 485 | { |
508 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | 486 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
509 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
510 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
511 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
512 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
513 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
514 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)}, | ||
515 | {0,} | ||
516 | }; | ||
517 | 487 | ||
518 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | 488 | if (chip) { |
489 | release_region(chip->vendor->base, TPM_INF_PORT_LEN); | ||
490 | tpm_remove_hardware(chip->dev); | ||
491 | } | ||
492 | } | ||
519 | 493 | ||
520 | static struct pci_driver inf_pci_driver = { | 494 | static struct pnp_driver tpm_inf_pnp = { |
521 | .name = "tpm_inf", | 495 | .name = "tpm_inf_pnp", |
522 | .id_table = tpm_pci_tbl, | 496 | .driver = { |
523 | .probe = tpm_inf_probe, | 497 | .owner = THIS_MODULE, |
524 | .remove = __devexit_p(tpm_remove), | 498 | .suspend = tpm_pm_suspend, |
525 | .suspend = tpm_pm_suspend, | 499 | .resume = tpm_pm_resume, |
526 | .resume = tpm_pm_resume, | 500 | }, |
501 | .id_table = tpm_pnp_tbl, | ||
502 | .probe = tpm_inf_pnp_probe, | ||
503 | .remove = tpm_inf_pnp_remove, | ||
527 | }; | 504 | }; |
528 | 505 | ||
529 | static int __init init_inf(void) | 506 | static int __init init_inf(void) |
530 | { | 507 | { |
531 | return pci_register_driver(&inf_pci_driver); | 508 | return pnp_register_driver(&tpm_inf_pnp); |
532 | } | 509 | } |
533 | 510 | ||
534 | static void __exit cleanup_inf(void) | 511 | static void __exit cleanup_inf(void) |
535 | { | 512 | { |
536 | if (pnp_registered) | 513 | pnp_unregister_driver(&tpm_inf_pnp); |
537 | pnp_unregister_driver(&tpm_inf_pnp); | ||
538 | pci_unregister_driver(&inf_pci_driver); | ||
539 | } | 514 | } |
540 | 515 | ||
541 | module_init(init_inf); | 516 | module_init(init_inf); |
@@ -543,5 +518,5 @@ module_exit(cleanup_inf); | |||
543 | 518 | ||
544 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 519 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
545 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 520 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
546 | MODULE_VERSION("1.5"); | 521 | MODULE_VERSION("1.6"); |
547 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index b4127348c063..253871b5b1e2 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -111,7 +111,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
111 | } | 111 | } |
112 | while (time_before(jiffies, stop)); | 112 | while (time_before(jiffies, stop)); |
113 | 113 | ||
114 | dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); | 114 | dev_info(chip->dev, "wait for ready failed\n"); |
115 | return -EBUSY; | 115 | return -EBUSY; |
116 | } | 116 | } |
117 | 117 | ||
@@ -127,12 +127,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
127 | return -EIO; | 127 | return -EIO; |
128 | 128 | ||
129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { | 129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { |
130 | dev_err(&chip->pci_dev->dev, "F0 timeout\n"); | 130 | dev_err(chip->dev, "F0 timeout\n"); |
131 | return -EIO; | 131 | return -EIO; |
132 | } | 132 | } |
133 | if ((data = | 133 | if ((data = |
134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { | 134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { |
135 | dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n", | 135 | dev_err(chip->dev, "not in normal mode (0x%x)\n", |
136 | data); | 136 | data); |
137 | return -EIO; | 137 | return -EIO; |
138 | } | 138 | } |
@@ -141,7 +141,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
141 | for (p = buffer; p < &buffer[count]; p++) { | 141 | for (p = buffer; p < &buffer[count]; p++) { |
142 | if (wait_for_stat | 142 | if (wait_for_stat |
143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { | 143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { |
144 | dev_err(&chip->pci_dev->dev, | 144 | dev_err(chip->dev, |
145 | "OBF timeout (while reading data)\n"); | 145 | "OBF timeout (while reading data)\n"); |
146 | return -EIO; | 146 | return -EIO; |
147 | } | 147 | } |
@@ -152,11 +152,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
152 | 152 | ||
153 | if ((data & NSC_STATUS_F0) == 0 && | 153 | if ((data & NSC_STATUS_F0) == 0 && |
154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { | 154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { |
155 | dev_err(&chip->pci_dev->dev, "F0 not set\n"); | 155 | dev_err(chip->dev, "F0 not set\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { | 158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { |
159 | dev_err(&chip->pci_dev->dev, | 159 | dev_err(chip->dev, |
160 | "expected end of command(0x%x)\n", data); | 160 | "expected end of command(0x%x)\n", data); |
161 | return -EIO; | 161 | return -EIO; |
162 | } | 162 | } |
@@ -187,19 +187,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
187 | return -EIO; | 187 | return -EIO; |
188 | 188 | ||
189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
190 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 190 | dev_err(chip->dev, "IBF timeout\n"); |
191 | return -EIO; | 191 | return -EIO; |
192 | } | 192 | } |
193 | 193 | ||
194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); | 194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); |
195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { | 195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { |
196 | dev_err(&chip->pci_dev->dev, "IBR timeout\n"); | 196 | dev_err(chip->dev, "IBR timeout\n"); |
197 | return -EIO; | 197 | return -EIO; |
198 | } | 198 | } |
199 | 199 | ||
200 | for (i = 0; i < count; i++) { | 200 | for (i = 0; i < count; i++) { |
201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
202 | dev_err(&chip->pci_dev->dev, | 202 | dev_err(chip->dev, |
203 | "IBF timeout (while writing data)\n"); | 203 | "IBF timeout (while writing data)\n"); |
204 | return -EIO; | 204 | return -EIO; |
205 | } | 205 | } |
@@ -207,7 +207,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
210 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 210 | dev_err(chip->dev, "IBF timeout\n"); |
211 | return -EIO; | 211 | return -EIO; |
212 | } | 212 | } |
213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); | 213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); |
@@ -220,6 +220,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip) | |||
220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); | 220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); |
221 | } | 221 | } |
222 | 222 | ||
223 | static u8 tpm_nsc_status(struct tpm_chip *chip) | ||
224 | { | ||
225 | return inb(chip->vendor->base + NSC_STATUS); | ||
226 | } | ||
227 | |||
223 | static struct file_operations nsc_ops = { | 228 | static struct file_operations nsc_ops = { |
224 | .owner = THIS_MODULE, | 229 | .owner = THIS_MODULE, |
225 | .llseek = no_llseek, | 230 | .llseek = no_llseek, |
@@ -239,7 +244,7 @@ static struct attribute * nsc_attrs[] = { | |||
239 | &dev_attr_pcrs.attr, | 244 | &dev_attr_pcrs.attr, |
240 | &dev_attr_caps.attr, | 245 | &dev_attr_caps.attr, |
241 | &dev_attr_cancel.attr, | 246 | &dev_attr_cancel.attr, |
242 | 0, | 247 | NULL, |
243 | }; | 248 | }; |
244 | 249 | ||
245 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; | 250 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; |
@@ -248,6 +253,7 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
248 | .recv = tpm_nsc_recv, | 253 | .recv = tpm_nsc_recv, |
249 | .send = tpm_nsc_send, | 254 | .send = tpm_nsc_send, |
250 | .cancel = tpm_nsc_cancel, | 255 | .cancel = tpm_nsc_cancel, |
256 | .status = tpm_nsc_status, | ||
251 | .req_complete_mask = NSC_STATUS_OBF, | 257 | .req_complete_mask = NSC_STATUS_OBF, |
252 | .req_complete_val = NSC_STATUS_OBF, | 258 | .req_complete_val = NSC_STATUS_OBF, |
253 | .req_canceled = NSC_STATUS_RDY, | 259 | .req_canceled = NSC_STATUS_RDY, |
@@ -255,16 +261,32 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
255 | .miscdev = { .fops = &nsc_ops, }, | 261 | .miscdev = { .fops = &nsc_ops, }, |
256 | }; | 262 | }; |
257 | 263 | ||
258 | static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | 264 | static struct platform_device *pdev = NULL; |
259 | const struct pci_device_id *pci_id) | 265 | |
266 | static void __devexit tpm_nsc_remove(struct device *dev) | ||
267 | { | ||
268 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
269 | if ( chip ) { | ||
270 | release_region(chip->vendor->base, 2); | ||
271 | tpm_remove_hardware(chip->dev); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | static struct device_driver nsc_drv = { | ||
276 | .name = "tpm_nsc", | ||
277 | .bus = &platform_bus_type, | ||
278 | .owner = THIS_MODULE, | ||
279 | .suspend = tpm_pm_suspend, | ||
280 | .resume = tpm_pm_resume, | ||
281 | }; | ||
282 | |||
283 | static int __init init_nsc(void) | ||
260 | { | 284 | { |
261 | int rc = 0; | 285 | int rc = 0; |
262 | int lo, hi; | 286 | int lo, hi; |
263 | int nscAddrBase = TPM_ADDR; | 287 | int nscAddrBase = TPM_ADDR; |
264 | 288 | ||
265 | 289 | driver_register(&nsc_drv); | |
266 | if (pci_enable_device(pci_dev)) | ||
267 | return -EIO; | ||
268 | 290 | ||
269 | /* select PM channel 1 */ | 291 | /* select PM channel 1 */ |
270 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); | 292 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); |
@@ -273,37 +295,71 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
273 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { | 295 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { |
274 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| | 296 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| |
275 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); | 297 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); |
276 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) { | 298 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) |
277 | rc = -ENODEV; | 299 | return -ENODEV; |
278 | goto out_err; | ||
279 | } | ||
280 | } | 300 | } |
281 | 301 | ||
282 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | 302 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); |
283 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | 303 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); |
284 | tpm_nsc.base = (hi<<8) | lo; | 304 | tpm_nsc.base = (hi<<8) | lo; |
285 | 305 | ||
286 | dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); | 306 | /* enable the DPM module */ |
287 | dev_dbg(&pci_dev->dev, | 307 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); |
308 | |||
309 | pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
310 | if ( !pdev ) | ||
311 | return -ENOMEM; | ||
312 | |||
313 | memset(pdev, 0, sizeof(struct platform_device)); | ||
314 | |||
315 | pdev->name = "tpm_nscl0"; | ||
316 | pdev->id = -1; | ||
317 | pdev->num_resources = 0; | ||
318 | pdev->dev.release = tpm_nsc_remove; | ||
319 | pdev->dev.driver = &nsc_drv; | ||
320 | |||
321 | if ((rc=platform_device_register(pdev)) < 0) { | ||
322 | kfree(pdev); | ||
323 | pdev = NULL; | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { | ||
328 | platform_device_unregister(pdev); | ||
329 | kfree(pdev); | ||
330 | pdev = NULL; | ||
331 | return -EBUSY; | ||
332 | } | ||
333 | |||
334 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) { | ||
335 | release_region(tpm_nsc.base, 2); | ||
336 | platform_device_unregister(pdev); | ||
337 | kfree(pdev); | ||
338 | pdev = NULL; | ||
339 | return rc; | ||
340 | } | ||
341 | |||
342 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); | ||
343 | dev_dbg(&pdev->dev, | ||
288 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", | 344 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", |
289 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), | 345 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), |
290 | tpm_read_index(nscAddrBase,0x27)); | 346 | tpm_read_index(nscAddrBase,0x27)); |
291 | dev_dbg(&pci_dev->dev, | 347 | dev_dbg(&pdev->dev, |
292 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", | 348 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", |
293 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), | 349 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), |
294 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); | 350 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); |
295 | dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", | 351 | dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n", |
296 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); | 352 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); |
297 | dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", | 353 | dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n", |
298 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); | 354 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); |
299 | dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", | 355 | dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n", |
300 | tpm_read_index(nscAddrBase,0x70)); | 356 | tpm_read_index(nscAddrBase,0x70)); |
301 | dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", | 357 | dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n", |
302 | tpm_read_index(nscAddrBase,0x71)); | 358 | tpm_read_index(nscAddrBase,0x71)); |
303 | dev_dbg(&pci_dev->dev, | 359 | dev_dbg(&pdev->dev, |
304 | "NSC DMA channel select0 0x%x, select1 0x%x\n", | 360 | "NSC DMA channel select0 0x%x, select1 0x%x\n", |
305 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); | 361 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); |
306 | dev_dbg(&pci_dev->dev, | 362 | dev_dbg(&pdev->dev, |
307 | "NSC Config " | 363 | "NSC Config " |
308 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 364 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
309 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), | 365 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), |
@@ -312,55 +368,23 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
312 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), | 368 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), |
313 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); | 369 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); |
314 | 370 | ||
315 | dev_info(&pci_dev->dev, | 371 | dev_info(&pdev->dev, |
316 | "NSC TPM revision %d\n", | 372 | "NSC TPM revision %d\n", |
317 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); | 373 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); |
318 | 374 | ||
319 | /* enable the DPM module */ | ||
320 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); | ||
321 | |||
322 | if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) | ||
323 | goto out_err; | ||
324 | |||
325 | return 0; | 375 | return 0; |
326 | |||
327 | out_err: | ||
328 | pci_disable_device(pci_dev); | ||
329 | return rc; | ||
330 | } | ||
331 | |||
332 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
333 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
334 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
335 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
336 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
337 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
338 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
339 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
340 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
341 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
342 | {0,} | ||
343 | }; | ||
344 | |||
345 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | ||
346 | |||
347 | static struct pci_driver nsc_pci_driver = { | ||
348 | .name = "tpm_nsc", | ||
349 | .id_table = tpm_pci_tbl, | ||
350 | .probe = tpm_nsc_init, | ||
351 | .remove = __devexit_p(tpm_remove), | ||
352 | .suspend = tpm_pm_suspend, | ||
353 | .resume = tpm_pm_resume, | ||
354 | }; | ||
355 | |||
356 | static int __init init_nsc(void) | ||
357 | { | ||
358 | return pci_register_driver(&nsc_pci_driver); | ||
359 | } | 376 | } |
360 | 377 | ||
361 | static void __exit cleanup_nsc(void) | 378 | static void __exit cleanup_nsc(void) |
362 | { | 379 | { |
363 | pci_unregister_driver(&nsc_pci_driver); | 380 | if (pdev) { |
381 | tpm_nsc_remove(&pdev->dev); | ||
382 | platform_device_unregister(pdev); | ||
383 | kfree(pdev); | ||
384 | pdev = NULL; | ||
385 | } | ||
386 | |||
387 | driver_unregister(&nsc_drv); | ||
364 | } | 388 | } |
365 | 389 | ||
366 | module_init(init_nsc); | 390 | module_init(init_nsc); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index f5649a337743..c586bfa852ee 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -809,7 +809,7 @@ static void do_tty_hangup(void *data) | |||
809 | check_tty_count(tty, "do_tty_hangup"); | 809 | check_tty_count(tty, "do_tty_hangup"); |
810 | file_list_lock(); | 810 | file_list_lock(); |
811 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 811 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
812 | list_for_each_entry(filp, &tty->tty_files, f_list) { | 812 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { |
813 | if (filp->f_op->write == redirected_tty_write) | 813 | if (filp->f_op->write == redirected_tty_write) |
814 | cons_filp = filp; | 814 | cons_filp = filp; |
815 | if (filp->f_op->write != tty_write) | 815 | if (filp->f_op->write != tty_write) |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index a5e104f428f8..51abd3defc1c 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -993,13 +993,16 @@ static struct vio_device_id viotape_device_table[] __devinitdata = { | |||
993 | { "viotape", "" }, | 993 | { "viotape", "" }, |
994 | { "", "" } | 994 | { "", "" } |
995 | }; | 995 | }; |
996 | |||
997 | MODULE_DEVICE_TABLE(vio, viotape_device_table); | 996 | MODULE_DEVICE_TABLE(vio, viotape_device_table); |
997 | |||
998 | static struct vio_driver viotape_driver = { | 998 | static struct vio_driver viotape_driver = { |
999 | .name = "viotape", | ||
1000 | .id_table = viotape_device_table, | 999 | .id_table = viotape_device_table, |
1001 | .probe = viotape_probe, | 1000 | .probe = viotape_probe, |
1002 | .remove = viotape_remove | 1001 | .remove = viotape_remove, |
1002 | .driver = { | ||
1003 | .name = "viotape", | ||
1004 | .owner = THIS_MODULE, | ||
1005 | } | ||
1003 | }; | 1006 | }; |
1004 | 1007 | ||
1005 | 1008 | ||
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 1d44f69e1fda..003dda147cd0 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -192,6 +192,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) | |||
192 | int i, j, k; | 192 | int i, j, k; |
193 | int ret; | 193 | int ret; |
194 | 194 | ||
195 | if (!capable(CAP_SYS_TTY_CONFIG)) | ||
196 | return -EPERM; | ||
197 | |||
195 | kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); | 198 | kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); |
196 | if (!kbs) { | 199 | if (!kbs) { |
197 | ret = -ENOMEM; | 200 | ret = -ENOMEM; |
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c index 2865dac0a813..e75045fe2641 100644 --- a/drivers/char/watchdog/cpu5wdt.c +++ b/drivers/char/watchdog/cpu5wdt.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/jiffies.h> | ||
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
33 | 34 | ||
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c index 7fc2188386d9..d8dede575402 100644 --- a/drivers/char/watchdog/mixcomwd.c +++ b/drivers/char/watchdog/mixcomwd.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/fs.h> | 45 | #include <linux/fs.h> |
46 | #include <linux/reboot.h> | 46 | #include <linux/reboot.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/jiffies.h> | ||
49 | #include <linux/timer.h> | ||
48 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
50 | 52 | ||
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 427ad51b7a35..37c9e13ad3ac 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -66,7 +66,7 @@ | |||
66 | #include <linux/init.h> | 66 | #include <linux/init.h> |
67 | #include <linux/spinlock.h> | 67 | #include <linux/spinlock.h> |
68 | #include <linux/reboot.h> | 68 | #include <linux/reboot.h> |
69 | 69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ | |
70 | #include <asm/uaccess.h> | 70 | #include <asm/uaccess.h> |
71 | #include <asm/io.h> | 71 | #include <asm/io.h> |
72 | 72 | ||
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index 0b8e493be045..5308e5c8f29a 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c | |||
@@ -753,6 +753,7 @@ static struct pci_device_id pcipcwd_pci_tbl[] = { | |||
753 | MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl); | 753 | MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl); |
754 | 754 | ||
755 | static struct pci_driver pcipcwd_driver = { | 755 | static struct pci_driver pcipcwd_driver = { |
756 | .owner = THIS_MODULE, | ||
756 | .name = WATCHDOG_NAME, | 757 | .name = WATCHDOG_NAME, |
757 | .id_table = pcipcwd_pci_tbl, | 758 | .id_table = pcipcwd_pci_tbl, |
758 | .probe = pcipcwd_card_init, | 759 | .probe = pcipcwd_card_init, |
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c index 72501be79b0c..4ee9974ad8cb 100644 --- a/drivers/char/watchdog/sc520_wdt.c +++ b/drivers/char/watchdog/sc520_wdt.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/notifier.h> | 63 | #include <linux/notifier.h> |
64 | #include <linux/reboot.h> | 64 | #include <linux/reboot.h> |
65 | #include <linux/init.h> | 65 | #include <linux/init.h> |
66 | #include <linux/jiffies.h> | ||
66 | 67 | ||
67 | #include <asm/io.h> | 68 | #include <asm/io.h> |
68 | #include <asm/uaccess.h> | 69 | #include <asm/uaccess.h> |
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c index 20e5eb8667f2..a91edaf3a350 100644 --- a/drivers/char/watchdog/softdog.c +++ b/drivers/char/watchdog/softdog.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <linux/notifier.h> | 47 | #include <linux/notifier.h> |
48 | #include <linux/reboot.h> | 48 | #include <linux/reboot.h> |
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/jiffies.h> | ||
51 | |||
50 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
51 | 53 | ||
52 | #define PFX "SoftDog: " | 54 | #define PFX "SoftDog: " |
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c index 4b3311993d48..dc9370f6c348 100644 --- a/drivers/char/watchdog/wdt_pci.c +++ b/drivers/char/watchdog/wdt_pci.c | |||
@@ -711,6 +711,7 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl); | |||
711 | 711 | ||
712 | 712 | ||
713 | static struct pci_driver wdtpci_driver = { | 713 | static struct pci_driver wdtpci_driver = { |
714 | .owner = THIS_MODULE, | ||
714 | .name = "wdt_pci", | 715 | .name = "wdt_pci", |
715 | .id_table = wdtpci_pci_tbl, | 716 | .id_table = wdtpci_pci_tbl, |
716 | .probe = wdtpci_init_one, | 717 | .probe = wdtpci_init_one, |