diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 5 | ||||
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 36 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 9 | ||||
-rw-r--r-- | drivers/char/agp/via-agp.c | 21 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 3 | ||||
-rw-r--r-- | drivers/char/mem.c | 4 | ||||
-rw-r--r-- | drivers/char/tlclk.c | 43 | ||||
-rw-r--r-- | drivers/char/vr41xx_giu.c | 114 |
9 files changed, 135 insertions, 102 deletions
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 979300405c0e..93d2209fee4c 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -655,7 +655,7 @@ static struct pci_device_id agp_amd64_pci_table[] = { | |||
655 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | 655 | .class = (PCI_CLASS_BRIDGE_HOST << 8), |
656 | .class_mask = ~0, | 656 | .class_mask = ~0, |
657 | .vendor = PCI_VENDOR_ID_VIA, | 657 | .vendor = PCI_VENDOR_ID_VIA, |
658 | .device = PCI_DEVICE_ID_VIA_K8M890CE, | 658 | .device = PCI_DEVICE_ID_VIA_VT3336, |
659 | .subvendor = PCI_ANY_ID, | 659 | .subvendor = PCI_ANY_ID, |
660 | .subdevice = PCI_ANY_ID, | 660 | .subdevice = PCI_ANY_ID, |
661 | }, | 661 | }, |
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 | ||
44 | typedef struct _ati_page_map { | 44 | struct 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 | ||
49 | static struct _ati_generic_private { | 49 | static 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 | ||
55 | static int ati_create_page_map(ati_page_map *page_map) | 55 | static 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 | ||
85 | static void ati_free_page_map(ati_page_map *page_map) | 85 | static 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) | |||
94 | static void ati_free_gatt_pages(void) | 94 | static 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 | ||
113 | static int ati_create_gatt_pages(int nr_tables) | 113 | static 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, | |||
340 | static int ati_create_gatt_table(struct agp_bridge_data *bridge) | 340 | static 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 | ||
401 | static int ati_free_gatt_table(struct agp_bridge_data *bridge) | 401 | static 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/intel-agp.c b/drivers/char/agp/intel-agp.c index ab0a9c0ad7c0..a3011de51f7c 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -1955,6 +1955,15 @@ static int agp_intel_resume(struct pci_dev *pdev) | |||
1955 | 1955 | ||
1956 | pci_restore_state(pdev); | 1956 | pci_restore_state(pdev); |
1957 | 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 | |||
1958 | if (bridge->driver == &intel_generic_driver) | 1967 | if (bridge->driver == &intel_generic_driver) |
1959 | intel_configure(); | 1968 | intel_configure(); |
1960 | else if (bridge->driver == &intel_850_driver) | 1969 | else if (bridge->driver == &intel_850_driver) |
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/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/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/tlclk.c b/drivers/char/tlclk.c index 448d5083c381..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 */ | |||
186 | static void switchover_timeout(unsigned long data); | 186 | static void switchover_timeout(unsigned long data); |
187 | static struct timer_list switchover_timer = | 187 | static struct timer_list switchover_timer = |
188 | TIMER_INITIALIZER(switchover_timeout , 0, 0); | 188 | TIMER_INITIALIZER(switchover_timeout , 0, 0); |
189 | static unsigned long tlclk_timer_data; | ||
189 | 190 | ||
190 | static struct tlclk_alarms *alarm_events; | 191 | static struct tlclk_alarms *alarm_events; |
191 | 192 | ||
@@ -197,10 +198,19 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id); | |||
197 | 198 | ||
198 | static DECLARE_WAIT_QUEUE_HEAD(wq); | 199 | static DECLARE_WAIT_QUEUE_HEAD(wq); |
199 | 200 | ||
201 | static unsigned long useflags; | ||
202 | static DEFINE_MUTEX(tlclk_mutex); | ||
203 | |||
200 | static int tlclk_open(struct inode *inode, struct file *filp) | 204 | static 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) | |||
221 | static int tlclk_release(struct inode *inode, struct file *filp) | 231 | static 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 | ||
244 | static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, | ||
245 | loff_t *f_pos) | ||
246 | { | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static const struct file_operations tlclk_fops = { | 261 | static 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 |
@@ -839,11 +849,13 @@ static void __exit tlclk_cleanup(void) | |||
839 | 849 | ||
840 | static void switchover_timeout(unsigned long data) | 850 | static void switchover_timeout(unsigned long data) |
841 | { | 851 | { |
842 | if ((data & 1)) { | 852 | unsigned long flags = *(unsigned long *) data; |
843 | if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) | 853 | |
854 | if ((flags & 1)) { | ||
855 | if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) | ||
844 | alarm_events->switchover_primary++; | 856 | alarm_events->switchover_primary++; |
845 | } else { | 857 | } else { |
846 | if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) | 858 | if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) |
847 | alarm_events->switchover_secondary++; | 859 | alarm_events->switchover_secondary++; |
848 | } | 860 | } |
849 | 861 | ||
@@ -901,8 +913,9 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id) | |||
901 | 913 | ||
902 | /* TIMEOUT in ~10ms */ | 914 | /* TIMEOUT in ~10ms */ |
903 | switchover_timer.expires = jiffies + msecs_to_jiffies(10); | 915 | switchover_timer.expires = jiffies + msecs_to_jiffies(10); |
904 | switchover_timer.data = inb(TLCLK_REG1); | 916 | tlclk_timer_data = inb(TLCLK_REG1); |
905 | add_timer(&switchover_timer); | 917 | switchover_timer.data = (unsigned long) &tlclk_timer_data; |
918 | mod_timer(&switchover_timer, switchover_timer.expires); | ||
906 | } else { | 919 | } else { |
907 | got_event = 1; | 920 | got_event = 1; |
908 | wake_up(&wq); | 921 | wake_up(&wq); |
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 | ||
128 | static unsigned int startup_giuint_low_irq(unsigned int irq) | 128 | static 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 | ||
139 | static void shutdown_giuint_low_irq(unsigned int irq) | 133 | static 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 | ||
144 | static void enable_giuint_low_irq(unsigned int irq) | 138 | static 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 | |||
151 | static 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 | ||
160 | static void end_giuint_low_irq(unsigned int irq) | 147 | static 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 | ||
166 | static struct hw_interrupt_type giuint_low_irq_type = { | 152 | static 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 | ||
176 | static unsigned int startup_giuint_high_irq(unsigned int irq) | 160 | static 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 | ||
187 | static void shutdown_giuint_high_irq(unsigned int irq) | 165 | static 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 | ||
192 | static void enable_giuint_high_irq(unsigned int irq) | 170 | static 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 | |||
199 | static 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 | ||
208 | static void end_giuint_high_irq(unsigned int irq) | 179 | static 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 | ||
214 | static struct hw_interrupt_type giuint_high_irq_type = { | 184 | static 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 | ||
224 | static int giu_get_irq(unsigned int irq) | 192 | static 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 = { | |||
617 | static int __devinit giu_probe(struct platform_device *dev) | 597 | static 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); |