aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/efficeon-agp.c8
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/cs5535_gpio.c5
-rw-r--r--drivers/char/drm/drmP.h4
-rw-r--r--drivers/char/drm/drm_drv.c4
-rw-r--r--drivers/char/drm/drm_memory.c134
-rw-r--r--drivers/char/drm/drm_memory.h128
-rw-r--r--drivers/char/drm/drm_memory_debug.h2
-rw-r--r--drivers/char/drm/drm_pci.c1
-rw-r--r--drivers/char/drm/via_irq.c12
-rw-r--r--drivers/char/dtlk.c2
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c4
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/char/sonypi.c3
-rw-r--r--drivers/char/tlclk.c36
-rw-r--r--drivers/char/tty_io.c36
-rw-r--r--drivers/char/vr41xx_rtc.c717
21 files changed, 215 insertions, 893 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 889cad07774e..402296670d3a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -805,10 +805,6 @@ config S3C2410_RTC
805 Samsung S3C2410. This can provide periodic interrupt rates 805 Samsung S3C2410. This can provide periodic interrupt rates
806 from 1Hz to 64Hz for user programs, and wakeup from Alarm. 806 from 1Hz to 64Hz for user programs, and wakeup from Alarm.
807 807
808config RTC_VR41XX
809 tristate "NEC VR4100 series Real Time Clock Support"
810 depends on CPU_VR41XX
811
812config COBALT_LCD 808config COBALT_LCD
813 bool "Support for Cobalt LCD" 809 bool "Support for Cobalt LCD"
814 depends on MIPS_COBALT 810 depends on MIPS_COBALT
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index a73cb4956928..f5b01c6d498e 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -67,7 +67,6 @@ obj-$(CONFIG_SGI_DS1286) += ds1286.o
67obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o 67obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
68obj-$(CONFIG_DS1302) += ds1302.o 68obj-$(CONFIG_DS1302) += ds1302.o
69obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o 69obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o
70obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o
71ifeq ($(CONFIG_GENERIC_NVRAM),y) 70ifeq ($(CONFIG_GENERIC_NVRAM),y)
72 obj-$(CONFIG_NVRAM) += generic_nvram.o 71 obj-$(CONFIG_NVRAM) += generic_nvram.o
73else 72else
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index fed0a87448d8..86a966b65236 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -64,6 +64,12 @@ static struct gatt_mask efficeon_generic_masks[] =
64 {.mask = 0x00000001, .type = 0} 64 {.mask = 0x00000001, .type = 0}
65}; 65};
66 66
67/* This function does the same thing as mask_memory() for this chipset... */
68static inline unsigned long efficeon_mask_memory(unsigned long addr)
69{
70 return addr | 0x00000001;
71}
72
67static struct aper_size_info_lvl2 efficeon_generic_sizes[4] = 73static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
68{ 74{
69 {256, 65536, 0}, 75 {256, 65536, 0},
@@ -251,7 +257,7 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t
251 last_page = NULL; 257 last_page = NULL;
252 for (i = 0; i < count; i++) { 258 for (i = 0; i < count; i++) {
253 int index = pg_start + i; 259 int index = pg_start + i;
254 unsigned long insert = mem->memory[i]; 260 unsigned long insert = efficeon_mask_memory(mem->memory[i]);
255 261
256 page = (unsigned int *) efficeon_private.l1_table[index >> 10]; 262 page = (unsigned int *) efficeon_private.l1_table[index >> 10];
257 263
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 927a5bbe112c..a370e7a0bad5 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -142,7 +142,7 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc,
142 if (!boardno) 142 if (!boardno)
143 boardno = readb(loc + NUMCARD_OWNER_TO_PC); 143 boardno = readb(loc + NUMCARD_OWNER_TO_PC);
144 144
145 if (!boardno && boardno > MAX_BOARD) { 145 if (!boardno || boardno > MAX_BOARD) {
146 printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", 146 printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",
147 boardno, physloc, MAX_BOARD); 147 boardno, physloc, MAX_BOARD);
148 return 0; 148 return 0;
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 5d72f50de1ac..46d66037b917 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -241,9 +241,10 @@ static int __init cs5535_gpio_init(void)
241static void __exit cs5535_gpio_cleanup(void) 241static void __exit cs5535_gpio_cleanup(void)
242{ 242{
243 dev_t dev_id = MKDEV(major, 0); 243 dev_t dev_id = MKDEV(major, 0);
244
245 cdev_del(&cs5535_gpio_cdev);
244 unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); 246 unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
245 if (gpio_base != 0) 247 release_region(gpio_base, CS5535_GPIO_SIZE);
246 release_region(gpio_base, CS5535_GPIO_SIZE);
247} 248}
248 249
249module_init(cs5535_gpio_init); 250module_init(cs5535_gpio_init);
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index edc72a6348a7..e1aadae00623 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -815,8 +815,6 @@ extern int drm_mem_info(char *buf, char **start, off_t offset,
815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); 815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
816extern void *drm_ioremap(unsigned long offset, unsigned long size, 816extern void *drm_ioremap(unsigned long offset, unsigned long size,
817 drm_device_t * dev); 817 drm_device_t * dev);
818extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
819 drm_device_t * dev);
820extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); 818extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
821 819
822extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); 820extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
@@ -1022,11 +1020,13 @@ static __inline__ void drm_core_ioremap(struct drm_map *map,
1022 map->handle = drm_ioremap(map->offset, map->size, dev); 1020 map->handle = drm_ioremap(map->offset, map->size, dev);
1023} 1021}
1024 1022
1023#if 0
1025static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, 1024static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
1026 struct drm_device *dev) 1025 struct drm_device *dev)
1027{ 1026{
1028 map->handle = drm_ioremap_nocache(map->offset, map->size, dev); 1027 map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
1029} 1028}
1029#endif /* 0 */
1030 1030
1031static __inline__ void drm_core_ioremapfree(struct drm_map *map, 1031static __inline__ void drm_core_ioremapfree(struct drm_map *map,
1032 struct drm_device *dev) 1032 struct drm_device *dev)
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index dc6bbe8a18dc..3c0b882a8e72 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -75,8 +75,8 @@ static drm_ioctl_desc_t drm_ioctls[] = {
75 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 75 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
76 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, 76 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
77 77
78 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 78 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY},
79 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 79 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_ROOT_ONLY},
80 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 80 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
81 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, 81 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
82 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 82 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index dddf8de66143..7e3318e1d1c6 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -80,6 +80,71 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
80} 80}
81 81
82#if __OS_HAS_AGP 82#if __OS_HAS_AGP
83/*
84 * Find the drm_map that covers the range [offset, offset+size).
85 */
86static drm_map_t *drm_lookup_map(unsigned long offset,
87 unsigned long size, drm_device_t * dev)
88{
89 struct list_head *list;
90 drm_map_list_t *r_list;
91 drm_map_t *map;
92
93 list_for_each(list, &dev->maplist->head) {
94 r_list = (drm_map_list_t *) list;
95 map = r_list->map;
96 if (!map)
97 continue;
98 if (map->offset <= offset
99 && (offset + size) <= (map->offset + map->size))
100 return map;
101 }
102 return NULL;
103}
104
105static void *agp_remap(unsigned long offset, unsigned long size,
106 drm_device_t * dev)
107{
108 unsigned long *phys_addr_map, i, num_pages =
109 PAGE_ALIGN(size) / PAGE_SIZE;
110 struct drm_agp_mem *agpmem;
111 struct page **page_map;
112 void *addr;
113
114 size = PAGE_ALIGN(size);
115
116#ifdef __alpha__
117 offset -= dev->hose->mem_space->start;
118#endif
119
120 for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
121 if (agpmem->bound <= offset
122 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
123 (offset + size))
124 break;
125 if (!agpmem)
126 return NULL;
127
128 /*
129 * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
130 * the CPU do not get remapped by the GART. We fix this by using the kernel's
131 * page-table instead (that's probably faster anyhow...).
132 */
133 /* note: use vmalloc() because num_pages could be large... */
134 page_map = vmalloc(num_pages * sizeof(struct page *));
135 if (!page_map)
136 return NULL;
137
138 phys_addr_map =
139 agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
140 for (i = 0; i < num_pages; ++i)
141 page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
142 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
143 vfree(page_map);
144
145 return addr;
146}
147
83/** Wrapper around agp_allocate_memory() */ 148/** Wrapper around agp_allocate_memory() */
84DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) 149DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
85{ 150{
@@ -103,5 +168,74 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
103{ 168{
104 return drm_agp_unbind_memory(handle); 169 return drm_agp_unbind_memory(handle);
105} 170}
171
172#else /* __OS_HAS_AGP */
173
174static inline drm_map_t *drm_lookup_map(unsigned long offset,
175 unsigned long size, drm_device_t * dev)
176{
177 return NULL;
178}
179
180static inline void *agp_remap(unsigned long offset, unsigned long size,
181 drm_device_t * dev)
182{
183 return NULL;
184}
185
106#endif /* agp */ 186#endif /* agp */
187
188void *drm_ioremap(unsigned long offset, unsigned long size,
189 drm_device_t * dev)
190{
191 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
192 drm_map_t *map = drm_lookup_map(offset, size, dev);
193
194 if (map && map->type == _DRM_AGP)
195 return agp_remap(offset, size, dev);
196 }
197 return ioremap(offset, size);
198}
199EXPORT_SYMBOL(drm_ioremap);
200
201#if 0
202void *drm_ioremap_nocache(unsigned long offset,
203 unsigned long size, drm_device_t * dev)
204{
205 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
206 drm_map_t *map = drm_lookup_map(offset, size, dev);
207
208 if (map && map->type == _DRM_AGP)
209 return agp_remap(offset, size, dev);
210 }
211 return ioremap_nocache(offset, size);
212}
213#endif /* 0 */
214
215void drm_ioremapfree(void *pt, unsigned long size,
216 drm_device_t * dev)
217{
218 /*
219 * This is a bit ugly. It would be much cleaner if the DRM API would use separate
220 * routines for handling mappings in the AGP space. Hopefully this can be done in
221 * a future revision of the interface...
222 */
223 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
224 && ((unsigned long)pt >= VMALLOC_START
225 && (unsigned long)pt < VMALLOC_END)) {
226 unsigned long offset;
227 drm_map_t *map;
228
229 offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
230 map = drm_lookup_map(offset, size, dev);
231 if (map && map->type == _DRM_AGP) {
232 vunmap(pt);
233 return;
234 }
235 }
236
237 iounmap(pt);
238}
239EXPORT_SYMBOL(drm_ioremapfree);
240
107#endif /* debug_memory */ 241#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
index 3732a61c3762..714d9aedcff5 100644
--- a/drivers/char/drm/drm_memory.h
+++ b/drivers/char/drm/drm_memory.h
@@ -57,71 +57,6 @@
57# endif 57# endif
58#endif 58#endif
59 59
60/*
61 * Find the drm_map that covers the range [offset, offset+size).
62 */
63static inline drm_map_t *drm_lookup_map(unsigned long offset,
64 unsigned long size, drm_device_t * dev)
65{
66 struct list_head *list;
67 drm_map_list_t *r_list;
68 drm_map_t *map;
69
70 list_for_each(list, &dev->maplist->head) {
71 r_list = (drm_map_list_t *) list;
72 map = r_list->map;
73 if (!map)
74 continue;
75 if (map->offset <= offset
76 && (offset + size) <= (map->offset + map->size))
77 return map;
78 }
79 return NULL;
80}
81
82static inline void *agp_remap(unsigned long offset, unsigned long size,
83 drm_device_t * dev)
84{
85 unsigned long *phys_addr_map, i, num_pages =
86 PAGE_ALIGN(size) / PAGE_SIZE;
87 struct drm_agp_mem *agpmem;
88 struct page **page_map;
89 void *addr;
90
91 size = PAGE_ALIGN(size);
92
93#ifdef __alpha__
94 offset -= dev->hose->mem_space->start;
95#endif
96
97 for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
98 if (agpmem->bound <= offset
99 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
100 (offset + size))
101 break;
102 if (!agpmem)
103 return NULL;
104
105 /*
106 * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
107 * the CPU do not get remapped by the GART. We fix this by using the kernel's
108 * page-table instead (that's probably faster anyhow...).
109 */
110 /* note: use vmalloc() because num_pages could be large... */
111 page_map = vmalloc(num_pages * sizeof(struct page *));
112 if (!page_map)
113 return NULL;
114
115 phys_addr_map =
116 agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
117 for (i = 0; i < num_pages; ++i)
118 page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
119 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
120 vfree(page_map);
121
122 return addr;
123}
124
125static inline unsigned long drm_follow_page(void *vaddr) 60static inline unsigned long drm_follow_page(void *vaddr)
126{ 61{
127 pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); 62 pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
@@ -133,18 +68,6 @@ static inline unsigned long drm_follow_page(void *vaddr)
133 68
134#else /* __OS_HAS_AGP */ 69#else /* __OS_HAS_AGP */
135 70
136static inline drm_map_t *drm_lookup_map(unsigned long offset,
137 unsigned long size, drm_device_t * dev)
138{
139 return NULL;
140}
141
142static inline void *agp_remap(unsigned long offset, unsigned long size,
143 drm_device_t * dev)
144{
145 return NULL;
146}
147
148static inline unsigned long drm_follow_page(void *vaddr) 71static inline unsigned long drm_follow_page(void *vaddr)
149{ 72{
150 return 0; 73 return 0;
@@ -152,51 +75,8 @@ static inline unsigned long drm_follow_page(void *vaddr)
152 75
153#endif 76#endif
154 77
155static inline void *drm_ioremap(unsigned long offset, unsigned long size, 78void *drm_ioremap(unsigned long offset, unsigned long size,
156 drm_device_t * dev) 79 drm_device_t * dev);
157{
158 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
159 drm_map_t *map = drm_lookup_map(offset, size, dev);
160
161 if (map && map->type == _DRM_AGP)
162 return agp_remap(offset, size, dev);
163 }
164 return ioremap(offset, size);
165}
166
167static inline void *drm_ioremap_nocache(unsigned long offset,
168 unsigned long size, drm_device_t * dev)
169{
170 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
171 drm_map_t *map = drm_lookup_map(offset, size, dev);
172
173 if (map && map->type == _DRM_AGP)
174 return agp_remap(offset, size, dev);
175 }
176 return ioremap_nocache(offset, size);
177}
178
179static inline void drm_ioremapfree(void *pt, unsigned long size,
180 drm_device_t * dev)
181{
182 /*
183 * This is a bit ugly. It would be much cleaner if the DRM API would use separate
184 * routines for handling mappings in the AGP space. Hopefully this can be done in
185 * a future revision of the interface...
186 */
187 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
188 && ((unsigned long)pt >= VMALLOC_START
189 && (unsigned long)pt < VMALLOC_END)) {
190 unsigned long offset;
191 drm_map_t *map;
192
193 offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
194 map = drm_lookup_map(offset, size, dev);
195 if (map && map->type == _DRM_AGP) {
196 vunmap(pt);
197 return;
198 }
199 }
200 80
201 iounmap(pt); 81void drm_ioremapfree(void *pt, unsigned long size,
202} 82 drm_device_t * dev);
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index 7868341817da..6543b9a14c42 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -229,6 +229,7 @@ void *drm_ioremap (unsigned long offset, unsigned long size,
229 return pt; 229 return pt;
230} 230}
231 231
232#if 0
232void *drm_ioremap_nocache (unsigned long offset, unsigned long size, 233void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
233 drm_device_t * dev) { 234 drm_device_t * dev) {
234 void *pt; 235 void *pt;
@@ -251,6 +252,7 @@ void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
251 spin_unlock(&drm_mem_lock); 252 spin_unlock(&drm_mem_lock);
252 return pt; 253 return pt;
253} 254}
255#endif /* 0 */
254 256
255void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { 257void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
256 int alloc_count; 258 int alloc_count;
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index b28ca9cea8a2..86a0f1c22091 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -37,6 +37,7 @@
37 */ 37 */
38 38
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/dma-mapping.h>
40#include "drmP.h" 41#include "drmP.h"
41 42
42/**********************************************************************/ 43/**********************************************************************/
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index 6152415644e9..c33d068cde19 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -196,9 +196,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
196{ 196{
197 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 197 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
198 unsigned int cur_irq_sequence; 198 unsigned int cur_irq_sequence;
199 drm_via_irq_t *cur_irq = dev_priv->via_irqs; 199 drm_via_irq_t *cur_irq;
200 int ret = 0; 200 int ret = 0;
201 maskarray_t *masks = dev_priv->irq_masks; 201 maskarray_t *masks;
202 int real_irq; 202 int real_irq;
203 203
204 DRM_DEBUG("%s\n", __FUNCTION__); 204 DRM_DEBUG("%s\n", __FUNCTION__);
@@ -221,8 +221,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
221 __FUNCTION__, irq); 221 __FUNCTION__, irq);
222 return DRM_ERR(EINVAL); 222 return DRM_ERR(EINVAL);
223 } 223 }
224 224
225 cur_irq += real_irq; 225 masks = dev_priv->irq_masks;
226 cur_irq = dev_priv->via_irqs + real_irq;
226 227
227 if (masks[real_irq][2] && !force_sequence) { 228 if (masks[real_irq][2] && !force_sequence) {
228 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, 229 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
@@ -247,11 +248,12 @@ void via_driver_irq_preinstall(drm_device_t * dev)
247{ 248{
248 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 249 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
249 u32 status; 250 u32 status;
250 drm_via_irq_t *cur_irq = dev_priv->via_irqs; 251 drm_via_irq_t *cur_irq;
251 int i; 252 int i;
252 253
253 DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); 254 DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
254 if (dev_priv) { 255 if (dev_priv) {
256 cur_irq = dev_priv->via_irqs;
255 257
256 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; 258 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
257 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; 259 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index a229915ce1b2..87dcaa237f07 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -490,7 +490,7 @@ for (i = 0; i < 10; i++) \
490 release_region(dtlk_portlist[i], DTLK_IO_EXTENT); 490 release_region(dtlk_portlist[i], DTLK_IO_EXTENT);
491 } 491 }
492 492
493 printk(KERN_INFO "\nDoubleTalk PC - not found\n"); 493 printk(KERN_INFO "DoubleTalk PC - not found\n");
494 return -ENODEV; 494 return -ENODEV;
495} 495}
496 496
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 58dcdee1cd71..0030cd8e2e95 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -165,7 +165,7 @@ static int bt_start_transaction(struct si_sm_data *bt,
165{ 165{
166 unsigned int i; 166 unsigned int i;
167 167
168 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) 168 if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2)))
169 return -1; 169 return -1;
170 170
171 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) 171 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0ded046d5aa8..9f2f8fdec69a 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -941,6 +941,7 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
941 list_del(&msg->link); 941 list_del(&msg->link);
942 list_add_tail(&msg->link, &msgs); 942 list_add_tail(&msg->link, &msgs);
943 } 943 }
944 intf->waiting_events_count = 0;
944 } 945 }
945 946
946 /* Hold the events lock while doing this to preserve order. */ 947 /* Hold the events lock while doing this to preserve order. */
@@ -2916,6 +2917,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2916 2917
2917 copy_event_into_recv_msg(recv_msg, msg); 2918 copy_event_into_recv_msg(recv_msg, msg);
2918 list_add_tail(&(recv_msg->link), &(intf->waiting_events)); 2919 list_add_tail(&(recv_msg->link), &(intf->waiting_events));
2920 intf->waiting_events_count++;
2919 } else { 2921 } else {
2920 /* There's too many things in the queue, discard this 2922 /* There's too many things in the queue, discard this
2921 message. */ 2923 message. */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index a86c0f29953e..b36eef0e9d19 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2198,11 +2198,11 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
2198 } 2198 }
2199} 2199}
2200 2200
2201static struct ipmi_default_vals 2201static __devinitdata struct ipmi_default_vals
2202{ 2202{
2203 int type; 2203 int type;
2204 int port; 2204 int port;
2205} __devinit ipmi_defaults[] = 2205} ipmi_defaults[] =
2206{ 2206{
2207 { .type = SI_KCS, .port = 0xca2 }, 2207 { .type = SI_KCS, .port = 0xca2 },
2208 { .type = SI_SMIC, .port = 0xca9 }, 2208 { .type = SI_SMIC, .port = 0xca9 },
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 86be04b241e1..58f3512c52e1 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1584,7 +1584,6 @@ u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dpo
1584 1584
1585 return twothirdsMD4Transform(daddr, hash); 1585 return twothirdsMD4Transform(daddr, hash);
1586} 1586}
1587EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
1588#endif 1587#endif
1589 1588
1590#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) 1589#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f8dd8527c6aa..a90f5d97df35 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1341,6 +1341,9 @@ static int __devinit sonypi_probe(struct platform_device *dev)
1341 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1341 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1342 PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) 1342 PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
1343 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; 1343 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1344 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1345 PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
1346 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1344 else 1347 else
1345 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; 1348 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
1346 1349
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 2546637a55c0..f58ad7f68267 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -327,7 +327,7 @@ static ssize_t store_received_ref_clk3a(struct device *d,
327 return strnlen(buf, count); 327 return strnlen(buf, count);
328} 328}
329 329
330static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, 330static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
331 store_received_ref_clk3a); 331 store_received_ref_clk3a);
332 332
333 333
@@ -349,7 +349,7 @@ static ssize_t store_received_ref_clk3b(struct device *d,
349 return strnlen(buf, count); 349 return strnlen(buf, count);
350} 350}
351 351
352static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, 352static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
353 store_received_ref_clk3b); 353 store_received_ref_clk3b);
354 354
355 355
@@ -371,7 +371,7 @@ static ssize_t store_enable_clk3b_output(struct device *d,
371 return strnlen(buf, count); 371 return strnlen(buf, count);
372} 372}
373 373
374static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, 374static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
375 store_enable_clk3b_output); 375 store_enable_clk3b_output);
376 376
377static ssize_t store_enable_clk3a_output(struct device *d, 377static ssize_t store_enable_clk3a_output(struct device *d,
@@ -392,7 +392,7 @@ static ssize_t store_enable_clk3a_output(struct device *d,
392 return strnlen(buf, count); 392 return strnlen(buf, count);
393} 393}
394 394
395static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, 395static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
396 store_enable_clk3a_output); 396 store_enable_clk3a_output);
397 397
398static ssize_t store_enable_clkb1_output(struct device *d, 398static ssize_t store_enable_clkb1_output(struct device *d,
@@ -413,7 +413,7 @@ static ssize_t store_enable_clkb1_output(struct device *d,
413 return strnlen(buf, count); 413 return strnlen(buf, count);
414} 414}
415 415
416static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, 416static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
417 store_enable_clkb1_output); 417 store_enable_clkb1_output);
418 418
419 419
@@ -435,7 +435,7 @@ static ssize_t store_enable_clka1_output(struct device *d,
435 return strnlen(buf, count); 435 return strnlen(buf, count);
436} 436}
437 437
438static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, 438static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
439 store_enable_clka1_output); 439 store_enable_clka1_output);
440 440
441static ssize_t store_enable_clkb0_output(struct device *d, 441static ssize_t store_enable_clkb0_output(struct device *d,
@@ -456,7 +456,7 @@ static ssize_t store_enable_clkb0_output(struct device *d,
456 return strnlen(buf, count); 456 return strnlen(buf, count);
457} 457}
458 458
459static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, 459static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
460 store_enable_clkb0_output); 460 store_enable_clkb0_output);
461 461
462static ssize_t store_enable_clka0_output(struct device *d, 462static ssize_t store_enable_clka0_output(struct device *d,
@@ -477,7 +477,7 @@ static ssize_t store_enable_clka0_output(struct device *d,
477 return strnlen(buf, count); 477 return strnlen(buf, count);
478} 478}
479 479
480static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, 480static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
481 store_enable_clka0_output); 481 store_enable_clka0_output);
482 482
483static ssize_t store_select_amcb2_transmit_clock(struct device *d, 483static ssize_t store_select_amcb2_transmit_clock(struct device *d,
@@ -519,7 +519,7 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d,
519 return strnlen(buf, count); 519 return strnlen(buf, count);
520} 520}
521 521
522static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, 522static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
523 store_select_amcb2_transmit_clock); 523 store_select_amcb2_transmit_clock);
524 524
525static ssize_t store_select_amcb1_transmit_clock(struct device *d, 525static ssize_t store_select_amcb1_transmit_clock(struct device *d,
@@ -560,7 +560,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d,
560 return strnlen(buf, count); 560 return strnlen(buf, count);
561} 561}
562 562
563static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, 563static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
564 store_select_amcb1_transmit_clock); 564 store_select_amcb1_transmit_clock);
565 565
566static ssize_t store_select_redundant_clock(struct device *d, 566static ssize_t store_select_redundant_clock(struct device *d,
@@ -581,7 +581,7 @@ static ssize_t store_select_redundant_clock(struct device *d,
581 return strnlen(buf, count); 581 return strnlen(buf, count);
582} 582}
583 583
584static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, 584static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
585 store_select_redundant_clock); 585 store_select_redundant_clock);
586 586
587static ssize_t store_select_ref_frequency(struct device *d, 587static ssize_t store_select_ref_frequency(struct device *d,
@@ -602,7 +602,7 @@ static ssize_t store_select_ref_frequency(struct device *d,
602 return strnlen(buf, count); 602 return strnlen(buf, count);
603} 603}
604 604
605static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, 605static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
606 store_select_ref_frequency); 606 store_select_ref_frequency);
607 607
608static ssize_t store_filter_select(struct device *d, 608static ssize_t store_filter_select(struct device *d,
@@ -623,7 +623,7 @@ static ssize_t store_filter_select(struct device *d,
623 return strnlen(buf, count); 623 return strnlen(buf, count);
624} 624}
625 625
626static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); 626static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
627 627
628static ssize_t store_hardware_switching_mode(struct device *d, 628static ssize_t store_hardware_switching_mode(struct device *d,
629 struct device_attribute *attr, const char *buf, size_t count) 629 struct device_attribute *attr, const char *buf, size_t count)
@@ -643,7 +643,7 @@ static ssize_t store_hardware_switching_mode(struct device *d,
643 return strnlen(buf, count); 643 return strnlen(buf, count);
644} 644}
645 645
646static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, 646static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
647 store_hardware_switching_mode); 647 store_hardware_switching_mode);
648 648
649static ssize_t store_hardware_switching(struct device *d, 649static ssize_t store_hardware_switching(struct device *d,
@@ -664,7 +664,7 @@ static ssize_t store_hardware_switching(struct device *d,
664 return strnlen(buf, count); 664 return strnlen(buf, count);
665} 665}
666 666
667static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, 667static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
668 store_hardware_switching); 668 store_hardware_switching);
669 669
670static ssize_t store_refalign (struct device *d, 670static ssize_t store_refalign (struct device *d,
@@ -684,7 +684,7 @@ static ssize_t store_refalign (struct device *d,
684 return strnlen(buf, count); 684 return strnlen(buf, count);
685} 685}
686 686
687static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); 687static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
688 688
689static ssize_t store_mode_select (struct device *d, 689static ssize_t store_mode_select (struct device *d,
690 struct device_attribute *attr, const char *buf, size_t count) 690 struct device_attribute *attr, const char *buf, size_t count)
@@ -704,7 +704,7 @@ static ssize_t store_mode_select (struct device *d,
704 return strnlen(buf, count); 704 return strnlen(buf, count);
705} 705}
706 706
707static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); 707static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
708 708
709static ssize_t store_reset (struct device *d, 709static ssize_t store_reset (struct device *d,
710 struct device_attribute *attr, const char *buf, size_t count) 710 struct device_attribute *attr, const char *buf, size_t count)
@@ -724,7 +724,7 @@ static ssize_t store_reset (struct device *d,
724 return strnlen(buf, count); 724 return strnlen(buf, count);
725} 725}
726 726
727static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); 727static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
728 728
729static struct attribute *tlclk_sysfs_entries[] = { 729static struct attribute *tlclk_sysfs_entries[] = {
730 &dev_attr_current_ref.attr, 730 &dev_attr_current_ref.attr,
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 98b126c2ded8..f07637a8f88f 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -351,10 +351,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
351 spin_unlock_irqrestore(&tty->buf.lock, flags); 351 spin_unlock_irqrestore(&tty->buf.lock, flags);
352 return size; 352 return size;
353} 353}
354
355EXPORT_SYMBOL_GPL(tty_buffer_request_room); 354EXPORT_SYMBOL_GPL(tty_buffer_request_room);
356 355
357int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) 356int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
357 size_t size)
358{ 358{
359 int copied = 0; 359 int copied = 0;
360 do { 360 do {
@@ -368,17 +368,16 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s
368 tb->used += space; 368 tb->used += space;
369 copied += space; 369 copied += space;
370 chars += space; 370 chars += space;
371/* printk("Flip insert %d.\n", space); */
372 } 371 }
373 /* There is a small chance that we need to split the data over 372 /* There is a small chance that we need to split the data over
374 several buffers. If this is the case we must loop */ 373 several buffers. If this is the case we must loop */
375 while (unlikely(size > copied)); 374 while (unlikely(size > copied));
376 return copied; 375 return copied;
377} 376}
378
379EXPORT_SYMBOL(tty_insert_flip_string); 377EXPORT_SYMBOL(tty_insert_flip_string);
380 378
381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) 379int tty_insert_flip_string_flags(struct tty_struct *tty,
380 const unsigned char *chars, const char *flags, size_t size)
382{ 381{
383 int copied = 0; 382 int copied = 0;
384 do { 383 do {
@@ -399,9 +398,20 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *ch
399 while (unlikely(size > copied)); 398 while (unlikely(size > copied));
400 return copied; 399 return copied;
401} 400}
402
403EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); 401EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags);
404 402
403void tty_schedule_flip(struct tty_struct *tty)
404{
405 unsigned long flags;
406 spin_lock_irqsave(&tty->buf.lock, flags);
407 if (tty->buf.tail != NULL) {
408 tty->buf.tail->active = 0;
409 tty->buf.tail->commit = tty->buf.tail->used;
410 }
411 spin_unlock_irqrestore(&tty->buf.lock, flags);
412 schedule_delayed_work(&tty->buf.work, 1);
413}
414EXPORT_SYMBOL(tty_schedule_flip);
405 415
406/* 416/*
407 * Prepare a block of space in the buffer for data. Returns the length 417 * Prepare a block of space in the buffer for data. Returns the length
@@ -1730,7 +1740,7 @@ static void release_dev(struct file * filp)
1730{ 1740{
1731 struct tty_struct *tty, *o_tty; 1741 struct tty_struct *tty, *o_tty;
1732 int pty_master, tty_closing, o_tty_closing, do_sleep; 1742 int pty_master, tty_closing, o_tty_closing, do_sleep;
1733 int devpts_master, devpts; 1743 int devpts;
1734 int idx; 1744 int idx;
1735 char buf[64]; 1745 char buf[64];
1736 unsigned long flags; 1746 unsigned long flags;
@@ -1747,7 +1757,6 @@ static void release_dev(struct file * filp)
1747 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1757 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1748 tty->driver->subtype == PTY_TYPE_MASTER); 1758 tty->driver->subtype == PTY_TYPE_MASTER);
1749 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; 1759 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
1750 devpts_master = pty_master && devpts;
1751 o_tty = tty->link; 1760 o_tty = tty->link;
1752 1761
1753#ifdef TTY_PARANOIA_CHECK 1762#ifdef TTY_PARANOIA_CHECK
@@ -2185,6 +2194,7 @@ static int ptmx_open(struct inode * inode, struct file * filp)
2185 return 0; 2194 return 0;
2186out1: 2195out1:
2187 release_dev(filp); 2196 release_dev(filp);
2197 return retval;
2188out: 2198out:
2189 down(&allocated_ptys_lock); 2199 down(&allocated_ptys_lock);
2190 idr_remove(&allocated_ptys, index); 2200 idr_remove(&allocated_ptys, index);
@@ -2713,7 +2723,11 @@ static void __do_SAK(void *arg)
2713 } 2723 }
2714 task_lock(p); 2724 task_lock(p);
2715 if (p->files) { 2725 if (p->files) {
2716 rcu_read_lock(); 2726 /*
2727 * We don't take a ref to the file, so we must
2728 * hold ->file_lock instead.
2729 */
2730 spin_lock(&p->files->file_lock);
2717 fdt = files_fdtable(p->files); 2731 fdt = files_fdtable(p->files);
2718 for (i=0; i < fdt->max_fds; i++) { 2732 for (i=0; i < fdt->max_fds; i++) {
2719 filp = fcheck_files(p->files, i); 2733 filp = fcheck_files(p->files, i);
@@ -2724,11 +2738,11 @@ static void __do_SAK(void *arg)
2724 printk(KERN_NOTICE "SAK: killed process %d" 2738 printk(KERN_NOTICE "SAK: killed process %d"
2725 " (%s): fd#%d opened to the tty\n", 2739 " (%s): fd#%d opened to the tty\n",
2726 p->pid, p->comm, i); 2740 p->pid, p->comm, i);
2727 send_sig(SIGKILL, p, 1); 2741 force_sig(SIGKILL, p);
2728 break; 2742 break;
2729 } 2743 }
2730 } 2744 }
2731 rcu_read_unlock(); 2745 spin_unlock(&p->files->file_lock);
2732 } 2746 }
2733 task_unlock(p); 2747 task_unlock(p);
2734 } while_each_thread(g, p); 2748 } while_each_thread(g, p);
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c
deleted file mode 100644
index b109d9a502d6..000000000000
--- a/drivers/char/vr41xx_rtc.c
+++ /dev/null
@@ -1,717 +0,0 @@
1/*
2 * Driver for NEC VR4100 series Real Time Clock unit.
3 *
4 * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/platform_device.h>
21#include <linux/fs.h>
22#include <linux/init.h>
23#include <linux/ioport.h>
24#include <linux/irq.h>
25#include <linux/mc146818rtc.h>
26#include <linux/miscdevice.h>
27#include <linux/module.h>
28#include <linux/poll.h>
29#include <linux/rtc.h>
30#include <linux/spinlock.h>
31#include <linux/types.h>
32#include <linux/wait.h>
33
34#include <asm/div64.h>
35#include <asm/io.h>
36#include <asm/time.h>
37#include <asm/uaccess.h>
38#include <asm/vr41xx/vr41xx.h>
39
40MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
41MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
42MODULE_LICENSE("GPL");
43
44#define RTC1_TYPE1_START 0x0b0000c0UL
45#define RTC1_TYPE1_END 0x0b0000dfUL
46#define RTC2_TYPE1_START 0x0b0001c0UL
47#define RTC2_TYPE1_END 0x0b0001dfUL
48
49#define RTC1_TYPE2_START 0x0f000100UL
50#define RTC1_TYPE2_END 0x0f00011fUL
51#define RTC2_TYPE2_START 0x0f000120UL
52#define RTC2_TYPE2_END 0x0f00013fUL
53
54#define RTC1_SIZE 0x20
55#define RTC2_SIZE 0x20
56
57/* RTC 1 registers */
58#define ETIMELREG 0x00
59#define ETIMEMREG 0x02
60#define ETIMEHREG 0x04
61/* RFU */
62#define ECMPLREG 0x08
63#define ECMPMREG 0x0a
64#define ECMPHREG 0x0c
65/* RFU */
66#define RTCL1LREG 0x10
67#define RTCL1HREG 0x12
68#define RTCL1CNTLREG 0x14
69#define RTCL1CNTHREG 0x16
70#define RTCL2LREG 0x18
71#define RTCL2HREG 0x1a
72#define RTCL2CNTLREG 0x1c
73#define RTCL2CNTHREG 0x1e
74
75/* RTC 2 registers */
76#define TCLKLREG 0x00
77#define TCLKHREG 0x02
78#define TCLKCNTLREG 0x04
79#define TCLKCNTHREG 0x06
80/* RFU */
81#define RTCINTREG 0x1e
82 #define TCLOCK_INT 0x08
83 #define RTCLONG2_INT 0x04
84 #define RTCLONG1_INT 0x02
85 #define ELAPSEDTIME_INT 0x01
86
87#define RTC_FREQUENCY 32768
88#define MAX_PERIODIC_RATE 6553
89#define MAX_USER_PERIODIC_RATE 64
90
91static void __iomem *rtc1_base;
92static void __iomem *rtc2_base;
93
94#define rtc1_read(offset) readw(rtc1_base + (offset))
95#define rtc1_write(offset, value) writew((value), rtc1_base + (offset))
96
97#define rtc2_read(offset) readw(rtc2_base + (offset))
98#define rtc2_write(offset, value) writew((value), rtc2_base + (offset))
99
100static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
101
102static spinlock_t rtc_task_lock;
103static wait_queue_head_t rtc_wait;
104static unsigned long rtc_irq_data;
105static struct fasync_struct *rtc_async_queue;
106static rtc_task_t *rtc_callback;
107static char rtc_name[] = "RTC";
108static unsigned long periodic_frequency;
109static unsigned long periodic_count;
110
111typedef enum {
112 RTC_RELEASE,
113 RTC_OPEN,
114} rtc_status_t;
115
116static rtc_status_t rtc_status;
117
118typedef enum {
119 FUNCTION_RTC_IOCTL,
120 FUNCTION_RTC_CONTROL,
121} rtc_callfrom_t;
122
123struct resource rtc_resource[2] = {
124 { .name = rtc_name,
125 .flags = IORESOURCE_MEM, },
126 { .name = rtc_name,
127 .flags = IORESOURCE_MEM, },
128};
129
130static inline unsigned long read_elapsed_second(void)
131{
132 unsigned long first_low, first_mid, first_high;
133 unsigned long second_low, second_mid, second_high;
134
135 do {
136 first_low = rtc1_read(ETIMELREG);
137 first_mid = rtc1_read(ETIMEMREG);
138 first_high = rtc1_read(ETIMEHREG);
139 second_low = rtc1_read(ETIMELREG);
140 second_mid = rtc1_read(ETIMEMREG);
141 second_high = rtc1_read(ETIMEHREG);
142 } while (first_low != second_low || first_mid != second_mid ||
143 first_high != second_high);
144
145 return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
146}
147
148static inline void write_elapsed_second(unsigned long sec)
149{
150 spin_lock_irq(&rtc_lock);
151
152 rtc1_write(ETIMELREG, (uint16_t)(sec << 15));
153 rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1));
154 rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17));
155
156 spin_unlock_irq(&rtc_lock);
157}
158
159static void set_alarm(struct rtc_time *time)
160{
161 unsigned long alarm_sec;
162
163 alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
164 time->tm_hour, time->tm_min, time->tm_sec);
165
166 spin_lock_irq(&rtc_lock);
167
168 rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
169 rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
170 rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
171
172 spin_unlock_irq(&rtc_lock);
173}
174
175static void read_alarm(struct rtc_time *time)
176{
177 unsigned long low, mid, high;
178
179 spin_lock_irq(&rtc_lock);
180
181 low = rtc1_read(ECMPLREG);
182 mid = rtc1_read(ECMPMREG);
183 high = rtc1_read(ECMPHREG);
184
185 spin_unlock_irq(&rtc_lock);
186
187 to_tm((high << 17) | (mid << 1) | (low >> 15), time);
188 time->tm_year -= 1900;
189}
190
191static void read_time(struct rtc_time *time)
192{
193 unsigned long epoch_sec, elapsed_sec;
194
195 epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
196 elapsed_sec = read_elapsed_second();
197
198 to_tm(epoch_sec + elapsed_sec, time);
199 time->tm_year -= 1900;
200}
201
202static void set_time(struct rtc_time *time)
203{
204 unsigned long epoch_sec, current_sec;
205
206 epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
207 current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
208 time->tm_hour, time->tm_min, time->tm_sec);
209
210 write_elapsed_second(current_sec - epoch_sec);
211}
212
213static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
214{
215 DECLARE_WAITQUEUE(wait, current);
216 unsigned long irq_data;
217 int retval = 0;
218
219 if (count != sizeof(unsigned int) && count != sizeof(unsigned long))
220 return -EINVAL;
221
222 add_wait_queue(&rtc_wait, &wait);
223
224 do {
225 __set_current_state(TASK_INTERRUPTIBLE);
226
227 spin_lock_irq(&rtc_lock);
228 irq_data = rtc_irq_data;
229 rtc_irq_data = 0;
230 spin_unlock_irq(&rtc_lock);
231
232 if (irq_data != 0)
233 break;
234
235 if (file->f_flags & O_NONBLOCK) {
236 retval = -EAGAIN;
237 break;
238 }
239
240 if (signal_pending(current)) {
241 retval = -ERESTARTSYS;
242 break;
243 }
244 } while (1);
245
246 if (retval == 0) {
247 if (count == sizeof(unsigned int)) {
248 retval = put_user(irq_data, (unsigned int __user *)buf);
249 if (retval == 0)
250 retval = sizeof(unsigned int);
251 } else {
252 retval = put_user(irq_data, (unsigned long __user *)buf);
253 if (retval == 0)
254 retval = sizeof(unsigned long);
255 }
256
257 }
258
259 __set_current_state(TASK_RUNNING);
260 remove_wait_queue(&rtc_wait, &wait);
261
262 return retval;
263}
264
265static unsigned int rtc_poll(struct file *file, struct poll_table_struct *table)
266{
267 poll_wait(file, &rtc_wait, table);
268
269 if (rtc_irq_data != 0)
270 return POLLIN | POLLRDNORM;
271
272 return 0;
273}
274
275static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from)
276{
277 struct rtc_time time;
278 unsigned long count;
279
280 switch (cmd) {
281 case RTC_AIE_ON:
282 enable_irq(ELAPSEDTIME_IRQ);
283 break;
284 case RTC_AIE_OFF:
285 disable_irq(ELAPSEDTIME_IRQ);
286 break;
287 case RTC_PIE_ON:
288 enable_irq(RTCLONG1_IRQ);
289 break;
290 case RTC_PIE_OFF:
291 disable_irq(RTCLONG1_IRQ);
292 break;
293 case RTC_ALM_SET:
294 if (copy_from_user(&time, (struct rtc_time __user *)arg,
295 sizeof(struct rtc_time)))
296 return -EFAULT;
297
298 set_alarm(&time);
299 break;
300 case RTC_ALM_READ:
301 memset(&time, 0, sizeof(struct rtc_time));
302 read_alarm(&time);
303 break;
304 case RTC_RD_TIME:
305 memset(&time, 0, sizeof(struct rtc_time));
306 read_time(&time);
307 if (copy_to_user((void __user *)arg, &time, sizeof(struct rtc_time)))
308 return -EFAULT;
309 break;
310 case RTC_SET_TIME:
311 if (capable(CAP_SYS_TIME) == 0)
312 return -EACCES;
313
314 if (copy_from_user(&time, (struct rtc_time __user *)arg,
315 sizeof(struct rtc_time)))
316 return -EFAULT;
317
318 set_time(&time);
319 break;
320 case RTC_IRQP_READ:
321 return put_user(periodic_frequency, (unsigned long __user *)arg);
322 break;
323 case RTC_IRQP_SET:
324 if (arg > MAX_PERIODIC_RATE)
325 return -EINVAL;
326
327 if (from == FUNCTION_RTC_IOCTL && arg > MAX_USER_PERIODIC_RATE &&
328 capable(CAP_SYS_RESOURCE) == 0)
329 return -EACCES;
330
331 periodic_frequency = arg;
332
333 count = RTC_FREQUENCY;
334 do_div(count, arg);
335
336 periodic_count = count;
337
338 spin_lock_irq(&rtc_lock);
339
340 rtc1_write(RTCL1LREG, count);
341 rtc1_write(RTCL1HREG, count >> 16);
342
343 spin_unlock_irq(&rtc_lock);
344 break;
345 case RTC_EPOCH_READ:
346 return put_user(epoch, (unsigned long __user *)arg);
347 case RTC_EPOCH_SET:
348 /* Doesn't support before 1900 */
349 if (arg < 1900)
350 return -EINVAL;
351
352 if (capable(CAP_SYS_TIME) == 0)
353 return -EACCES;
354
355 epoch = arg;
356 break;
357 default:
358 return -EINVAL;
359 }
360
361 return 0;
362}
363
364static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
365 unsigned long arg)
366{
367 return rtc_do_ioctl(cmd, arg, FUNCTION_RTC_IOCTL);
368}
369
370static int rtc_open(struct inode *inode, struct file *file)
371{
372 spin_lock_irq(&rtc_lock);
373
374 if (rtc_status == RTC_OPEN) {
375 spin_unlock_irq(&rtc_lock);
376 return -EBUSY;
377 }
378
379 rtc_status = RTC_OPEN;
380 rtc_irq_data = 0;
381
382 spin_unlock_irq(&rtc_lock);
383
384 return 0;
385}
386
387static int rtc_release(struct inode *inode, struct file *file)
388{
389 if (file->f_flags & FASYNC)
390 (void)fasync_helper(-1, file, 0, &rtc_async_queue);
391
392 spin_lock_irq(&rtc_lock);
393
394 rtc1_write(ECMPLREG, 0);
395 rtc1_write(ECMPMREG, 0);
396 rtc1_write(ECMPHREG, 0);
397 rtc1_write(RTCL1LREG, 0);
398 rtc1_write(RTCL1HREG, 0);
399
400 rtc_status = RTC_RELEASE;
401
402 spin_unlock_irq(&rtc_lock);
403
404 disable_irq(ELAPSEDTIME_IRQ);
405 disable_irq(RTCLONG1_IRQ);
406
407 return 0;
408}
409
410static int rtc_fasync(int fd, struct file *file, int on)
411{
412 return fasync_helper(fd, file, on, &rtc_async_queue);
413}
414
415static struct file_operations rtc_fops = {
416 .owner = THIS_MODULE,
417 .llseek = no_llseek,
418 .read = rtc_read,
419 .poll = rtc_poll,
420 .ioctl = rtc_ioctl,
421 .open = rtc_open,
422 .release = rtc_release,
423 .fasync = rtc_fasync,
424};
425
426static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs)
427{
428 spin_lock(&rtc_lock);
429 rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
430
431 rtc_irq_data += 0x100;
432 rtc_irq_data &= ~0xff;
433 rtc_irq_data |= RTC_AF;
434 spin_unlock(&rtc_lock);
435
436 spin_lock(&rtc_lock);
437 if (rtc_callback)
438 rtc_callback->func(rtc_callback->private_data);
439 spin_unlock(&rtc_lock);
440
441 wake_up_interruptible(&rtc_wait);
442
443 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
444
445 return IRQ_HANDLED;
446}
447
448static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
449{
450 unsigned long count = periodic_count;
451
452 spin_lock(&rtc_lock);
453 rtc2_write(RTCINTREG, RTCLONG1_INT);
454
455 rtc1_write(RTCL1LREG, count);
456 rtc1_write(RTCL1HREG, count >> 16);
457
458 rtc_irq_data += 0x100;
459 rtc_irq_data &= ~0xff;
460 rtc_irq_data |= RTC_PF;
461 spin_unlock(&rtc_lock);
462
463 spin_lock(&rtc_task_lock);
464 if (rtc_callback)
465 rtc_callback->func(rtc_callback->private_data);
466 spin_unlock(&rtc_task_lock);
467
468 wake_up_interruptible(&rtc_wait);
469
470 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
471
472 return IRQ_HANDLED;
473}
474
475int rtc_register(rtc_task_t *task)
476{
477 if (task == NULL || task->func == NULL)
478 return -EINVAL;
479
480 spin_lock_irq(&rtc_lock);
481 if (rtc_status == RTC_OPEN) {
482 spin_unlock_irq(&rtc_lock);
483 return -EBUSY;
484 }
485
486 spin_lock(&rtc_task_lock);
487 if (rtc_callback != NULL) {
488 spin_unlock(&rtc_task_lock);
489 spin_unlock_irq(&rtc_task_lock);
490 return -EBUSY;
491 }
492
493 rtc_callback = task;
494 spin_unlock(&rtc_task_lock);
495
496 rtc_status = RTC_OPEN;
497
498 spin_unlock_irq(&rtc_lock);
499
500 return 0;
501}
502
503EXPORT_SYMBOL_GPL(rtc_register);
504
505int rtc_unregister(rtc_task_t *task)
506{
507 spin_lock_irq(&rtc_task_lock);
508 if (task == NULL || rtc_callback != task) {
509 spin_unlock_irq(&rtc_task_lock);
510 return -ENXIO;
511 }
512
513 spin_lock(&rtc_lock);
514
515 rtc1_write(ECMPLREG, 0);
516 rtc1_write(ECMPMREG, 0);
517 rtc1_write(ECMPHREG, 0);
518 rtc1_write(RTCL1LREG, 0);
519 rtc1_write(RTCL1HREG, 0);
520
521 rtc_status = RTC_RELEASE;
522
523 spin_unlock(&rtc_lock);
524
525 rtc_callback = NULL;
526
527 spin_unlock_irq(&rtc_task_lock);
528
529 disable_irq(ELAPSEDTIME_IRQ);
530 disable_irq(RTCLONG1_IRQ);
531
532 return 0;
533}
534
535EXPORT_SYMBOL_GPL(rtc_unregister);
536
537int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
538{
539 int retval = 0;
540
541 spin_lock_irq(&rtc_task_lock);
542
543 if (rtc_callback != task)
544 retval = -ENXIO;
545 else
546 rtc_do_ioctl(cmd, arg, FUNCTION_RTC_CONTROL);
547
548 spin_unlock_irq(&rtc_task_lock);
549
550 return retval;
551}
552
553EXPORT_SYMBOL_GPL(rtc_control);
554
555static struct miscdevice rtc_miscdevice = {
556 .minor = RTC_MINOR,
557 .name = rtc_name,
558 .fops = &rtc_fops,
559};
560
561static int __devinit rtc_probe(struct platform_device *pdev)
562{
563 unsigned int irq;
564 int retval;
565
566 if (pdev->num_resources != 2)
567 return -EBUSY;
568
569 rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE);
570 if (rtc1_base == NULL)
571 return -EBUSY;
572
573 rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE);
574 if (rtc2_base == NULL) {
575 iounmap(rtc1_base);
576 rtc1_base = NULL;
577 return -EBUSY;
578 }
579
580 retval = misc_register(&rtc_miscdevice);
581 if (retval < 0) {
582 iounmap(rtc1_base);
583 iounmap(rtc2_base);
584 rtc1_base = NULL;
585 rtc2_base = NULL;
586 return retval;
587 }
588
589 spin_lock_irq(&rtc_lock);
590
591 rtc1_write(ECMPLREG, 0);
592 rtc1_write(ECMPMREG, 0);
593 rtc1_write(ECMPHREG, 0);
594 rtc1_write(RTCL1LREG, 0);
595 rtc1_write(RTCL1HREG, 0);
596
597 rtc_status = RTC_RELEASE;
598 rtc_irq_data = 0;
599
600 spin_unlock_irq(&rtc_lock);
601
602 init_waitqueue_head(&rtc_wait);
603
604 irq = ELAPSEDTIME_IRQ;
605 retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT,
606 "elapsed_time", NULL);
607 if (retval == 0) {
608 irq = RTCLONG1_IRQ;
609 retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT,
610 "rtclong1", NULL);
611 }
612
613 if (retval < 0) {
614 printk(KERN_ERR "rtc: IRQ%d is busy\n", irq);
615 if (irq == RTCLONG1_IRQ)
616 free_irq(ELAPSEDTIME_IRQ, NULL);
617 iounmap(rtc1_base);
618 iounmap(rtc2_base);
619 rtc1_base = NULL;
620 rtc2_base = NULL;
621 return retval;
622 }
623
624 disable_irq(ELAPSEDTIME_IRQ);
625 disable_irq(RTCLONG1_IRQ);
626
627 spin_lock_init(&rtc_task_lock);
628
629 printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n");
630
631 return 0;
632}
633
634static int __devexit rtc_remove(struct platform_device *dev)
635{
636 int retval;
637
638 retval = misc_deregister(&rtc_miscdevice);
639 if (retval < 0)
640 return retval;
641
642 free_irq(ELAPSEDTIME_IRQ, NULL);
643 free_irq(RTCLONG1_IRQ, NULL);
644 if (rtc1_base != NULL)
645 iounmap(rtc1_base);
646 if (rtc2_base != NULL)
647 iounmap(rtc2_base);
648
649 return 0;
650}
651
652static struct platform_device *rtc_platform_device;
653
654static struct platform_driver rtc_device_driver = {
655 .probe = rtc_probe,
656 .remove = __devexit_p(rtc_remove),
657 .driver = {
658 .name = rtc_name,
659 .owner = THIS_MODULE,
660 },
661};
662
663static int __init vr41xx_rtc_init(void)
664{
665 int retval;
666
667 switch (current_cpu_data.cputype) {
668 case CPU_VR4111:
669 case CPU_VR4121:
670 rtc_resource[0].start = RTC1_TYPE1_START;
671 rtc_resource[0].end = RTC1_TYPE1_END;
672 rtc_resource[1].start = RTC2_TYPE1_START;
673 rtc_resource[1].end = RTC2_TYPE1_END;
674 break;
675 case CPU_VR4122:
676 case CPU_VR4131:
677 case CPU_VR4133:
678 rtc_resource[0].start = RTC1_TYPE2_START;
679 rtc_resource[0].end = RTC1_TYPE2_END;
680 rtc_resource[1].start = RTC2_TYPE2_START;
681 rtc_resource[1].end = RTC2_TYPE2_END;
682 break;
683 default:
684 return -ENODEV;
685 break;
686 }
687
688 rtc_platform_device = platform_device_alloc("RTC", -1);
689 if (!rtc_platform_device)
690 return -ENOMEM;
691
692 retval = platform_device_add_resources(rtc_platform_device,
693 rtc_resource, ARRAY_SIZE(rtc_resource));
694
695 if (retval == 0)
696 retval = platform_device_add(rtc_platform_device);
697
698 if (retval < 0) {
699 platform_device_put(rtc_platform_device);
700 return retval;
701 }
702
703 retval = platform_driver_register(&rtc_device_driver);
704 if (retval < 0)
705 platform_device_unregister(rtc_platform_device);
706
707 return retval;
708}
709
710static void __exit vr41xx_rtc_exit(void)
711{
712 platform_driver_unregister(&rtc_device_driver);
713 platform_device_unregister(rtc_platform_device);
714}
715
716module_init(vr41xx_rtc_init);
717module_exit(vr41xx_rtc_exit);