aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/agp.h4
-rw-r--r--drivers/char/agp/amd-k7-agp.c5
-rw-r--r--drivers/char/agp/amd64-agp.c9
-rw-r--r--drivers/char/agp/ati-agp.c36
-rw-r--r--drivers/char/agp/generic.c11
-rw-r--r--drivers/char/agp/intel-agp.c181
-rw-r--r--drivers/char/agp/sgi-agp.c9
-rw-r--r--drivers/char/agp/via-agp.c21
-rw-r--r--drivers/char/drm/drmP.h7
-rw-r--r--drivers/char/drm/drm_lock.c2
-rw-r--r--drivers/char/drm/drm_stub.c12
-rw-r--r--drivers/char/drm/drm_sysfs.c8
-rw-r--r--drivers/char/drm/i915_irq.c201
-rw-r--r--drivers/char/drm/r128_drm.h3
-rw-r--r--drivers/char/drm/r128_drv.h3
-rw-r--r--drivers/char/drm/r128_state.c3
-rw-r--r--drivers/char/drm/r300_cmdbuf.c32
-rw-r--r--drivers/char/drm/radeon_drv.h15
-rw-r--r--drivers/char/drm/radeon_irq.c4
-rw-r--r--drivers/char/drm/radeon_mem.c4
-rw-r--r--drivers/char/drm/radeon_state.c13
-rw-r--r--drivers/char/drm/savage_bci.c4
-rw-r--r--drivers/char/hw_random/amd-rng.c2
-rw-r--r--drivers/char/hw_random/geode-rng.c2
-rw-r--r--drivers/char/hw_random/intel-rng.c34
-rw-r--r--drivers/char/hw_random/ixp4xx-rng.c2
-rw-r--r--drivers/char/hw_random/via-rng.c2
-rw-r--r--drivers/char/ip2/i2ellis.h4
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c3
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c11
-rw-r--r--drivers/char/isicom.c103
-rw-r--r--drivers/char/mem.c4
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/mxser_new.c1
-rw-r--r--drivers/char/rtc.c7
-rw-r--r--drivers/char/sysrq.c20
-rw-r--r--drivers/char/tlclk.c45
-rw-r--r--drivers/char/viocons.c7
-rw-r--r--drivers/char/viotape.c5
-rw-r--r--drivers/char/vr41xx_giu.c114
40 files changed, 574 insertions, 380 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 8b3317fd46c9..1d59e2a5b9aa 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -225,6 +225,10 @@ struct agp_bridge_data {
225#define I810_GMS_DISABLE 0x00000000 225#define I810_GMS_DISABLE 0x00000000
226#define I810_PGETBL_CTL 0x2020 226#define I810_PGETBL_CTL 0x2020
227#define I810_PGETBL_ENABLED 0x00000001 227#define I810_PGETBL_ENABLED 0x00000001
228#define I965_PGETBL_SIZE_MASK 0x0000000e
229#define I965_PGETBL_SIZE_512KB (0 << 1)
230#define I965_PGETBL_SIZE_256KB (1 << 1)
231#define I965_PGETBL_SIZE_128KB (2 << 1)
228#define I810_DRAM_CTL 0x3000 232#define I810_DRAM_CTL 0x3000
229#define I810_DRAM_ROW_0 0x00000001 233#define I810_DRAM_ROW_0 0x00000001
230#define I810_DRAM_ROW_0_SDRAM 0x00000001 234#define I810_DRAM_ROW_0_SDRAM 0x00000001
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 51d0d562d01e..c85c8cadb6df 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -101,6 +101,11 @@ static int amd_create_gatt_pages(int nr_tables)
101 for (i = 0; i < nr_tables; i++) { 101 for (i = 0; i < nr_tables; i++) {
102 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); 102 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL);
103 if (entry == NULL) { 103 if (entry == NULL) {
104 while (i > 0) {
105 kfree(tables[i-1]);
106 i--;
107 }
108 kfree(tables);
104 retval = -ENOMEM; 109 retval = -ENOMEM;
105 break; 110 break;
106 } 111 }
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 2f2c4efff8a3..93d2209fee4c 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -650,6 +650,15 @@ static struct pci_device_id agp_amd64_pci_table[] = {
650 .subvendor = PCI_ANY_ID, 650 .subvendor = PCI_ANY_ID,
651 .subdevice = PCI_ANY_ID, 651 .subdevice = PCI_ANY_ID,
652 }, 652 },
653 /* VIA K8M890 / K8N890 */
654 {
655 .class = (PCI_CLASS_BRIDGE_HOST << 8),
656 .class_mask = ~0,
657 .vendor = PCI_VENDOR_ID_VIA,
658 .device = PCI_DEVICE_ID_VIA_VT3336,
659 .subvendor = PCI_ANY_ID,
660 .subdevice = PCI_ANY_ID,
661 },
653 /* VIA K8T890 */ 662 /* VIA K8T890 */
654 { 663 {
655 .class = (PCI_CLASS_BRIDGE_HOST << 8), 664 .class = (PCI_CLASS_BRIDGE_HOST << 8),
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index f244c6682738..9987dc2e0c3f 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -41,18 +41,18 @@ static struct gatt_mask ati_generic_masks[] =
41}; 41};
42 42
43 43
44typedef struct _ati_page_map { 44struct ati_page_map {
45 unsigned long *real; 45 unsigned long *real;
46 unsigned long __iomem *remapped; 46 unsigned long __iomem *remapped;
47} ati_page_map; 47};
48 48
49static struct _ati_generic_private { 49static struct _ati_generic_private {
50 volatile u8 __iomem *registers; 50 volatile u8 __iomem *registers;
51 ati_page_map **gatt_pages; 51 struct ati_page_map **gatt_pages;
52 int num_tables; 52 int num_tables;
53} ati_generic_private; 53} ati_generic_private;
54 54
55static int ati_create_page_map(ati_page_map *page_map) 55static int ati_create_page_map(struct ati_page_map *page_map)
56{ 56{
57 int i, err = 0; 57 int i, err = 0;
58 58
@@ -82,7 +82,7 @@ static int ati_create_page_map(ati_page_map *page_map)
82} 82}
83 83
84 84
85static void ati_free_page_map(ati_page_map *page_map) 85static void ati_free_page_map(struct ati_page_map *page_map)
86{ 86{
87 unmap_page_from_agp(virt_to_page(page_map->real)); 87 unmap_page_from_agp(virt_to_page(page_map->real));
88 iounmap(page_map->remapped); 88 iounmap(page_map->remapped);
@@ -94,8 +94,8 @@ static void ati_free_page_map(ati_page_map *page_map)
94static void ati_free_gatt_pages(void) 94static void ati_free_gatt_pages(void)
95{ 95{
96 int i; 96 int i;
97 ati_page_map **tables; 97 struct ati_page_map **tables;
98 ati_page_map *entry; 98 struct ati_page_map *entry;
99 99
100 tables = ati_generic_private.gatt_pages; 100 tables = ati_generic_private.gatt_pages;
101 for (i = 0; i < ati_generic_private.num_tables; i++) { 101 for (i = 0; i < ati_generic_private.num_tables; i++) {
@@ -112,30 +112,30 @@ static void ati_free_gatt_pages(void)
112 112
113static int ati_create_gatt_pages(int nr_tables) 113static int ati_create_gatt_pages(int nr_tables)
114{ 114{
115 ati_page_map **tables; 115 struct ati_page_map **tables;
116 ati_page_map *entry; 116 struct ati_page_map *entry;
117 int retval = 0; 117 int retval = 0;
118 int i; 118 int i;
119 119
120 tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL); 120 tables = kzalloc((nr_tables + 1) * sizeof(struct ati_page_map *),GFP_KERNEL);
121 if (tables == NULL) 121 if (tables == NULL)
122 return -ENOMEM; 122 return -ENOMEM;
123 123
124 for (i = 0; i < nr_tables; i++) { 124 for (i = 0; i < nr_tables; i++) {
125 entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL); 125 entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL);
126 if (entry == NULL) { 126 if (entry == NULL) {
127 while (i>0) { 127 while (i > 0) {
128 kfree (tables[i-1]); 128 kfree(tables[i-1]);
129 i--; 129 i--;
130 } 130 }
131 kfree (tables); 131 kfree(tables);
132 tables = NULL;
133 retval = -ENOMEM; 132 retval = -ENOMEM;
134 break; 133 break;
135 } 134 }
136 tables[i] = entry; 135 tables[i] = entry;
137 retval = ati_create_page_map(entry); 136 retval = ati_create_page_map(entry);
138 if (retval != 0) break; 137 if (retval != 0)
138 break;
139 } 139 }
140 ati_generic_private.num_tables = nr_tables; 140 ati_generic_private.num_tables = nr_tables;
141 ati_generic_private.gatt_pages = tables; 141 ati_generic_private.gatt_pages = tables;
@@ -340,7 +340,7 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start,
340static int ati_create_gatt_table(struct agp_bridge_data *bridge) 340static int ati_create_gatt_table(struct agp_bridge_data *bridge)
341{ 341{
342 struct aper_size_info_lvl2 *value; 342 struct aper_size_info_lvl2 *value;
343 ati_page_map page_dir; 343 struct ati_page_map page_dir;
344 unsigned long addr; 344 unsigned long addr;
345 int retval; 345 int retval;
346 u32 temp; 346 u32 temp;
@@ -400,7 +400,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
400 400
401static int ati_free_gatt_table(struct agp_bridge_data *bridge) 401static int ati_free_gatt_table(struct agp_bridge_data *bridge)
402{ 402{
403 ati_page_map page_dir; 403 struct ati_page_map page_dir;
404 404
405 page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; 405 page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
406 page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table; 406 page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 883a36a27833..3491d6f84bc6 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -965,6 +965,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
965 if (!bridge) 965 if (!bridge)
966 return -EINVAL; 966 return -EINVAL;
967 967
968 if (mem->page_count == 0)
969 return 0;
970
968 temp = bridge->current_size; 971 temp = bridge->current_size;
969 972
970 switch (bridge->driver->size_type) { 973 switch (bridge->driver->size_type) {
@@ -1016,8 +1019,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
1016 1019
1017 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 1020 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1018 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j); 1021 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j);
1019 readl(bridge->gatt_table+j); /* PCI Posting. */
1020 } 1022 }
1023 readl(bridge->gatt_table+j-1); /* PCI Posting. */
1021 1024
1022 bridge->driver->tlb_flush(mem); 1025 bridge->driver->tlb_flush(mem);
1023 return 0; 1026 return 0;
@@ -1034,6 +1037,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1034 if (!bridge) 1037 if (!bridge)
1035 return -EINVAL; 1038 return -EINVAL;
1036 1039
1040 if (mem->page_count == 0)
1041 return 0;
1042
1037 if (type != 0 || mem->type != 0) { 1043 if (type != 0 || mem->type != 0) {
1038 /* The generic routines know nothing of memory types */ 1044 /* The generic routines know nothing of memory types */
1039 return -EINVAL; 1045 return -EINVAL;
@@ -1042,10 +1048,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1042 /* AK: bogus, should encode addresses > 4GB */ 1048 /* AK: bogus, should encode addresses > 4GB */
1043 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 1049 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1044 writel(bridge->scratch_page, bridge->gatt_table+i); 1050 writel(bridge->scratch_page, bridge->gatt_table+i);
1045 readl(bridge->gatt_table+i); /* PCI Posting. */
1046 } 1051 }
1052 readl(bridge->gatt_table+i-1); /* PCI Posting. */
1047 1053
1048 global_cache_flush();
1049 bridge->driver->tlb_flush(mem); 1054 bridge->driver->tlb_flush(mem);
1050 return 0; 1055 return 0;
1051} 1056}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 555b3a8ab49c..a3011de51f7c 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -207,6 +207,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
207 int i, j, num_entries; 207 int i, j, num_entries;
208 void *temp; 208 void *temp;
209 209
210 if (mem->page_count == 0)
211 return 0;
212
210 temp = agp_bridge->current_size; 213 temp = agp_bridge->current_size;
211 num_entries = A_SIZE_FIX(temp)->num_entries; 214 num_entries = A_SIZE_FIX(temp)->num_entries;
212 215
@@ -221,12 +224,16 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
221 if (type != 0 || mem->type != 0) { 224 if (type != 0 || mem->type != 0) {
222 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) { 225 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) {
223 /* special insert */ 226 /* special insert */
224 global_cache_flush(); 227 if (!mem->is_flushed) {
228 global_cache_flush();
229 mem->is_flushed = TRUE;
230 }
231
225 for (i = pg_start; i < (pg_start + mem->page_count); i++) { 232 for (i = pg_start; i < (pg_start + mem->page_count); i++) {
226 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, intel_i810_private.registers+I810_PTE_BASE+(i*4)); 233 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, intel_i810_private.registers+I810_PTE_BASE+(i*4));
227 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
228 } 234 }
229 global_cache_flush(); 235 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */
236
230 agp_bridge->driver->tlb_flush(mem); 237 agp_bridge->driver->tlb_flush(mem);
231 return 0; 238 return 0;
232 } 239 }
@@ -236,14 +243,17 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
236 } 243 }
237 244
238insert: 245insert:
239 global_cache_flush(); 246 if (!mem->is_flushed) {
247 global_cache_flush();
248 mem->is_flushed = TRUE;
249 }
250
240 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 251 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
241 writel(agp_bridge->driver->mask_memory(agp_bridge, 252 writel(agp_bridge->driver->mask_memory(agp_bridge,
242 mem->memory[i], mem->type), 253 mem->memory[i], mem->type),
243 intel_i810_private.registers+I810_PTE_BASE+(j*4)); 254 intel_i810_private.registers+I810_PTE_BASE+(j*4));
244 readl(intel_i810_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
245 } 255 }
246 global_cache_flush(); 256 readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4)); /* PCI Posting. */
247 257
248 agp_bridge->driver->tlb_flush(mem); 258 agp_bridge->driver->tlb_flush(mem);
249 return 0; 259 return 0;
@@ -254,12 +264,14 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
254{ 264{
255 int i; 265 int i;
256 266
267 if (mem->page_count == 0)
268 return 0;
269
257 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 270 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
258 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4)); 271 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
259 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
260 } 272 }
273 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
261 274
262 global_cache_flush();
263 agp_bridge->driver->tlb_flush(mem); 275 agp_bridge->driver->tlb_flush(mem);
264 return 0; 276 return 0;
265} 277}
@@ -370,6 +382,11 @@ static struct _intel_i830_private {
370 struct pci_dev *i830_dev; /* device one */ 382 struct pci_dev *i830_dev; /* device one */
371 volatile u8 __iomem *registers; 383 volatile u8 __iomem *registers;
372 volatile u32 __iomem *gtt; /* I915G */ 384 volatile u32 __iomem *gtt; /* I915G */
385 /* gtt_entries is the number of gtt entries that are already mapped
386 * to stolen memory. Stolen memory is larger than the memory mapped
387 * through gtt_entries, as it includes some reserved space for the BIOS
388 * popup and for the GTT.
389 */
373 int gtt_entries; 390 int gtt_entries;
374} intel_i830_private; 391} intel_i830_private;
375 392
@@ -380,14 +397,41 @@ static void intel_i830_init_gtt_entries(void)
380 u8 rdct; 397 u8 rdct;
381 int local = 0; 398 int local = 0;
382 static const int ddt[4] = { 0, 16, 32, 64 }; 399 static const int ddt[4] = { 0, 16, 32, 64 };
383 int size; 400 int size; /* reserved space (in kb) at the top of stolen memory */
384 401
385 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 402 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
386 403
387 /* We obtain the size of the GTT, which is also stored (for some 404 if (IS_I965) {
388 * reason) at the top of stolen memory. Then we add 4KB to that 405 u32 pgetbl_ctl;
389 * for the video BIOS popup, which is also stored in there. */ 406
390 size = agp_bridge->driver->fetch_size() + 4; 407 pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
408 &pgetbl_ctl);
409 /* The 965 has a field telling us the size of the GTT,
410 * which may be larger than what is necessary to map the
411 * aperture.
412 */
413 switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
414 case I965_PGETBL_SIZE_128KB:
415 size = 128;
416 break;
417 case I965_PGETBL_SIZE_256KB:
418 size = 256;
419 break;
420 case I965_PGETBL_SIZE_512KB:
421 size = 512;
422 break;
423 default:
424 printk(KERN_INFO PFX "Unknown page table size, "
425 "assuming 512KB\n");
426 size = 512;
427 }
428 size += 4; /* add in BIOS popup space */
429 } else {
430 /* On previous hardware, the GTT size was just what was
431 * required to map the aperture.
432 */
433 size = agp_bridge->driver->fetch_size() + 4;
434 }
391 435
392 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || 436 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
393 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { 437 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
@@ -576,6 +620,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
576 int i,j,num_entries; 620 int i,j,num_entries;
577 void *temp; 621 void *temp;
578 622
623 if (mem->page_count == 0)
624 return 0;
625
579 temp = agp_bridge->current_size; 626 temp = agp_bridge->current_size;
580 num_entries = A_SIZE_FIX(temp)->num_entries; 627 num_entries = A_SIZE_FIX(temp)->num_entries;
581 628
@@ -598,16 +645,18 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
598 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 645 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
599 return -EINVAL; 646 return -EINVAL;
600 647
601 global_cache_flush(); /* FIXME: Necessary ?*/ 648 if (!mem->is_flushed) {
649 global_cache_flush();
650 mem->is_flushed = TRUE;
651 }
602 652
603 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 653 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
604 writel(agp_bridge->driver->mask_memory(agp_bridge, 654 writel(agp_bridge->driver->mask_memory(agp_bridge,
605 mem->memory[i], mem->type), 655 mem->memory[i], mem->type),
606 intel_i830_private.registers+I810_PTE_BASE+(j*4)); 656 intel_i830_private.registers+I810_PTE_BASE+(j*4));
607 readl(intel_i830_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
608 } 657 }
658 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
609 659
610 global_cache_flush();
611 agp_bridge->driver->tlb_flush(mem); 660 agp_bridge->driver->tlb_flush(mem);
612 return 0; 661 return 0;
613} 662}
@@ -617,7 +666,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
617{ 666{
618 int i; 667 int i;
619 668
620 global_cache_flush(); 669 if (mem->page_count == 0)
670 return 0;
621 671
622 if (pg_start < intel_i830_private.gtt_entries) { 672 if (pg_start < intel_i830_private.gtt_entries) {
623 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 673 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -626,10 +676,9 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
626 676
627 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 677 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
628 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4)); 678 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
629 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
630 } 679 }
680 readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
631 681
632 global_cache_flush();
633 agp_bridge->driver->tlb_flush(mem); 682 agp_bridge->driver->tlb_flush(mem);
634 return 0; 683 return 0;
635} 684}
@@ -686,6 +735,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
686 int i,j,num_entries; 735 int i,j,num_entries;
687 void *temp; 736 void *temp;
688 737
738 if (mem->page_count == 0)
739 return 0;
740
689 temp = agp_bridge->current_size; 741 temp = agp_bridge->current_size;
690 num_entries = A_SIZE_FIX(temp)->num_entries; 742 num_entries = A_SIZE_FIX(temp)->num_entries;
691 743
@@ -708,15 +760,17 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
708 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 760 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
709 return -EINVAL; 761 return -EINVAL;
710 762
711 global_cache_flush(); 763 if (!mem->is_flushed) {
764 global_cache_flush();
765 mem->is_flushed = TRUE;
766 }
712 767
713 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 768 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
714 writel(agp_bridge->driver->mask_memory(agp_bridge, 769 writel(agp_bridge->driver->mask_memory(agp_bridge,
715 mem->memory[i], mem->type), intel_i830_private.gtt+j); 770 mem->memory[i], mem->type), intel_i830_private.gtt+j);
716 readl(intel_i830_private.gtt+j); /* PCI Posting. */
717 } 771 }
772 readl(intel_i830_private.gtt+j-1);
718 773
719 global_cache_flush();
720 agp_bridge->driver->tlb_flush(mem); 774 agp_bridge->driver->tlb_flush(mem);
721 return 0; 775 return 0;
722} 776}
@@ -726,7 +780,8 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
726{ 780{
727 int i; 781 int i;
728 782
729 global_cache_flush(); 783 if (mem->page_count == 0)
784 return 0;
730 785
731 if (pg_start < intel_i830_private.gtt_entries) { 786 if (pg_start < intel_i830_private.gtt_entries) {
732 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 787 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -735,30 +790,34 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
735 790
736 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 791 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
737 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i); 792 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
738 readl(intel_i830_private.gtt+i);
739 } 793 }
794 readl(intel_i830_private.gtt+i-1);
740 795
741 global_cache_flush();
742 agp_bridge->driver->tlb_flush(mem); 796 agp_bridge->driver->tlb_flush(mem);
743 return 0; 797 return 0;
744} 798}
745 799
746static int intel_i915_fetch_size(void) 800/* Return the aperture size by just checking the resource length. The effect
801 * described in the spec of the MSAC registers is just changing of the
802 * resource size.
803 */
804static int intel_i9xx_fetch_size(void)
747{ 805{
748 struct aper_size_info_fixed *values; 806 int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
749 u32 temp, offset; 807 int aper_size; /* size in megabytes */
808 int i;
750 809
751#define I915_256MB_ADDRESS_MASK (1<<27) 810 aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
752 811
753 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); 812 for (i = 0; i < num_sizes; i++) {
813 if (aper_size == intel_i830_sizes[i].size) {
814 agp_bridge->current_size = intel_i830_sizes + i;
815 agp_bridge->previous_size = agp_bridge->current_size;
816 return aper_size;
817 }
818 }
754 819
755 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp); 820 return 0;
756 if (temp & I915_256MB_ADDRESS_MASK)
757 offset = 0; /* 128MB aperture */
758 else
759 offset = 2; /* 256MB aperture */
760 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
761 return values[offset].size;
762} 821}
763 822
764/* The intel i915 automatically initializes the agp aperture during POST. 823/* The intel i915 automatically initializes the agp aperture during POST.
@@ -821,40 +880,9 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
821 return addr | bridge->driver->masks[type].mask; 880 return addr | bridge->driver->masks[type].mask;
822} 881}
823 882
824static int intel_i965_fetch_size(void)
825{
826 struct aper_size_info_fixed *values;
827 u32 offset = 0;
828 u8 temp;
829
830#define I965_512MB_ADDRESS_MASK (3<<1)
831
832 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
833
834 pci_read_config_byte(intel_i830_private.i830_dev, I965_MSAC, &temp);
835 temp &= I965_512MB_ADDRESS_MASK;
836 switch (temp) {
837 case 0x00:
838 offset = 0; /* 128MB */
839 break;
840 case 0x06:
841 offset = 3; /* 512MB */
842 break;
843 default:
844 case 0x02:
845 offset = 2; /* 256MB */
846 break;
847 }
848
849 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
850
851 /* The i965 GTT is always sized as if it had a 512kB aperture size */
852 return 512;
853}
854
855/* The intel i965 automatically initializes the agp aperture during POST. 883/* The intel i965 automatically initializes the agp aperture during POST.
856+ * Use the memory already set aside for in the GTT. 884 * Use the memory already set aside for in the GTT.
857+ */ 885 */
858static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) 886static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
859{ 887{
860 int page_order; 888 int page_order;
@@ -1574,7 +1602,7 @@ static struct agp_bridge_driver intel_915_driver = {
1574 .num_aperture_sizes = 4, 1602 .num_aperture_sizes = 4,
1575 .needs_scratch_page = TRUE, 1603 .needs_scratch_page = TRUE,
1576 .configure = intel_i915_configure, 1604 .configure = intel_i915_configure,
1577 .fetch_size = intel_i915_fetch_size, 1605 .fetch_size = intel_i9xx_fetch_size,
1578 .cleanup = intel_i915_cleanup, 1606 .cleanup = intel_i915_cleanup,
1579 .tlb_flush = intel_i810_tlbflush, 1607 .tlb_flush = intel_i810_tlbflush,
1580 .mask_memory = intel_i810_mask_memory, 1608 .mask_memory = intel_i810_mask_memory,
@@ -1598,7 +1626,7 @@ static struct agp_bridge_driver intel_i965_driver = {
1598 .num_aperture_sizes = 4, 1626 .num_aperture_sizes = 4,
1599 .needs_scratch_page = TRUE, 1627 .needs_scratch_page = TRUE,
1600 .configure = intel_i915_configure, 1628 .configure = intel_i915_configure,
1601 .fetch_size = intel_i965_fetch_size, 1629 .fetch_size = intel_i9xx_fetch_size,
1602 .cleanup = intel_i915_cleanup, 1630 .cleanup = intel_i915_cleanup,
1603 .tlb_flush = intel_i810_tlbflush, 1631 .tlb_flush = intel_i810_tlbflush,
1604 .mask_memory = intel_i965_mask_memory, 1632 .mask_memory = intel_i965_mask_memory,
@@ -1927,6 +1955,15 @@ static int agp_intel_resume(struct pci_dev *pdev)
1927 1955
1928 pci_restore_state(pdev); 1956 pci_restore_state(pdev);
1929 1957
1958 /* We should restore our graphics device's config space,
1959 * as host bridge (00:00) resumes before graphics device (02:00),
1960 * then our access to its pci space can work right.
1961 */
1962 if (intel_i810_private.i810_dev)
1963 pci_restore_state(intel_i810_private.i810_dev);
1964 if (intel_i830_private.i830_dev)
1965 pci_restore_state(intel_i830_private.i830_dev);
1966
1930 if (bridge->driver == &intel_generic_driver) 1967 if (bridge->driver == &intel_generic_driver)
1931 intel_configure(); 1968 intel_configure();
1932 else if (bridge->driver == &intel_850_driver) 1969 else if (bridge->driver == &intel_850_driver)
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index d73be4c2db8a..902648db7efa 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -281,10 +281,11 @@ static int __devinit agp_sgi_init(void)
281 else 281 else
282 return 0; 282 return 0;
283 283
284 sgi_tioca_agp_bridges = 284 sgi_tioca_agp_bridges = kmalloc(tioca_gart_found *
285 (struct agp_bridge_data **)kmalloc(tioca_gart_found * 285 sizeof(struct agp_bridge_data *),
286 sizeof(struct agp_bridge_data *), 286 GFP_KERNEL);
287 GFP_KERNEL); 287 if (!sgi_tioca_agp_bridges)
288 return -ENOMEM;
288 289
289 j = 0; 290 j = 0;
290 list_for_each_entry(info, &tioca_list, ca_list) { 291 list_for_each_entry(info, &tioca_list, ca_list) {
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index c149ac9ce9a7..2ded7a280d7f 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -380,9 +380,23 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
380 /* P4M800CE */ 380 /* P4M800CE */
381 { 381 {
382 .device_id = PCI_DEVICE_ID_VIA_P4M800CE, 382 .device_id = PCI_DEVICE_ID_VIA_P4M800CE,
383 .chipset_name = "P4M800CE", 383 .chipset_name = "VT3314",
384 },
385 /* CX700 */
386 {
387 .device_id = PCI_DEVICE_ID_VIA_CX700,
388 .chipset_name = "CX700",
389 },
390 /* VT3336 */
391 {
392 .device_id = PCI_DEVICE_ID_VIA_VT3336,
393 .chipset_name = "VT3336",
394 },
395 /* P4M890 */
396 {
397 .device_id = PCI_DEVICE_ID_VIA_P4M890,
398 .chipset_name = "P4M890",
384 }, 399 },
385
386 { }, /* dummy final entry, always present */ 400 { }, /* dummy final entry, always present */
387}; 401};
388 402
@@ -524,6 +538,9 @@ static const struct pci_device_id agp_via_pci_table[] = {
524 ID(PCI_DEVICE_ID_VIA_83_87XX_1), 538 ID(PCI_DEVICE_ID_VIA_83_87XX_1),
525 ID(PCI_DEVICE_ID_VIA_3296_0), 539 ID(PCI_DEVICE_ID_VIA_3296_0),
526 ID(PCI_DEVICE_ID_VIA_P4M800CE), 540 ID(PCI_DEVICE_ID_VIA_P4M800CE),
541 ID(PCI_DEVICE_ID_VIA_CX700),
542 ID(PCI_DEVICE_ID_VIA_VT3336),
543 ID(PCI_DEVICE_ID_VIA_P4M890),
527 { } 544 { }
528}; 545};
529 546
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 0bbb04f2390f..6dcdceb81203 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -561,8 +561,7 @@ struct drm_driver {
561 int (*context_dtor) (struct drm_device * dev, int context); 561 int (*context_dtor) (struct drm_device * dev, int context);
562 int (*kernel_context_switch) (struct drm_device * dev, int old, 562 int (*kernel_context_switch) (struct drm_device * dev, int old,
563 int new); 563 int new);
564 void (*kernel_context_switch_unlock) (struct drm_device * dev, 564 void (*kernel_context_switch_unlock) (struct drm_device * dev);
565 drm_lock_t *lock);
566 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); 565 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
567 int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence); 566 int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence);
568 int (*dri_library_name) (struct drm_device *dev, char *buf); 567 int (*dri_library_name) (struct drm_device *dev, char *buf);
@@ -1143,9 +1142,5 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
1143extern unsigned long drm_core_get_map_ofs(drm_map_t * map); 1142extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
1144extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); 1143extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
1145 1144
1146#ifndef pci_pretty_name
1147#define pci_pretty_name(dev) ""
1148#endif
1149
1150#endif /* __KERNEL__ */ 1145#endif /* __KERNEL__ */
1151#endif 1146#endif
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index 116ed0f2ac09..e9993ba461a2 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -182,7 +182,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
182 * modules but is required by the Sparc driver. 182 * modules but is required by the Sparc driver.
183 */ 183 */
184 if (dev->driver->kernel_context_switch_unlock) 184 if (dev->driver->kernel_context_switch_unlock)
185 dev->driver->kernel_context_switch_unlock(dev, &lock); 185 dev->driver->kernel_context_switch_unlock(dev);
186 else { 186 else {
187 drm_lock_transfer(dev, &dev->lock.hw_lock->lock, 187 drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
188 DRM_KERNEL_CONTEXT); 188 DRM_KERNEL_CONTEXT);
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 5fd6dc0870cf..120d10256feb 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -211,14 +211,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
211 if (!dev) 211 if (!dev)
212 return -ENOMEM; 212 return -ENOMEM;
213 213
214 pci_enable_device(pdev); 214 ret = pci_enable_device(pdev);
215 if (ret)
216 goto err_g1;
215 217
216 if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { 218 if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
217 printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); 219 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
218 goto err_g1; 220 goto err_g2;
219 } 221 }
220 if ((ret = drm_get_head(dev, &dev->primary))) 222 if ((ret = drm_get_head(dev, &dev->primary)))
221 goto err_g1; 223 goto err_g2;
222 224
223 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", 225 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
224 driver->name, driver->major, driver->minor, driver->patchlevel, 226 driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -226,7 +228,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
226 228
227 return 0; 229 return 0;
228 230
229 err_g1: 231err_g2:
232 pci_disable_device(pdev);
233err_g1:
230 drm_free(dev, sizeof(*dev), DRM_MEM_STUB); 234 drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
231 return ret; 235 return ret;
232} 236}
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index ba4b8de83cf0..cc8e2ebe128c 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -45,8 +45,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
45 int err; 45 int err;
46 46
47 class = class_create(owner, name); 47 class = class_create(owner, name);
48 if (!class) { 48 if (IS_ERR(class)) {
49 err = -ENOMEM; 49 err = PTR_ERR(class);
50 goto err_out; 50 goto err_out;
51 } 51 }
52 52
@@ -113,8 +113,8 @@ struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
113 MKDEV(DRM_MAJOR, head->minor), 113 MKDEV(DRM_MAJOR, head->minor),
114 &(head->dev->pdev)->dev, 114 &(head->dev->pdev)->dev,
115 "card%d", head->minor); 115 "card%d", head->minor);
116 if (!class_dev) { 116 if (IS_ERR(class_dev)) {
117 err = -ENOMEM; 117 err = PTR_ERR(class_dev);
118 goto err_out; 118 goto err_out;
119 } 119 }
120 120
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index e5463b111fc0..78c1ae28f17c 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -46,88 +46,167 @@ static void i915_vblank_tasklet(drm_device_t *dev)
46{ 46{
47 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 47 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
48 unsigned long irqflags; 48 unsigned long irqflags;
49 struct list_head *list, *tmp; 49 struct list_head *list, *tmp, hits, *hit;
50 int nhits, nrects, slice[2], upper[2], lower[2], i;
51 unsigned counter[2] = { atomic_read(&dev->vbl_received),
52 atomic_read(&dev->vbl_received2) };
53 drm_drawable_info_t *drw;
54 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
55 u32 cpp = dev_priv->cpp;
56 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
57 XY_SRC_COPY_BLT_WRITE_ALPHA |
58 XY_SRC_COPY_BLT_WRITE_RGB)
59 : XY_SRC_COPY_BLT_CMD;
60 u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
61 (cpp << 23) | (1 << 24);
62 RING_LOCALS;
50 63
51 DRM_DEBUG("\n"); 64 DRM_DEBUG("\n");
52 65
66 INIT_LIST_HEAD(&hits);
67
68 nhits = nrects = 0;
69
53 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 70 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
54 71
72 /* Find buffer swaps scheduled for this vertical blank */
55 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { 73 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
56 drm_i915_vbl_swap_t *vbl_swap = 74 drm_i915_vbl_swap_t *vbl_swap =
57 list_entry(list, drm_i915_vbl_swap_t, head); 75 list_entry(list, drm_i915_vbl_swap_t, head);
58 atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 :
59 &dev->vbl_received;
60
61 if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) {
62 drm_drawable_info_t *drw;
63
64 spin_unlock(&dev_priv->swaps_lock);
65
66 spin_lock(&dev->drw_lock);
67
68 drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
69
70 if (drw) {
71 int i, num_rects = drw->num_rects;
72 drm_clip_rect_t *rect = drw->rects;
73 drm_i915_sarea_t *sarea_priv =
74 dev_priv->sarea_priv;
75 u32 cpp = dev_priv->cpp;
76 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
77 XY_SRC_COPY_BLT_WRITE_ALPHA |
78 XY_SRC_COPY_BLT_WRITE_RGB)
79 : XY_SRC_COPY_BLT_CMD;
80 u32 pitchropcpp = (sarea_priv->pitch * cpp) |
81 (0xcc << 16) | (cpp << 23) |
82 (1 << 24);
83 RING_LOCALS;
84
85 i915_kernel_lost_context(dev);
86
87 BEGIN_LP_RING(6);
88
89 OUT_RING(GFX_OP_DRAWRECT_INFO);
90 OUT_RING(0);
91 OUT_RING(0);
92 OUT_RING(sarea_priv->width |
93 sarea_priv->height << 16);
94 OUT_RING(sarea_priv->width |
95 sarea_priv->height << 16);
96 OUT_RING(0);
97 76
98 ADVANCE_LP_RING(); 77 if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
78 continue;
79
80 list_del(list);
81 dev_priv->swaps_pending--;
99 82
100 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; 83 spin_unlock(&dev_priv->swaps_lock);
84 spin_lock(&dev->drw_lock);
101 85
102 for (i = 0; i < num_rects; i++, rect++) { 86 drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
103 BEGIN_LP_RING(8); 87
88 if (!drw) {
89 spin_unlock(&dev->drw_lock);
90 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
91 spin_lock(&dev_priv->swaps_lock);
92 continue;
93 }
104 94
105 OUT_RING(cmd); 95 list_for_each(hit, &hits) {
106 OUT_RING(pitchropcpp); 96 drm_i915_vbl_swap_t *swap_cmp =
107 OUT_RING((rect->y1 << 16) | rect->x1); 97 list_entry(hit, drm_i915_vbl_swap_t, head);
108 OUT_RING((rect->y2 << 16) | rect->x2); 98 drm_drawable_info_t *drw_cmp =
109 OUT_RING(sarea_priv->front_offset); 99 drm_get_drawable_info(dev, swap_cmp->drw_id);
110 OUT_RING((rect->y1 << 16) | rect->x1);
111 OUT_RING(pitchropcpp & 0xffff);
112 OUT_RING(sarea_priv->back_offset);
113 100
114 ADVANCE_LP_RING(); 101 if (drw_cmp &&
115 } 102 drw_cmp->rects[0].y1 > drw->rects[0].y1) {
103 list_add_tail(list, hit);
104 break;
116 } 105 }
106 }
117 107
118 spin_unlock(&dev->drw_lock); 108 spin_unlock(&dev->drw_lock);
119 109
120 spin_lock(&dev_priv->swaps_lock); 110 /* List of hits was empty, or we reached the end of it */
111 if (hit == &hits)
112 list_add_tail(list, hits.prev);
121 113
122 list_del(list); 114 nhits++;
123 115
124 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); 116 spin_lock(&dev_priv->swaps_lock);
117 }
118
119 if (nhits == 0) {
120 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
121 return;
122 }
123
124 spin_unlock(&dev_priv->swaps_lock);
125 125
126 dev_priv->swaps_pending--; 126 i915_kernel_lost_context(dev);
127
128 BEGIN_LP_RING(6);
129
130 OUT_RING(GFX_OP_DRAWRECT_INFO);
131 OUT_RING(0);
132 OUT_RING(0);
133 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
134 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
135 OUT_RING(0);
136
137 ADVANCE_LP_RING();
138
139 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
140
141 upper[0] = upper[1] = 0;
142 slice[0] = max(sarea_priv->pipeA_h / nhits, 1);
143 slice[1] = max(sarea_priv->pipeB_h / nhits, 1);
144 lower[0] = sarea_priv->pipeA_y + slice[0];
145 lower[1] = sarea_priv->pipeB_y + slice[0];
146
147 spin_lock(&dev->drw_lock);
148
149 /* Emit blits for buffer swaps, partitioning both outputs into as many
150 * slices as there are buffer swaps scheduled in order to avoid tearing
151 * (based on the assumption that a single buffer swap would always
152 * complete before scanout starts).
153 */
154 for (i = 0; i++ < nhits;
155 upper[0] = lower[0], lower[0] += slice[0],
156 upper[1] = lower[1], lower[1] += slice[1]) {
157 if (i == nhits)
158 lower[0] = lower[1] = sarea_priv->height;
159
160 list_for_each(hit, &hits) {
161 drm_i915_vbl_swap_t *swap_hit =
162 list_entry(hit, drm_i915_vbl_swap_t, head);
163 drm_clip_rect_t *rect;
164 int num_rects, pipe;
165 unsigned short top, bottom;
166
167 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
168
169 if (!drw)
170 continue;
171
172 rect = drw->rects;
173 pipe = swap_hit->pipe;
174 top = upper[pipe];
175 bottom = lower[pipe];
176
177 for (num_rects = drw->num_rects; num_rects--; rect++) {
178 int y1 = max(rect->y1, top);
179 int y2 = min(rect->y2, bottom);
180
181 if (y1 >= y2)
182 continue;
183
184 BEGIN_LP_RING(8);
185
186 OUT_RING(cmd);
187 OUT_RING(pitchropcpp);
188 OUT_RING((y1 << 16) | rect->x1);
189 OUT_RING((y2 << 16) | rect->x2);
190 OUT_RING(sarea_priv->front_offset);
191 OUT_RING((y1 << 16) | rect->x1);
192 OUT_RING(pitchropcpp & 0xffff);
193 OUT_RING(sarea_priv->back_offset);
194
195 ADVANCE_LP_RING();
196 }
127 } 197 }
128 } 198 }
129 199
130 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 200 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
201
202 list_for_each_safe(hit, tmp, &hits) {
203 drm_i915_vbl_swap_t *swap_hit =
204 list_entry(hit, drm_i915_vbl_swap_t, head);
205
206 list_del(hit);
207
208 drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
209 }
131} 210}
132 211
133irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 212irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
@@ -421,7 +500,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
421 500
422 if (!drm_get_drawable_info(dev, swap.drawable)) { 501 if (!drm_get_drawable_info(dev, swap.drawable)) {
423 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 502 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
424 DRM_ERROR("Invalid drawable ID %d\n", swap.drawable); 503 DRM_DEBUG("Invalid drawable ID %d\n", swap.drawable);
425 return DRM_ERR(EINVAL); 504 return DRM_ERR(EINVAL);
426 } 505 }
427 506
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index 5d835b006f55..6e8af313f2b4 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -1,7 +1,8 @@
1/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- 1/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com 2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
3 */ 3 */
4/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 4/*
5 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved. 7 * All rights reserved.
7 * 8 *
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 94abffb2cca5..f1efb49de8df 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -1,7 +1,8 @@
1/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- 1/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
2 * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com 2 * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
3 */ 3 */
4/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 4/*
5 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved. 7 * All rights reserved.
7 * 8 *
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index a080cdd6081e..17b11e7d8f32 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1,7 +1,8 @@
1/* r128_state.c -- State support for r128 -*- linux-c -*- 1/* r128_state.c -- State support for r128 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com 2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
3 */ 3 */
4/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4/*
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved. 6 * All Rights Reserved.
6 * 7 *
7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index d14477ba3679..032a022ec6a8 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count)
242 return 0; 242 return 0;
243} 243}
244 244
245/*
246 * we expect offsets passed to the framebuffer to be either within video
247 * memory or within AGP space
248 */
249static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
250 u32 offset)
251{
252 /* we realy want to check against end of video aperture
253 but this value is not being kept.
254 This code is correct for now (does the same thing as the
255 code that sets MC_FB_LOCATION) in radeon_cp.c */
256 if (offset >= dev_priv->fb_location &&
257 offset < (dev_priv->fb_location + dev_priv->fb_size))
258 return 0;
259 if (offset >= dev_priv->gart_vm_start &&
260 offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
261 return 0;
262 return 1;
263}
264
265static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * 245static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
266 dev_priv, 246 dev_priv,
267 drm_radeon_kcmd_buffer_t 247 drm_radeon_kcmd_buffer_t
@@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
290 case MARK_SAFE: 270 case MARK_SAFE:
291 break; 271 break;
292 case MARK_CHECK_OFFSET: 272 case MARK_CHECK_OFFSET:
293 if (r300_check_offset(dev_priv, (u32) values[i])) { 273 if (!radeon_check_offset(dev_priv, (u32) values[i])) {
294 DRM_ERROR 274 DRM_ERROR
295 ("Offset failed range check (reg=%04x sz=%d)\n", 275 ("Offset failed range check (reg=%04x sz=%d)\n",
296 reg, sz); 276 reg, sz);
@@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
452 i = 1; 432 i = 1;
453 while ((k < narrays) && (i < (count + 1))) { 433 while ((k < narrays) && (i < (count + 1))) {
454 i++; /* skip attribute field */ 434 i++; /* skip attribute field */
455 if (r300_check_offset(dev_priv, payload[i])) { 435 if (!radeon_check_offset(dev_priv, payload[i])) {
456 DRM_ERROR 436 DRM_ERROR
457 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", 437 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
458 k, i); 438 k, i);
@@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
463 if (k == narrays) 443 if (k == narrays)
464 break; 444 break;
465 /* have one more to process, they come in pairs */ 445 /* have one more to process, they come in pairs */
466 if (r300_check_offset(dev_priv, payload[i])) { 446 if (!radeon_check_offset(dev_priv, payload[i])) {
467 DRM_ERROR 447 DRM_ERROR
468 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", 448 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
469 k, i); 449 k, i);
@@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
508 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL 488 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
509 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { 489 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
510 offset = cmd[2] << 10; 490 offset = cmd[2] << 10;
511 ret = r300_check_offset(dev_priv, offset); 491 ret = !radeon_check_offset(dev_priv, offset);
512 if (ret) { 492 if (ret) {
513 DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); 493 DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
514 return DRM_ERR(EINVAL); 494 return DRM_ERR(EINVAL);
@@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
518 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && 498 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
519 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { 499 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
520 offset = cmd[3] << 10; 500 offset = cmd[3] << 10;
521 ret = r300_check_offset(dev_priv, offset); 501 ret = !radeon_check_offset(dev_priv, offset);
522 if (ret) { 502 if (ret) {
523 DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); 503 DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
524 return DRM_ERR(EINVAL); 504 return DRM_ERR(EINVAL);
@@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
551 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); 531 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
552 return DRM_ERR(EINVAL); 532 return DRM_ERR(EINVAL);
553 } 533 }
554 ret = r300_check_offset(dev_priv, cmd[2]); 534 ret = !radeon_check_offset(dev_priv, cmd[2]);
555 if (ret) { 535 if (ret) {
556 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); 536 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
557 return DRM_ERR(EINVAL); 537 return DRM_ERR(EINVAL);
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index f45cd7f147a5..8b105f1460a7 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -303,6 +303,21 @@ extern int radeon_no_wb;
303extern drm_ioctl_desc_t radeon_ioctls[]; 303extern drm_ioctl_desc_t radeon_ioctls[];
304extern int radeon_max_ioctl; 304extern int radeon_max_ioctl;
305 305
306/* Check whether the given hardware address is inside the framebuffer or the
307 * GART area.
308 */
309static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
310 u64 off)
311{
312 u32 fb_start = dev_priv->fb_location;
313 u32 fb_end = fb_start + dev_priv->fb_size - 1;
314 u32 gart_start = dev_priv->gart_vm_start;
315 u32 gart_end = gart_start + dev_priv->gart_size - 1;
316
317 return ((off >= fb_start && off <= fb_end) ||
318 (off >= gart_start && off <= gart_end));
319}
320
306 /* radeon_cp.c */ 321 /* radeon_cp.c */
307extern int radeon_cp_init(DRM_IOCTL_ARGS); 322extern int radeon_cp_init(DRM_IOCTL_ARGS);
308extern int radeon_cp_start(DRM_IOCTL_ARGS); 323extern int radeon_cp_start(DRM_IOCTL_ARGS);
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index d60519de887b..3ff0baa2fbfa 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -1,5 +1,5 @@
1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- 1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
2 * 2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 * 4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
index 030a6fad0d86..517cad8b6e3a 100644
--- a/drivers/char/drm/radeon_mem.c
+++ b/drivers/char/drm/radeon_mem.c
@@ -1,5 +1,5 @@
1/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- 1/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
2 * 2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 * 4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 6e04fdd732ac..938eccb78cc0 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
43 u32 *offset) 43 u32 *offset)
44{ 44{
45 u64 off = *offset; 45 u64 off = *offset;
46 u32 fb_start = dev_priv->fb_location; 46 u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
47 u32 fb_end = fb_start + dev_priv->fb_size - 1;
48 u32 gart_start = dev_priv->gart_vm_start;
49 u32 gart_end = gart_start + dev_priv->gart_size - 1;
50 struct drm_radeon_driver_file_fields *radeon_priv; 47 struct drm_radeon_driver_file_fields *radeon_priv;
51 48
52 /* Hrm ... the story of the offset ... So this function converts 49 /* Hrm ... the story of the offset ... So this function converts
@@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
66 /* First, the best case, the offset already lands in either the 63 /* First, the best case, the offset already lands in either the
67 * framebuffer or the GART mapped space 64 * framebuffer or the GART mapped space
68 */ 65 */
69 if ((off >= fb_start && off <= fb_end) || 66 if (radeon_check_offset(dev_priv, off))
70 (off >= gart_start && off <= gart_end))
71 return 0; 67 return 0;
72 68
73 /* Ok, that didn't happen... now check if we have a zero based 69 /* Ok, that didn't happen... now check if we have a zero based
@@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
81 77
82 /* Finally, assume we aimed at a GART offset if beyond the fb */ 78 /* Finally, assume we aimed at a GART offset if beyond the fb */
83 if (off > fb_end) 79 if (off > fb_end)
84 off = off - fb_end - 1 + gart_start; 80 off = off - fb_end - 1 + dev_priv->gart_vm_start;
85 81
86 /* Now recheck and fail if out of bounds */ 82 /* Now recheck and fail if out of bounds */
87 if ((off >= fb_start && off <= fb_end) || 83 if (radeon_check_offset(dev_priv, off)) {
88 (off >= gart_start && off <= gart_end)) {
89 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); 84 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
90 *offset = off; 85 *offset = off;
91 return 0; 86 return 0;
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index a9a84f88df5e..b94fab556809 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -963,8 +963,8 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS)
963 963
964 event.count = savage_bci_emit_event(dev_priv, event.flags); 964 event.count = savage_bci_emit_event(dev_priv, event.flags);
965 event.count |= dev_priv->event_wrap << 16; 965 event.count |= dev_priv->event_wrap << 16;
966 DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)-> 966 DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *) data,
967 count, event.count, sizeof(event.count)); 967 event, sizeof(event));
968 return 0; 968 return 0;
969} 969}
970 970
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
index 71e4e0f3fd54..556fd81fa815 100644
--- a/drivers/char/hw_random/amd-rng.c
+++ b/drivers/char/hw_random/amd-rng.c
@@ -144,7 +144,7 @@ static void __exit mod_exit(void)
144 hwrng_unregister(&amd_rng); 144 hwrng_unregister(&amd_rng);
145} 145}
146 146
147subsys_initcall(mod_init); 147module_init(mod_init);
148module_exit(mod_exit); 148module_exit(mod_exit);
149 149
150MODULE_AUTHOR("The Linux Kernel team"); 150MODULE_AUTHOR("The Linux Kernel team");
diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
index d37ced0d132b..8e8658dcd2e3 100644
--- a/drivers/char/hw_random/geode-rng.c
+++ b/drivers/char/hw_random/geode-rng.c
@@ -125,7 +125,7 @@ static void __exit mod_exit(void)
125 iounmap(mem); 125 iounmap(mem);
126} 126}
127 127
128subsys_initcall(mod_init); 128module_init(mod_init);
129module_exit(mod_exit); 129module_exit(mod_exit);
130 130
131MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs"); 131MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs");
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 8efbc9c0e545..f22e78e3c70f 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -143,6 +143,11 @@ static const struct pci_device_id pci_tbl[] = {
143}; 143};
144MODULE_DEVICE_TABLE(pci, pci_tbl); 144MODULE_DEVICE_TABLE(pci, pci_tbl);
145 145
146static __initdata int no_fwh_detect;
147module_param(no_fwh_detect, int, 0);
148MODULE_PARM_DESC(no_fwh_detect, "Skip FWH detection:\n"
149 " positive value - skip if FWH space locked read-only\n"
150 " negative value - skip always");
146 151
147static inline u8 hwstatus_get(void __iomem *mem) 152static inline u8 hwstatus_get(void __iomem *mem)
148{ 153{
@@ -240,6 +245,11 @@ static int __init mod_init(void)
240 if (!dev) 245 if (!dev)
241 goto out; /* Device not found. */ 246 goto out; /* Device not found. */
242 247
248 if (no_fwh_detect < 0) {
249 pci_dev_put(dev);
250 goto fwh_done;
251 }
252
243 /* Check for Intel 82802 */ 253 /* Check for Intel 82802 */
244 if (dev->device < 0x2640) { 254 if (dev->device < 0x2640) {
245 fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; 255 fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
@@ -252,6 +262,23 @@ static int __init mod_init(void)
252 pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val); 262 pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
253 pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val); 263 pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
254 264
265 if ((bios_cntl_val &
266 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
267 == BIOS_CNTL_LOCK_ENABLE_MASK) {
268 static __initdata /*const*/ char warning[] =
269 KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
270 KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
271 KERN_WARNING PFX "you are certain that your system has a functional\n"
272 KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
273
274 pci_dev_put(dev);
275 if (no_fwh_detect)
276 goto fwh_done;
277 printk(warning);
278 err = -EBUSY;
279 goto out;
280 }
281
255 mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); 282 mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
256 if (mem == NULL) { 283 if (mem == NULL) {
257 pci_dev_put(dev); 284 pci_dev_put(dev);
@@ -280,8 +307,7 @@ static int __init mod_init(void)
280 pci_write_config_byte(dev, 307 pci_write_config_byte(dev,
281 fwh_dec_en1_off, 308 fwh_dec_en1_off,
282 fwh_dec_en1_val | FWH_F8_EN_MASK); 309 fwh_dec_en1_val | FWH_F8_EN_MASK);
283 if (!(bios_cntl_val & 310 if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
284 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
285 pci_write_config_byte(dev, 311 pci_write_config_byte(dev,
286 bios_cntl_off, 312 bios_cntl_off,
287 bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK); 313 bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
@@ -315,6 +341,8 @@ static int __init mod_init(void)
315 goto out; 341 goto out;
316 } 342 }
317 343
344fwh_done:
345
318 err = -ENOMEM; 346 err = -ENOMEM;
319 mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); 347 mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
320 if (!mem) 348 if (!mem)
@@ -350,7 +378,7 @@ static void __exit mod_exit(void)
350 iounmap(mem); 378 iounmap(mem);
351} 379}
352 380
353subsys_initcall(mod_init); 381module_init(mod_init);
354module_exit(mod_exit); 382module_exit(mod_exit);
355 383
356MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets"); 384MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets");
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index c9caff57db85..bab43ca32ac1 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -64,7 +64,7 @@ static void __exit ixp4xx_rng_exit(void)
64 iounmap(rng_base); 64 iounmap(rng_base);
65} 65}
66 66
67subsys_initcall(ixp4xx_rng_init); 67module_init(ixp4xx_rng_init);
68module_exit(ixp4xx_rng_exit); 68module_exit(ixp4xx_rng_exit);
69 69
70MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); 70MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
index 0e786b617bb8..9ebf84d18655 100644
--- a/drivers/char/hw_random/via-rng.c
+++ b/drivers/char/hw_random/via-rng.c
@@ -176,7 +176,7 @@ static void __exit mod_exit(void)
176 hwrng_unregister(&via_rng); 176 hwrng_unregister(&via_rng);
177} 177}
178 178
179subsys_initcall(mod_init); 179module_init(mod_init);
180module_exit(mod_exit); 180module_exit(mod_exit);
181 181
182MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets"); 182MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets");
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h
index 5eabe47b0bc8..433305062fb8 100644
--- a/drivers/char/ip2/i2ellis.h
+++ b/drivers/char/ip2/i2ellis.h
@@ -606,9 +606,9 @@ static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int);
606// code and returning. 606// code and returning.
607// 607//
608#define COMPLETE(pB,code) \ 608#define COMPLETE(pB,code) \
609 if(1){ \ 609 do { \
610 pB->i2eError = code; \ 610 pB->i2eError = code; \
611 return (code == I2EE_GOOD);\ 611 return (code == I2EE_GOOD);\
612 } 612 } while (0)
613 613
614#endif // I2ELLIS_H 614#endif // I2ELLIS_H
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 4e4691a53890..53582b53da95 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -3649,8 +3649,6 @@ static void ipmi_timeout_handler(long timeout_period)
3649 unsigned long flags; 3649 unsigned long flags;
3650 int i; 3650 int i;
3651 3651
3652 INIT_LIST_HEAD(&timeouts);
3653
3654 rcu_read_lock(); 3652 rcu_read_lock();
3655 list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { 3653 list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
3656 /* See if any waiting messages need to be processed. */ 3654 /* See if any waiting messages need to be processed. */
@@ -3671,6 +3669,7 @@ static void ipmi_timeout_handler(long timeout_period)
3671 /* Go through the seq table and find any messages that 3669 /* Go through the seq table and find any messages that
3672 have timed out, putting them in the timeouts 3670 have timed out, putting them in the timeouts
3673 list. */ 3671 list. */
3672 INIT_LIST_HEAD(&timeouts);
3674 spin_lock_irqsave(&intf->seq_lock, flags); 3673 spin_lock_irqsave(&intf->seq_lock, flags);
3675 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) 3674 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
3676 check_msg_timeout(intf, &(intf->seq_table[i]), 3675 check_msg_timeout(intf, &(intf->seq_table[i]),
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 78280380a905..6b634e8d9519 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -216,13 +216,13 @@ static int set_param_str(const char *val, struct kernel_param *kp)
216{ 216{
217 action_fn fn = (action_fn) kp->arg; 217 action_fn fn = (action_fn) kp->arg;
218 int rv = 0; 218 int rv = 0;
219 char *dup, *s; 219 char valcp[16];
220 char *s;
220 221
221 dup = kstrdup(val, GFP_KERNEL); 222 strncpy(valcp, val, 16);
222 if (!dup) 223 valcp[15] = '\0';
223 return -ENOMEM;
224 224
225 s = strstrip(dup); 225 s = strstrip(valcp);
226 226
227 down_read(&register_sem); 227 down_read(&register_sem);
228 rv = fn(s, NULL); 228 rv = fn(s, NULL);
@@ -235,7 +235,6 @@ static int set_param_str(const char *val, struct kernel_param *kp)
235 235
236 out_unlock: 236 out_unlock:
237 up_read(&register_sem); 237 up_read(&register_sem);
238 kfree(dup);
239 return rv; 238 return rv;
240} 239}
241 240
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 5a747e685993..01084abffddf 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -230,6 +230,20 @@ static struct isi_port isi_ports[PORT_COUNT];
230 * it wants to talk. 230 * it wants to talk.
231 */ 231 */
232 232
233static inline int WaitTillCardIsFree(u16 base)
234{
235 unsigned int count = 0;
236 unsigned int a = in_atomic(); /* do we run under spinlock? */
237
238 while (!(inw(base + 0xe) & 0x1) && count++ < 100)
239 if (a)
240 mdelay(1);
241 else
242 msleep(1);
243
244 return !(inw(base + 0xe) & 0x1);
245}
246
233static int lock_card(struct isi_board *card) 247static int lock_card(struct isi_board *card)
234{ 248{
235 char retries; 249 char retries;
@@ -276,69 +290,71 @@ static void unlock_card(struct isi_board *card)
276 * ISI Card specific ops ... 290 * ISI Card specific ops ...
277 */ 291 */
278 292
293/* card->lock HAS to be held */
279static void raise_dtr(struct isi_port *port) 294static void raise_dtr(struct isi_port *port)
280{ 295{
281 struct isi_board *card = port->card; 296 struct isi_board *card = port->card;
282 unsigned long base = card->base; 297 unsigned long base = card->base;
283 u16 channel = port->channel; 298 u16 channel = port->channel;
284 299
285 if (!lock_card(card)) 300 if (WaitTillCardIsFree(base))
286 return; 301 return;
287 302
288 outw(0x8000 | (channel << card->shift_count) | 0x02, base); 303 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
289 outw(0x0504, base); 304 outw(0x0504, base);
290 InterruptTheCard(base); 305 InterruptTheCard(base);
291 port->status |= ISI_DTR; 306 port->status |= ISI_DTR;
292 unlock_card(card);
293} 307}
294 308
309/* card->lock HAS to be held */
295static inline void drop_dtr(struct isi_port *port) 310static inline void drop_dtr(struct isi_port *port)
296{ 311{
297 struct isi_board *card = port->card; 312 struct isi_board *card = port->card;
298 unsigned long base = card->base; 313 unsigned long base = card->base;
299 u16 channel = port->channel; 314 u16 channel = port->channel;
300 315
301 if (!lock_card(card)) 316 if (WaitTillCardIsFree(base))
302 return; 317 return;
303 318
304 outw(0x8000 | (channel << card->shift_count) | 0x02, base); 319 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
305 outw(0x0404, base); 320 outw(0x0404, base);
306 InterruptTheCard(base); 321 InterruptTheCard(base);
307 port->status &= ~ISI_DTR; 322 port->status &= ~ISI_DTR;
308 unlock_card(card);
309} 323}
310 324
325/* card->lock HAS to be held */
311static inline void raise_rts(struct isi_port *port) 326static inline void raise_rts(struct isi_port *port)
312{ 327{
313 struct isi_board *card = port->card; 328 struct isi_board *card = port->card;
314 unsigned long base = card->base; 329 unsigned long base = card->base;
315 u16 channel = port->channel; 330 u16 channel = port->channel;
316 331
317 if (!lock_card(card)) 332 if (WaitTillCardIsFree(base))
318 return; 333 return;
319 334
320 outw(0x8000 | (channel << card->shift_count) | 0x02, base); 335 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
321 outw(0x0a04, base); 336 outw(0x0a04, base);
322 InterruptTheCard(base); 337 InterruptTheCard(base);
323 port->status |= ISI_RTS; 338 port->status |= ISI_RTS;
324 unlock_card(card);
325} 339}
340
341/* card->lock HAS to be held */
326static inline void drop_rts(struct isi_port *port) 342static inline void drop_rts(struct isi_port *port)
327{ 343{
328 struct isi_board *card = port->card; 344 struct isi_board *card = port->card;
329 unsigned long base = card->base; 345 unsigned long base = card->base;
330 u16 channel = port->channel; 346 u16 channel = port->channel;
331 347
332 if (!lock_card(card)) 348 if (WaitTillCardIsFree(base))
333 return; 349 return;
334 350
335 outw(0x8000 | (channel << card->shift_count) | 0x02, base); 351 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
336 outw(0x0804, base); 352 outw(0x0804, base);
337 InterruptTheCard(base); 353 InterruptTheCard(base);
338 port->status &= ~ISI_RTS; 354 port->status &= ~ISI_RTS;
339 unlock_card(card);
340} 355}
341 356
357/* card->lock MUST NOT be held */
342static inline void raise_dtr_rts(struct isi_port *port) 358static inline void raise_dtr_rts(struct isi_port *port)
343{ 359{
344 struct isi_board *card = port->card; 360 struct isi_board *card = port->card;
@@ -355,35 +371,20 @@ static inline void raise_dtr_rts(struct isi_port *port)
355 unlock_card(card); 371 unlock_card(card);
356} 372}
357 373
374/* card->lock HAS to be held */
358static void drop_dtr_rts(struct isi_port *port) 375static void drop_dtr_rts(struct isi_port *port)
359{ 376{
360 struct isi_board *card = port->card; 377 struct isi_board *card = port->card;
361 unsigned long base = card->base; 378 unsigned long base = card->base;
362 u16 channel = port->channel; 379 u16 channel = port->channel;
363 380
364 if (!lock_card(card)) 381 if (WaitTillCardIsFree(base))
365 return; 382 return;
366 383
367 outw(0x8000 | (channel << card->shift_count) | 0x02, base); 384 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
368 outw(0x0c04, base); 385 outw(0x0c04, base);
369 InterruptTheCard(base); 386 InterruptTheCard(base);
370 port->status &= ~(ISI_RTS | ISI_DTR); 387 port->status &= ~(ISI_RTS | ISI_DTR);
371 unlock_card(card);
372}
373
374static inline void kill_queue(struct isi_port *port, short queue)
375{
376 struct isi_board *card = port->card;
377 unsigned long base = card->base;
378 u16 channel = port->channel;
379
380 if (!lock_card(card))
381 return;
382
383 outw(0x8000 | (channel << card->shift_count) | 0x02, base);
384 outw((queue << 8) | 0x06, base);
385 InterruptTheCard(base);
386 unlock_card(card);
387} 388}
388 389
389/* 390/*
@@ -744,7 +745,7 @@ static void isicom_config_port(struct isi_port *port)
744 else 745 else
745 raise_dtr(port); 746 raise_dtr(port);
746 747
747 if (lock_card(card)) { 748 if (WaitTillCardIsFree(base) == 0) {
748 outw(0x8000 | (channel << shift_count) |0x03, base); 749 outw(0x8000 | (channel << shift_count) |0x03, base);
749 outw(linuxb_to_isib[baud] << 8 | 0x03, base); 750 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
750 channel_setup = 0; 751 channel_setup = 0;
@@ -772,7 +773,6 @@ static void isicom_config_port(struct isi_port *port)
772 } 773 }
773 outw(channel_setup, base); 774 outw(channel_setup, base);
774 InterruptTheCard(base); 775 InterruptTheCard(base);
775 unlock_card(card);
776 } 776 }
777 if (C_CLOCAL(tty)) 777 if (C_CLOCAL(tty))
778 port->flags &= ~ASYNC_CHECK_CD; 778 port->flags &= ~ASYNC_CHECK_CD;
@@ -791,12 +791,11 @@ static void isicom_config_port(struct isi_port *port)
791 if (I_IXOFF(tty)) 791 if (I_IXOFF(tty))
792 flow_ctrl |= ISICOM_INITIATE_XONXOFF; 792 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
793 793
794 if (lock_card(card)) { 794 if (WaitTillCardIsFree(base) == 0) {
795 outw(0x8000 | (channel << shift_count) |0x04, base); 795 outw(0x8000 | (channel << shift_count) |0x04, base);
796 outw(flow_ctrl << 8 | 0x05, base); 796 outw(flow_ctrl << 8 | 0x05, base);
797 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); 797 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
798 InterruptTheCard(base); 798 InterruptTheCard(base);
799 unlock_card(card);
800 } 799 }
801 800
802 /* rx enabled -> enable port for rx on the card */ 801 /* rx enabled -> enable port for rx on the card */
@@ -821,10 +820,9 @@ static inline void isicom_setup_board(struct isi_board *bp)
821 } 820 }
822 port = bp->ports; 821 port = bp->ports;
823 bp->status |= BOARD_ACTIVE; 822 bp->status |= BOARD_ACTIVE;
824 spin_unlock_irqrestore(&bp->card_lock, flags);
825 for (channel = 0; channel < bp->port_count; channel++, port++) 823 for (channel = 0; channel < bp->port_count; channel++, port++)
826 drop_dtr_rts(port); 824 drop_dtr_rts(port);
827 return; 825 spin_unlock_irqrestore(&bp->card_lock, flags);
828} 826}
829 827
830static int isicom_setup_port(struct isi_port *port) 828static int isicom_setup_port(struct isi_port *port)
@@ -857,7 +855,12 @@ static int isicom_setup_port(struct isi_port *port)
857 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 855 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
858 856
859 /* discard any residual data */ 857 /* discard any residual data */
860 kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX); 858 if (WaitTillCardIsFree(card->base) == 0) {
859 outw(0x8000 | (port->channel << card->shift_count) | 0x02,
860 card->base);
861 outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
862 InterruptTheCard(card->base);
863 }
861 864
862 isicom_config_port(port); 865 isicom_config_port(port);
863 port->flags |= ASYNC_INITIALIZED; 866 port->flags |= ASYNC_INITIALIZED;
@@ -983,28 +986,22 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
983 986
984static inline void isicom_shutdown_board(struct isi_board *bp) 987static inline void isicom_shutdown_board(struct isi_board *bp)
985{ 988{
986 unsigned long flags;
987
988 spin_lock_irqsave(&bp->card_lock, flags);
989 if (bp->status & BOARD_ACTIVE) { 989 if (bp->status & BOARD_ACTIVE) {
990 bp->status &= ~BOARD_ACTIVE; 990 bp->status &= ~BOARD_ACTIVE;
991 } 991 }
992 spin_unlock_irqrestore(&bp->card_lock, flags);
993} 992}
994 993
994/* card->lock HAS to be held */
995static void isicom_shutdown_port(struct isi_port *port) 995static void isicom_shutdown_port(struct isi_port *port)
996{ 996{
997 struct isi_board *card = port->card; 997 struct isi_board *card = port->card;
998 struct tty_struct *tty; 998 struct tty_struct *tty;
999 unsigned long flags;
1000 999
1001 tty = port->tty; 1000 tty = port->tty;
1002 1001
1003 spin_lock_irqsave(&card->card_lock, flags); 1002 if (!(port->flags & ASYNC_INITIALIZED))
1004 if (!(port->flags & ASYNC_INITIALIZED)) {
1005 spin_unlock_irqrestore(&card->card_lock, flags);
1006 return; 1003 return;
1007 } 1004
1008 if (port->xmit_buf) { 1005 if (port->xmit_buf) {
1009 free_page((unsigned long) port->xmit_buf); 1006 free_page((unsigned long) port->xmit_buf);
1010 port->xmit_buf = NULL; 1007 port->xmit_buf = NULL;
@@ -1012,7 +1009,6 @@ static void isicom_shutdown_port(struct isi_port *port)
1012 port->flags &= ~ASYNC_INITIALIZED; 1009 port->flags &= ~ASYNC_INITIALIZED;
1013 /* 3rd October 2000 : Vinayak P Risbud */ 1010 /* 3rd October 2000 : Vinayak P Risbud */
1014 port->tty = NULL; 1011 port->tty = NULL;
1015 spin_unlock_irqrestore(&card->card_lock, flags);
1016 1012
1017 /*Fix done by Anil .S on 30-04-2001 1013 /*Fix done by Anil .S on 30-04-2001
1018 remote login through isi port has dtr toggle problem 1014 remote login through isi port has dtr toggle problem
@@ -1258,10 +1254,12 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1258 unsigned int set, unsigned int clear) 1254 unsigned int set, unsigned int clear)
1259{ 1255{
1260 struct isi_port *port = tty->driver_data; 1256 struct isi_port *port = tty->driver_data;
1257 unsigned long flags;
1261 1258
1262 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) 1259 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1263 return -ENODEV; 1260 return -ENODEV;
1264 1261
1262 spin_lock_irqsave(&port->card->card_lock, flags);
1265 if (set & TIOCM_RTS) 1263 if (set & TIOCM_RTS)
1266 raise_rts(port); 1264 raise_rts(port);
1267 if (set & TIOCM_DTR) 1265 if (set & TIOCM_DTR)
@@ -1271,6 +1269,7 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1271 drop_rts(port); 1269 drop_rts(port);
1272 if (clear & TIOCM_DTR) 1270 if (clear & TIOCM_DTR)
1273 drop_dtr(port); 1271 drop_dtr(port);
1272 spin_unlock_irqrestore(&port->card->card_lock, flags);
1274 1273
1275 return 0; 1274 return 0;
1276} 1275}
@@ -1303,7 +1302,10 @@ static int isicom_set_serial_info(struct isi_port *port,
1303 (newinfo.flags & ASYNC_FLAGS)); 1302 (newinfo.flags & ASYNC_FLAGS));
1304 } 1303 }
1305 if (reconfig_port) { 1304 if (reconfig_port) {
1305 unsigned long flags;
1306 spin_lock_irqsave(&port->card->card_lock, flags);
1306 isicom_config_port(port); 1307 isicom_config_port(port);
1308 spin_unlock_irqrestore(&port->card->card_lock, flags);
1307 } 1309 }
1308 return 0; 1310 return 0;
1309} 1311}
@@ -1384,6 +1386,7 @@ static void isicom_set_termios(struct tty_struct *tty,
1384 struct ktermios *old_termios) 1386 struct ktermios *old_termios)
1385{ 1387{
1386 struct isi_port *port = tty->driver_data; 1388 struct isi_port *port = tty->driver_data;
1389 unsigned long flags;
1387 1390
1388 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) 1391 if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1389 return; 1392 return;
@@ -1392,7 +1395,9 @@ static void isicom_set_termios(struct tty_struct *tty,
1392 tty->termios->c_iflag == old_termios->c_iflag) 1395 tty->termios->c_iflag == old_termios->c_iflag)
1393 return; 1396 return;
1394 1397
1398 spin_lock_irqsave(&port->card->card_lock, flags);
1395 isicom_config_port(port); 1399 isicom_config_port(port);
1400 spin_unlock_irqrestore(&port->card->card_lock, flags);
1396 1401
1397 if ((old_termios->c_cflag & CRTSCTS) && 1402 if ((old_termios->c_cflag & CRTSCTS) &&
1398 !(tty->termios->c_cflag & CRTSCTS)) { 1403 !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1469,11 +1474,15 @@ static void do_isicom_hangup(struct work_struct *work)
1469static void isicom_hangup(struct tty_struct *tty) 1474static void isicom_hangup(struct tty_struct *tty)
1470{ 1475{
1471 struct isi_port *port = tty->driver_data; 1476 struct isi_port *port = tty->driver_data;
1477 unsigned long flags;
1472 1478
1473 if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) 1479 if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1474 return; 1480 return;
1475 1481
1482 spin_lock_irqsave(&port->card->card_lock, flags);
1476 isicom_shutdown_port(port); 1483 isicom_shutdown_port(port);
1484 spin_unlock_irqrestore(&port->card->card_lock, flags);
1485
1477 port->count = 0; 1486 port->count = 0;
1478 port->flags &= ~ASYNC_NORMAL_ACTIVE; 1487 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1479 port->tty = NULL; 1488 port->tty = NULL;
@@ -1578,16 +1587,6 @@ end:
1578 return retval; 1587 return retval;
1579} 1588}
1580 1589
1581static inline int WaitTillCardIsFree(u16 base)
1582{
1583 unsigned long count = 0;
1584
1585 while (!(inw(base + 0xe) & 0x1) && count++ < 100)
1586 msleep(5);
1587
1588 return !(inw(base + 0xe) & 0x1);
1589}
1590
1591static int __devinit load_firmware(struct pci_dev *pdev, 1590static int __devinit load_firmware(struct pci_dev *pdev,
1592 const unsigned int index, const unsigned int signature) 1591 const unsigned int index, const unsigned int signature)
1593{ 1592{
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 4f1813e04754..f5c160caf9f4 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -293,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
293{ 293{
294 unsigned long pfn; 294 unsigned long pfn;
295 295
296 /* Turn a pfn offset into an absolute pfn */ 296 /* Turn a kernel-virtual address into a physical page frame */
297 pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff; 297 pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
298 298
299 /* 299 /*
300 * RED-PEN: on some architectures there is more mapped memory 300 * RED-PEN: on some architectures there is more mapped memory
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index c063359baf78..83f604b19290 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -717,6 +717,7 @@ static int mxser_init(void)
717 717
718 /* Initialize the tty_driver structure */ 718 /* Initialize the tty_driver structure */
719 memset(mxvar_sdriver, 0, sizeof(struct tty_driver)); 719 memset(mxvar_sdriver, 0, sizeof(struct tty_driver));
720 mxvar_sdriver->owner = THIS_MODULE;
720 mxvar_sdriver->magic = TTY_DRIVER_MAGIC; 721 mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
721 mxvar_sdriver->name = "ttyMI"; 722 mxvar_sdriver->name = "ttyMI";
722 mxvar_sdriver->major = ttymajor; 723 mxvar_sdriver->major = ttymajor;
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index cd989dce7c53..1bb030b3a51a 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -2690,6 +2690,7 @@ static int __init mxser_module_init(void)
2690 MXSER_VERSION); 2690 MXSER_VERSION);
2691 2691
2692 /* Initialize the tty_driver structure */ 2692 /* Initialize the tty_driver structure */
2693 mxvar_sdriver->owner = THIS_MODULE;
2693 mxvar_sdriver->magic = TTY_DRIVER_MAGIC; 2694 mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
2694 mxvar_sdriver->name = "ttyMI"; 2695 mxvar_sdriver->name = "ttyMI";
2695 mxvar_sdriver->major = ttymajor; 2696 mxvar_sdriver->major = ttymajor;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index e1d70e8b6268..664f36c98e6a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -113,7 +113,12 @@ static int rtc_has_irq = 1;
113#define hpet_set_rtc_irq_bit(arg) 0 113#define hpet_set_rtc_irq_bit(arg) 0
114#define hpet_rtc_timer_init() do { } while (0) 114#define hpet_rtc_timer_init() do { } while (0)
115#define hpet_rtc_dropped_irq() 0 115#define hpet_rtc_dropped_irq() 0
116static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;} 116#ifdef RTC_IRQ
117static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
118{
119 return 0;
120}
121#endif
117#else 122#else
118extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); 123extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
119#endif 124#endif
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 13935235e066..7fd3cd5ddf21 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -215,7 +215,7 @@ static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty)
215} 215}
216static struct sysrq_key_op sysrq_showstate_blocked_op = { 216static struct sysrq_key_op sysrq_showstate_blocked_op = {
217 .handler = sysrq_handle_showstate_blocked, 217 .handler = sysrq_handle_showstate_blocked,
218 .help_msg = "showBlockedTasks", 218 .help_msg = "shoW-blocked-tasks",
219 .action_msg = "Show Blocked State", 219 .action_msg = "Show Blocked State",
220 .enable_mask = SYSRQ_ENABLE_DUMP, 220 .enable_mask = SYSRQ_ENABLE_DUMP,
221}; 221};
@@ -315,15 +315,16 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
315 &sysrq_loglevel_op, /* 9 */ 315 &sysrq_loglevel_op, /* 9 */
316 316
317 /* 317 /*
318 * Don't use for system provided sysrqs, it is handled specially on 318 * a: Don't use for system provided sysrqs, it is handled specially on
319 * sparc and will never arrive 319 * sparc and will never arrive.
320 */ 320 */
321 NULL, /* a */ 321 NULL, /* a */
322 &sysrq_reboot_op, /* b */ 322 &sysrq_reboot_op, /* b */
323 &sysrq_crashdump_op, /* c */ 323 &sysrq_crashdump_op, /* c & ibm_emac driver debug */
324 &sysrq_showlocks_op, /* d */ 324 &sysrq_showlocks_op, /* d */
325 &sysrq_term_op, /* e */ 325 &sysrq_term_op, /* e */
326 &sysrq_moom_op, /* f */ 326 &sysrq_moom_op, /* f */
327 /* g: May be registered by ppc for kgdb */
327 NULL, /* g */ 328 NULL, /* g */
328 NULL, /* h */ 329 NULL, /* h */
329 &sysrq_kill_op, /* i */ 330 &sysrq_kill_op, /* i */
@@ -332,18 +333,19 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
332 NULL, /* l */ 333 NULL, /* l */
333 &sysrq_showmem_op, /* m */ 334 &sysrq_showmem_op, /* m */
334 &sysrq_unrt_op, /* n */ 335 &sysrq_unrt_op, /* n */
335 /* This will often be registered as 'Off' at init time */ 336 /* o: This will often be registered as 'Off' at init time */
336 NULL, /* o */ 337 NULL, /* o */
337 &sysrq_showregs_op, /* p */ 338 &sysrq_showregs_op, /* p */
338 NULL, /* q */ 339 NULL, /* q */
339 &sysrq_unraw_op, /* r */ 340 &sysrq_unraw_op, /* r */
340 &sysrq_sync_op, /* s */ 341 &sysrq_sync_op, /* s */
341 &sysrq_showstate_op, /* t */ 342 &sysrq_showstate_op, /* t */
342 &sysrq_mountro_op, /* u */ 343 &sysrq_mountro_op, /* u */
343 /* May be assigned at init time by SMP VOYAGER */ 344 /* v: May be registered at init time by SMP VOYAGER */
344 NULL, /* v */ 345 NULL, /* v */
345 NULL, /* w */ 346 &sysrq_showstate_blocked_op, /* w */
346 &sysrq_showstate_blocked_op, /* x */ 347 /* x: May be registered on ppc/powerpc for xmon */
348 NULL, /* x */
347 NULL, /* y */ 349 NULL, /* y */
348 NULL /* z */ 350 NULL /* z */
349}; 351};
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 244d30a03fef..4fac2bdf6215 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -186,6 +186,7 @@ static int got_event; /* if events processing have been done */
186static void switchover_timeout(unsigned long data); 186static void switchover_timeout(unsigned long data);
187static struct timer_list switchover_timer = 187static struct timer_list switchover_timer =
188 TIMER_INITIALIZER(switchover_timeout , 0, 0); 188 TIMER_INITIALIZER(switchover_timeout , 0, 0);
189static unsigned long tlclk_timer_data;
189 190
190static struct tlclk_alarms *alarm_events; 191static struct tlclk_alarms *alarm_events;
191 192
@@ -197,10 +198,19 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id);
197 198
198static DECLARE_WAIT_QUEUE_HEAD(wq); 199static DECLARE_WAIT_QUEUE_HEAD(wq);
199 200
201static unsigned long useflags;
202static DEFINE_MUTEX(tlclk_mutex);
203
200static int tlclk_open(struct inode *inode, struct file *filp) 204static int tlclk_open(struct inode *inode, struct file *filp)
201{ 205{
202 int result; 206 int result;
203 207
208 if (test_and_set_bit(0, &useflags))
209 return -EBUSY;
210 /* this legacy device is always one per system and it doesn't
211 * know how to handle multiple concurrent clients.
212 */
213
204 /* Make sure there is no interrupt pending while 214 /* Make sure there is no interrupt pending while
205 * initialising interrupt handler */ 215 * initialising interrupt handler */
206 inb(TLCLK_REG6); 216 inb(TLCLK_REG6);
@@ -221,6 +231,7 @@ static int tlclk_open(struct inode *inode, struct file *filp)
221static int tlclk_release(struct inode *inode, struct file *filp) 231static int tlclk_release(struct inode *inode, struct file *filp)
222{ 232{
223 free_irq(telclk_interrupt, tlclk_interrupt); 233 free_irq(telclk_interrupt, tlclk_interrupt);
234 clear_bit(0, &useflags);
224 235
225 return 0; 236 return 0;
226} 237}
@@ -230,26 +241,25 @@ static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
230{ 241{
231 if (count < sizeof(struct tlclk_alarms)) 242 if (count < sizeof(struct tlclk_alarms))
232 return -EIO; 243 return -EIO;
244 if (mutex_lock_interruptible(&tlclk_mutex))
245 return -EINTR;
246
233 247
234 wait_event_interruptible(wq, got_event); 248 wait_event_interruptible(wq, got_event);
235 if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) 249 if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) {
250 mutex_unlock(&tlclk_mutex);
236 return -EFAULT; 251 return -EFAULT;
252 }
237 253
238 memset(alarm_events, 0, sizeof(struct tlclk_alarms)); 254 memset(alarm_events, 0, sizeof(struct tlclk_alarms));
239 got_event = 0; 255 got_event = 0;
240 256
257 mutex_unlock(&tlclk_mutex);
241 return sizeof(struct tlclk_alarms); 258 return sizeof(struct tlclk_alarms);
242} 259}
243 260
244static 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
250static const struct file_operations tlclk_fops = { 261static const struct file_operations tlclk_fops = {
251 .read = tlclk_read, 262 .read = tlclk_read,
252 .write = tlclk_write,
253 .open = tlclk_open, 263 .open = tlclk_open,
254 .release = tlclk_release, 264 .release = tlclk_release,
255 265
@@ -540,7 +550,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d,
540 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); 550 SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
541 switch (val) { 551 switch (val) {
542 case CLK_8_592MHz: 552 case CLK_8_592MHz:
543 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); 553 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
544 break; 554 break;
545 case CLK_11_184MHz: 555 case CLK_11_184MHz:
546 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); 556 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
@@ -549,7 +559,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d,
549 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); 559 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
550 break; 560 break;
551 case CLK_44_736MHz: 561 case CLK_44_736MHz:
552 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); 562 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
553 break; 563 break;
554 } 564 }
555 } else 565 } else
@@ -807,8 +817,6 @@ static int __init tlclk_init(void)
807 &tlclk_attribute_group); 817 &tlclk_attribute_group);
808 if (ret) { 818 if (ret) {
809 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n"); 819 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
810 sysfs_remove_group(&tlclk_device->dev.kobj,
811 &tlclk_attribute_group);
812 goto out5; 820 goto out5;
813 } 821 }
814 822
@@ -841,11 +849,13 @@ static void __exit tlclk_cleanup(void)
841 849
842static void switchover_timeout(unsigned long data) 850static void switchover_timeout(unsigned long data)
843{ 851{
844 if ((data & 1)) { 852 unsigned long flags = *(unsigned long *) data;
845 if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) 853
854 if ((flags & 1)) {
855 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
846 alarm_events->switchover_primary++; 856 alarm_events->switchover_primary++;
847 } else { 857 } else {
848 if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) 858 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
849 alarm_events->switchover_secondary++; 859 alarm_events->switchover_secondary++;
850 } 860 }
851 861
@@ -903,8 +913,9 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
903 913
904 /* TIMEOUT in ~10ms */ 914 /* TIMEOUT in ~10ms */
905 switchover_timer.expires = jiffies + msecs_to_jiffies(10); 915 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
906 switchover_timer.data = inb(TLCLK_REG1); 916 tlclk_timer_data = inb(TLCLK_REG1);
907 add_timer(&switchover_timer); 917 switchover_timer.data = (unsigned long) &tlclk_timer_data;
918 mod_timer(&switchover_timer, switchover_timer.expires);
908 } else { 919 } else {
909 got_event = 1; 920 got_event = 1;
910 wake_up(&wq); 921 wake_up(&wq);
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 0e0da443cbd5..8de6b95aeb84 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -42,6 +42,7 @@
42#include <linux/tty_flip.h> 42#include <linux/tty_flip.h>
43#include <linux/sysrq.h> 43#include <linux/sysrq.h>
44 44
45#include <asm/firmware.h>
45#include <asm/iseries/vio.h> 46#include <asm/iseries/vio.h>
46#include <asm/iseries/hv_lp_event.h> 47#include <asm/iseries/hv_lp_event.h>
47#include <asm/iseries/hv_call_event.h> 48#include <asm/iseries/hv_call_event.h>
@@ -1060,6 +1061,9 @@ static int __init viocons_init2(void)
1060 atomic_t wait_flag; 1061 atomic_t wait_flag;
1061 int rc; 1062 int rc;
1062 1063
1064 if (!firmware_has_feature(FW_FEATURE_ISERIES))
1065 return -ENODEV;
1066
1063 /* +2 for fudge */ 1067 /* +2 for fudge */
1064 rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), 1068 rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
1065 viomajorsubtype_chario, VIOCHAR_WINDOW + 2); 1069 viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
@@ -1145,6 +1149,9 @@ static int __init viocons_init(void)
1145{ 1149{
1146 int i; 1150 int i;
1147 1151
1152 if (!firmware_has_feature(FW_FEATURE_ISERIES))
1153 return -ENODEV;
1154
1148 printk(VIOCONS_KERN_INFO "registering console\n"); 1155 printk(VIOCONS_KERN_INFO "registering console\n");
1149 for (i = 0; i < VTTY_PORTS; i++) { 1156 for (i = 0; i < VTTY_PORTS; i++) {
1150 port_info[i].lp = HvLpIndexInvalid; 1157 port_info[i].lp = HvLpIndexInvalid;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 94d79cb8ce8d..9438512b17f1 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -49,7 +49,7 @@
49 49
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51#include <asm/ioctls.h> 51#include <asm/ioctls.h>
52 52#include <asm/firmware.h>
53#include <asm/vio.h> 53#include <asm/vio.h>
54#include <asm/iseries/vio.h> 54#include <asm/iseries/vio.h>
55#include <asm/iseries/hv_lp_event.h> 55#include <asm/iseries/hv_lp_event.h>
@@ -997,6 +997,9 @@ int __init viotap_init(void)
997 int ret; 997 int ret;
998 struct proc_dir_entry *e; 998 struct proc_dir_entry *e;
999 999
1000 if (!firmware_has_feature(FW_FEATURE_ISERIES))
1001 return -ENODEV;
1002
1000 op_struct_list = NULL; 1003 op_struct_list = NULL;
1001 if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) { 1004 if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) {
1002 printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n"); 1005 printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n");
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index a744dad9cf45..0cea8d4907df 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2002 MontaVista Software Inc. 4 * Copyright (C) 2002 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> 5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 6 * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License as published by
@@ -125,30 +125,17 @@ static inline uint16_t giu_clear(uint16_t offset, uint16_t clear)
125 return data; 125 return data;
126} 126}
127 127
128static unsigned int startup_giuint_low_irq(unsigned int irq) 128static void ack_giuint_low(unsigned int irq)
129{ 129{
130 unsigned int pin; 130 giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
131
132 pin = GPIO_PIN_OF_IRQ(irq);
133 giu_write(GIUINTSTATL, 1 << pin);
134 giu_set(GIUINTENL, 1 << pin);
135
136 return 0;
137} 131}
138 132
139static void shutdown_giuint_low_irq(unsigned int irq) 133static void mask_giuint_low(unsigned int irq)
140{ 134{
141 giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); 135 giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
142} 136}
143 137
144static void enable_giuint_low_irq(unsigned int irq) 138static void mask_ack_giuint_low(unsigned int irq)
145{
146 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
147}
148
149#define disable_giuint_low_irq shutdown_giuint_low_irq
150
151static void ack_giuint_low_irq(unsigned int irq)
152{ 139{
153 unsigned int pin; 140 unsigned int pin;
154 141
@@ -157,46 +144,30 @@ static void ack_giuint_low_irq(unsigned int irq)
157 giu_write(GIUINTSTATL, 1 << pin); 144 giu_write(GIUINTSTATL, 1 << pin);
158} 145}
159 146
160static void end_giuint_low_irq(unsigned int irq) 147static void unmask_giuint_low(unsigned int irq)
161{ 148{
162 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) 149 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
163 giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
164} 150}
165 151
166static struct hw_interrupt_type giuint_low_irq_type = { 152static struct irq_chip giuint_low_irq_chip = {
167 .typename = "GIUINTL", 153 .name = "GIUINTL",
168 .startup = startup_giuint_low_irq, 154 .ack = ack_giuint_low,
169 .shutdown = shutdown_giuint_low_irq, 155 .mask = mask_giuint_low,
170 .enable = enable_giuint_low_irq, 156 .mask_ack = mask_ack_giuint_low,
171 .disable = disable_giuint_low_irq, 157 .unmask = unmask_giuint_low,
172 .ack = ack_giuint_low_irq,
173 .end = end_giuint_low_irq,
174}; 158};
175 159
176static unsigned int startup_giuint_high_irq(unsigned int irq) 160static void ack_giuint_high(unsigned int irq)
177{ 161{
178 unsigned int pin; 162 giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
179
180 pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
181 giu_write(GIUINTSTATH, 1 << pin);
182 giu_set(GIUINTENH, 1 << pin);
183
184 return 0;
185} 163}
186 164
187static void shutdown_giuint_high_irq(unsigned int irq) 165static void mask_giuint_high(unsigned int irq)
188{ 166{
189 giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); 167 giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
190} 168}
191 169
192static void enable_giuint_high_irq(unsigned int irq) 170static void mask_ack_giuint_high(unsigned int irq)
193{
194 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
195}
196
197#define disable_giuint_high_irq shutdown_giuint_high_irq
198
199static void ack_giuint_high_irq(unsigned int irq)
200{ 171{
201 unsigned int pin; 172 unsigned int pin;
202 173
@@ -205,20 +176,17 @@ static void ack_giuint_high_irq(unsigned int irq)
205 giu_write(GIUINTSTATH, 1 << pin); 176 giu_write(GIUINTSTATH, 1 << pin);
206} 177}
207 178
208static void end_giuint_high_irq(unsigned int irq) 179static void unmask_giuint_high(unsigned int irq)
209{ 180{
210 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) 181 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
211 giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
212} 182}
213 183
214static struct hw_interrupt_type giuint_high_irq_type = { 184static struct irq_chip giuint_high_irq_chip = {
215 .typename = "GIUINTH", 185 .name = "GIUINTH",
216 .startup = startup_giuint_high_irq, 186 .ack = ack_giuint_high,
217 .shutdown = shutdown_giuint_high_irq, 187 .mask = mask_giuint_high,
218 .enable = enable_giuint_high_irq, 188 .mask_ack = mask_ack_giuint_high,
219 .disable = disable_giuint_high_irq, 189 .unmask = unmask_giuint_high,
220 .ack = ack_giuint_high_irq,
221 .end = end_giuint_high_irq,
222}; 190};
223 191
224static int giu_get_irq(unsigned int irq) 192static int giu_get_irq(unsigned int irq)
@@ -282,9 +250,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
282 break; 250 break;
283 } 251 }
284 } 252 }
253 set_irq_chip_and_handler(GIU_IRQ(pin),
254 &giuint_low_irq_chip,
255 handle_edge_irq);
285 } else { 256 } else {
286 giu_clear(GIUINTTYPL, mask); 257 giu_clear(GIUINTTYPL, mask);
287 giu_clear(GIUINTHTSELL, mask); 258 giu_clear(GIUINTHTSELL, mask);
259 set_irq_chip_and_handler(GIU_IRQ(pin),
260 &giuint_low_irq_chip,
261 handle_level_irq);
288 } 262 }
289 giu_write(GIUINTSTATL, mask); 263 giu_write(GIUINTSTATL, mask);
290 } else if (pin < GIUINT_HIGH_MAX) { 264 } else if (pin < GIUINT_HIGH_MAX) {
@@ -311,9 +285,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
311 break; 285 break;
312 } 286 }
313 } 287 }
288 set_irq_chip_and_handler(GIU_IRQ(pin),
289 &giuint_high_irq_chip,
290 handle_edge_irq);
314 } else { 291 } else {
315 giu_clear(GIUINTTYPH, mask); 292 giu_clear(GIUINTTYPH, mask);
316 giu_clear(GIUINTHTSELH, mask); 293 giu_clear(GIUINTHTSELH, mask);
294 set_irq_chip_and_handler(GIU_IRQ(pin),
295 &giuint_high_irq_chip,
296 handle_level_irq);
317 } 297 }
318 giu_write(GIUINTSTATH, mask); 298 giu_write(GIUINTSTATH, mask);
319 } 299 }
@@ -617,10 +597,11 @@ static const struct file_operations gpio_fops = {
617static int __devinit giu_probe(struct platform_device *dev) 597static int __devinit giu_probe(struct platform_device *dev)
618{ 598{
619 unsigned long start, size, flags = 0; 599 unsigned long start, size, flags = 0;
620 unsigned int nr_pins = 0; 600 unsigned int nr_pins = 0, trigger, i, pin;
621 struct resource *res1, *res2 = NULL; 601 struct resource *res1, *res2 = NULL;
622 void *base; 602 void *base;
623 int retval, i; 603 struct irq_chip *chip;
604 int retval;
624 605
625 switch (current_cpu_data.cputype) { 606 switch (current_cpu_data.cputype) {
626 case CPU_VR4111: 607 case CPU_VR4111:
@@ -688,11 +669,20 @@ static int __devinit giu_probe(struct platform_device *dev)
688 giu_write(GIUINTENL, 0); 669 giu_write(GIUINTENL, 0);
689 giu_write(GIUINTENH, 0); 670 giu_write(GIUINTENH, 0);
690 671
672 trigger = giu_read(GIUINTTYPH) << 16;
673 trigger |= giu_read(GIUINTTYPL);
691 for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { 674 for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
692 if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) 675 pin = GPIO_PIN_OF_IRQ(i);
693 irq_desc[i].chip = &giuint_low_irq_type; 676 if (pin < GIUINT_HIGH_OFFSET)
677 chip = &giuint_low_irq_chip;
694 else 678 else
695 irq_desc[i].chip = &giuint_high_irq_type; 679 chip = &giuint_high_irq_chip;
680
681 if (trigger & (1 << pin))
682 set_irq_chip_and_handler(i, chip, handle_edge_irq);
683 else
684 set_irq_chip_and_handler(i, chip, handle_level_irq);
685
696 } 686 }
697 687
698 return cascade_irq(GIUINT_IRQ, giu_get_irq); 688 return cascade_irq(GIUINT_IRQ, giu_get_irq);