diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/snsc.h | 5 | ||||
-rw-r--r-- | drivers/char/snsc_event.c | 32 | ||||
-rw-r--r-- | drivers/sn/ioc4.c | 41 |
3 files changed, 46 insertions, 32 deletions
diff --git a/drivers/char/snsc.h b/drivers/char/snsc.h index a9efc13cc858..8a98169b60c1 100644 --- a/drivers/char/snsc.h +++ b/drivers/char/snsc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
@@ -70,6 +70,9 @@ struct sysctl_data_s { | |||
70 | #define EV_CLASS_TEST_WARNING 0x6000ul | 70 | #define EV_CLASS_TEST_WARNING 0x6000ul |
71 | #define EV_CLASS_PWRD_NOTIFY 0x8000ul | 71 | #define EV_CLASS_PWRD_NOTIFY 0x8000ul |
72 | 72 | ||
73 | /* ENV class codes */ | ||
74 | #define ENV_PWRDN_PEND 0x4101ul | ||
75 | |||
73 | #define EV_SEVERITY_POWER_STABLE 0x0000ul | 76 | #define EV_SEVERITY_POWER_STABLE 0x0000ul |
74 | #define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul | 77 | #define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul |
75 | #define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul | 78 | #define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul |
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index baaa365285fa..a4fa507eed9e 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
@@ -187,7 +187,8 @@ scdrv_event_severity(int code) | |||
187 | static void | 187 | static void |
188 | scdrv_dispatch_event(char *event, int len) | 188 | scdrv_dispatch_event(char *event, int len) |
189 | { | 189 | { |
190 | int code, esp_code, src; | 190 | static int snsc_shutting_down = 0; |
191 | int code, esp_code, src, class; | ||
191 | char desc[CHUNKSIZE]; | 192 | char desc[CHUNKSIZE]; |
192 | char *severity; | 193 | char *severity; |
193 | 194 | ||
@@ -199,9 +200,25 @@ scdrv_dispatch_event(char *event, int len) | |||
199 | /* how urgent is the message? */ | 200 | /* how urgent is the message? */ |
200 | severity = scdrv_event_severity(code); | 201 | severity = scdrv_event_severity(code); |
201 | 202 | ||
202 | if ((code & EV_CLASS_MASK) == EV_CLASS_PWRD_NOTIFY) { | 203 | class = (code & EV_CLASS_MASK); |
204 | |||
205 | if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) { | ||
203 | struct task_struct *p; | 206 | struct task_struct *p; |
204 | 207 | ||
208 | if (snsc_shutting_down) | ||
209 | return; | ||
210 | |||
211 | snsc_shutting_down = 1; | ||
212 | |||
213 | /* give a message for each type of event */ | ||
214 | if (class == EV_CLASS_PWRD_NOTIFY) | ||
215 | printk(KERN_NOTICE "Power off indication received." | ||
216 | " Sending SIGPWR to init...\n"); | ||
217 | else if (code == ENV_PWRDN_PEND) | ||
218 | printk(KERN_CRIT "WARNING: Shutting down the system" | ||
219 | " due to a critical environmental condition." | ||
220 | " Sending SIGPWR to init...\n"); | ||
221 | |||
205 | /* give a SIGPWR signal to init proc */ | 222 | /* give a SIGPWR signal to init proc */ |
206 | 223 | ||
207 | /* first find init's task */ | 224 | /* first find init's task */ |
@@ -210,12 +227,11 @@ scdrv_dispatch_event(char *event, int len) | |||
210 | if (p->pid == 1) | 227 | if (p->pid == 1) |
211 | break; | 228 | break; |
212 | } | 229 | } |
213 | if (p) { /* we found init's task */ | 230 | if (p) { |
214 | printk(KERN_EMERG "Power off indication received. Initiating power fail sequence...\n"); | ||
215 | force_sig(SIGPWR, p); | 231 | force_sig(SIGPWR, p); |
216 | } else { /* failed to find init's task - just give message(s) */ | 232 | } else { |
217 | printk(KERN_WARNING "Failed to find init proc to handle power off!\n"); | 233 | printk(KERN_ERR "Failed to signal init!\n"); |
218 | printk("%s|$(0x%x)%s\n", severity, esp_code, desc); | 234 | snsc_shutting_down = 0; /* so can try again (?) */ |
219 | } | 235 | } |
220 | read_unlock(&tasklist_lock); | 236 | read_unlock(&tasklist_lock); |
221 | } else { | 237 | } else { |
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index ea75b3d0612b..67140a5804f5 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/ioc4.h> | 31 | #include <linux/ioc4.h> |
32 | #include <linux/mmtimer.h> | 32 | #include <linux/mmtimer.h> |
33 | #include <linux/rtc.h> | 33 | #include <linux/rtc.h> |
34 | #include <linux/rwsem.h> | 34 | #include <linux/mutex.h> |
35 | #include <asm/sn/addrs.h> | 35 | #include <asm/sn/addrs.h> |
36 | #include <asm/sn/clksupport.h> | 36 | #include <asm/sn/clksupport.h> |
37 | #include <asm/sn/shub_mmr.h> | 37 | #include <asm/sn/shub_mmr.h> |
@@ -54,11 +54,10 @@ | |||
54 | * Submodule management * | 54 | * Submodule management * |
55 | ************************/ | 55 | ************************/ |
56 | 56 | ||
57 | static LIST_HEAD(ioc4_devices); | 57 | static DEFINE_MUTEX(ioc4_mutex); |
58 | static DECLARE_RWSEM(ioc4_devices_rwsem); | ||
59 | 58 | ||
59 | static LIST_HEAD(ioc4_devices); | ||
60 | static LIST_HEAD(ioc4_submodules); | 60 | static LIST_HEAD(ioc4_submodules); |
61 | static DECLARE_RWSEM(ioc4_submodules_rwsem); | ||
62 | 61 | ||
63 | /* Register an IOC4 submodule */ | 62 | /* Register an IOC4 submodule */ |
64 | int | 63 | int |
@@ -66,15 +65,13 @@ ioc4_register_submodule(struct ioc4_submodule *is) | |||
66 | { | 65 | { |
67 | struct ioc4_driver_data *idd; | 66 | struct ioc4_driver_data *idd; |
68 | 67 | ||
69 | down_write(&ioc4_submodules_rwsem); | 68 | mutex_lock(&ioc4_mutex); |
70 | list_add(&is->is_list, &ioc4_submodules); | 69 | list_add(&is->is_list, &ioc4_submodules); |
71 | up_write(&ioc4_submodules_rwsem); | ||
72 | 70 | ||
73 | /* Initialize submodule for each IOC4 */ | 71 | /* Initialize submodule for each IOC4 */ |
74 | if (!is->is_probe) | 72 | if (!is->is_probe) |
75 | return 0; | 73 | goto out; |
76 | 74 | ||
77 | down_read(&ioc4_devices_rwsem); | ||
78 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | 75 | list_for_each_entry(idd, &ioc4_devices, idd_list) { |
79 | if (is->is_probe(idd)) { | 76 | if (is->is_probe(idd)) { |
80 | printk(KERN_WARNING | 77 | printk(KERN_WARNING |
@@ -84,8 +81,8 @@ ioc4_register_submodule(struct ioc4_submodule *is) | |||
84 | pci_name(idd->idd_pdev)); | 81 | pci_name(idd->idd_pdev)); |
85 | } | 82 | } |
86 | } | 83 | } |
87 | up_read(&ioc4_devices_rwsem); | 84 | out: |
88 | 85 | mutex_unlock(&ioc4_mutex); | |
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | 88 | ||
@@ -95,15 +92,13 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) | |||
95 | { | 92 | { |
96 | struct ioc4_driver_data *idd; | 93 | struct ioc4_driver_data *idd; |
97 | 94 | ||
98 | down_write(&ioc4_submodules_rwsem); | 95 | mutex_lock(&ioc4_mutex); |
99 | list_del(&is->is_list); | 96 | list_del(&is->is_list); |
100 | up_write(&ioc4_submodules_rwsem); | ||
101 | 97 | ||
102 | /* Remove submodule for each IOC4 */ | 98 | /* Remove submodule for each IOC4 */ |
103 | if (!is->is_remove) | 99 | if (!is->is_remove) |
104 | return; | 100 | goto out; |
105 | 101 | ||
106 | down_read(&ioc4_devices_rwsem); | ||
107 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | 102 | list_for_each_entry(idd, &ioc4_devices, idd_list) { |
108 | if (is->is_remove(idd)) { | 103 | if (is->is_remove(idd)) { |
109 | printk(KERN_WARNING | 104 | printk(KERN_WARNING |
@@ -113,7 +108,8 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) | |||
113 | pci_name(idd->idd_pdev)); | 108 | pci_name(idd->idd_pdev)); |
114 | } | 109 | } |
115 | } | 110 | } |
116 | up_read(&ioc4_devices_rwsem); | 111 | out: |
112 | mutex_unlock(&ioc4_mutex); | ||
117 | } | 113 | } |
118 | 114 | ||
119 | /********************* | 115 | /********************* |
@@ -312,12 +308,11 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
312 | /* Track PCI-device specific data */ | 308 | /* Track PCI-device specific data */ |
313 | idd->idd_serial_data = NULL; | 309 | idd->idd_serial_data = NULL; |
314 | pci_set_drvdata(idd->idd_pdev, idd); | 310 | pci_set_drvdata(idd->idd_pdev, idd); |
315 | down_write(&ioc4_devices_rwsem); | 311 | |
312 | mutex_lock(&ioc4_mutex); | ||
316 | list_add(&idd->idd_list, &ioc4_devices); | 313 | list_add(&idd->idd_list, &ioc4_devices); |
317 | up_write(&ioc4_devices_rwsem); | ||
318 | 314 | ||
319 | /* Add this IOC4 to all submodules */ | 315 | /* Add this IOC4 to all submodules */ |
320 | down_read(&ioc4_submodules_rwsem); | ||
321 | list_for_each_entry(is, &ioc4_submodules, is_list) { | 316 | list_for_each_entry(is, &ioc4_submodules, is_list) { |
322 | if (is->is_probe && is->is_probe(idd)) { | 317 | if (is->is_probe && is->is_probe(idd)) { |
323 | printk(KERN_WARNING | 318 | printk(KERN_WARNING |
@@ -327,7 +322,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
327 | pci_name(idd->idd_pdev)); | 322 | pci_name(idd->idd_pdev)); |
328 | } | 323 | } |
329 | } | 324 | } |
330 | up_read(&ioc4_submodules_rwsem); | 325 | mutex_unlock(&ioc4_mutex); |
331 | 326 | ||
332 | return 0; | 327 | return 0; |
333 | 328 | ||
@@ -351,7 +346,7 @@ ioc4_remove(struct pci_dev *pdev) | |||
351 | idd = pci_get_drvdata(pdev); | 346 | idd = pci_get_drvdata(pdev); |
352 | 347 | ||
353 | /* Remove this IOC4 from all submodules */ | 348 | /* Remove this IOC4 from all submodules */ |
354 | down_read(&ioc4_submodules_rwsem); | 349 | mutex_lock(&ioc4_mutex); |
355 | list_for_each_entry(is, &ioc4_submodules, is_list) { | 350 | list_for_each_entry(is, &ioc4_submodules, is_list) { |
356 | if (is->is_remove && is->is_remove(idd)) { | 351 | if (is->is_remove && is->is_remove(idd)) { |
357 | printk(KERN_WARNING | 352 | printk(KERN_WARNING |
@@ -361,7 +356,7 @@ ioc4_remove(struct pci_dev *pdev) | |||
361 | pci_name(idd->idd_pdev)); | 356 | pci_name(idd->idd_pdev)); |
362 | } | 357 | } |
363 | } | 358 | } |
364 | up_read(&ioc4_submodules_rwsem); | 359 | mutex_unlock(&ioc4_mutex); |
365 | 360 | ||
366 | /* Release resources */ | 361 | /* Release resources */ |
367 | iounmap(idd->idd_misc_regs); | 362 | iounmap(idd->idd_misc_regs); |
@@ -377,9 +372,9 @@ ioc4_remove(struct pci_dev *pdev) | |||
377 | pci_disable_device(pdev); | 372 | pci_disable_device(pdev); |
378 | 373 | ||
379 | /* Remove and free driver data */ | 374 | /* Remove and free driver data */ |
380 | down_write(&ioc4_devices_rwsem); | 375 | mutex_lock(&ioc4_mutex); |
381 | list_del(&idd->idd_list); | 376 | list_del(&idd->idd_list); |
382 | up_write(&ioc4_devices_rwsem); | 377 | mutex_unlock(&ioc4_mutex); |
383 | kfree(idd); | 378 | kfree(idd); |
384 | } | 379 | } |
385 | 380 | ||