diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-20 16:45:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-20 16:45:53 -0400 |
commit | ede13d81b4dda409a6d271b34b8e2ec9383e255d (patch) | |
tree | 2e32142d5a8e076c64f1871f5ad162fffff5f357 /arch/powerpc/sysdev/pmi.c | |
parent | 2008220879af095d00ca27eb168a55c8595fbc0b (diff) | |
parent | 486acd4850dde6d2f8c7f431432f3914c4bfb5f5 (diff) |
Merge branch 'for-2.6.23' of master.kernel.org:/pub/scm/linux/kernel/git/arnd/cell-2.6
* 'for-2.6.23' of master.kernel.org:/pub/scm/linux/kernel/git/arnd/cell-2.6: (37 commits)
[CELL] spufs: rework list management and associated locking
[CELL] oprofile: add support to OProfile for profiling CELL BE SPUs
[CELL] oprofile: enable SPU switch notification to detect currently active SPU tasks
[CELL] spu_base: locking cleanup
[CELL] cell: indexing of SPUs based on firmware vicinity properties
[CELL] spufs: integration of SPE affinity with the scheduller
[CELL] cell: add placement computation for scheduling of affinity contexts
[CELL] spufs: extension of spu_create to support affinity definition
[CELL] cell: add hardcoded spu vicinity information for QS20
[CELL] cell: add vicinity information on spus
[CELL] cell: add per BE structure with info about its SPUs
[CELL] spufs: use find_first_bit() instead of sched_find_first_bit()
[CELL] spufs: remove unused file argument from spufs_run_spu()
[CELL] spufs: change decrementer restore timing
[CELL] spufs: dont halt decrementer at restore step 47
[CELL] spufs: limit saving MFC_CNTL bits
[CELL] spufs: fix read and write for decr_status file
[CELL] spufs: fix decr_status meanings
[CELL] spufs: remove needless context save/restore code
[CELL] spufs: fix array size of channel index
...
Diffstat (limited to 'arch/powerpc/sysdev/pmi.c')
-rw-r--r-- | arch/powerpc/sysdev/pmi.c | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 85a7c99c1003..2f91b55b7754 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c | |||
@@ -48,15 +48,13 @@ struct pmi_data { | |||
48 | struct work_struct work; | 48 | struct work_struct work; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct pmi_data *data; | ||
51 | 52 | ||
52 | static int pmi_irq_handler(int irq, void *dev_id) | 53 | static int pmi_irq_handler(int irq, void *dev_id) |
53 | { | 54 | { |
54 | struct pmi_data *data; | ||
55 | u8 type; | 55 | u8 type; |
56 | int rc; | 56 | int rc; |
57 | 57 | ||
58 | data = dev_id; | ||
59 | |||
60 | spin_lock(&data->pmi_spinlock); | 58 | spin_lock(&data->pmi_spinlock); |
61 | 59 | ||
62 | type = ioread8(data->pmi_reg + PMI_READ_TYPE); | 60 | type = ioread8(data->pmi_reg + PMI_READ_TYPE); |
@@ -111,16 +109,13 @@ MODULE_DEVICE_TABLE(of, pmi_match); | |||
111 | 109 | ||
112 | static void pmi_notify_handlers(struct work_struct *work) | 110 | static void pmi_notify_handlers(struct work_struct *work) |
113 | { | 111 | { |
114 | struct pmi_data *data; | ||
115 | struct pmi_handler *handler; | 112 | struct pmi_handler *handler; |
116 | 113 | ||
117 | data = container_of(work, struct pmi_data, work); | ||
118 | |||
119 | spin_lock(&data->handler_spinlock); | 114 | spin_lock(&data->handler_spinlock); |
120 | list_for_each_entry(handler, &data->handler, node) { | 115 | list_for_each_entry(handler, &data->handler, node) { |
121 | pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler); | 116 | pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler); |
122 | if (handler->type == data->msg.type) | 117 | if (handler->type == data->msg.type) |
123 | handler->handle_pmi_message(data->dev, data->msg); | 118 | handler->handle_pmi_message(data->msg); |
124 | } | 119 | } |
125 | spin_unlock(&data->handler_spinlock); | 120 | spin_unlock(&data->handler_spinlock); |
126 | } | 121 | } |
@@ -129,9 +124,14 @@ static int pmi_of_probe(struct of_device *dev, | |||
129 | const struct of_device_id *match) | 124 | const struct of_device_id *match) |
130 | { | 125 | { |
131 | struct device_node *np = dev->node; | 126 | struct device_node *np = dev->node; |
132 | struct pmi_data *data; | ||
133 | int rc; | 127 | int rc; |
134 | 128 | ||
129 | if (data) { | ||
130 | printk(KERN_ERR "pmi: driver has already been initialized.\n"); | ||
131 | rc = -EBUSY; | ||
132 | goto out; | ||
133 | } | ||
134 | |||
135 | data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL); | 135 | data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL); |
136 | if (!data) { | 136 | if (!data) { |
137 | printk(KERN_ERR "pmi: could not allocate memory.\n"); | 137 | printk(KERN_ERR "pmi: could not allocate memory.\n"); |
@@ -154,7 +154,6 @@ static int pmi_of_probe(struct of_device *dev, | |||
154 | 154 | ||
155 | INIT_WORK(&data->work, pmi_notify_handlers); | 155 | INIT_WORK(&data->work, pmi_notify_handlers); |
156 | 156 | ||
157 | dev->dev.driver_data = data; | ||
158 | data->dev = dev; | 157 | data->dev = dev; |
159 | 158 | ||
160 | data->irq = irq_of_parse_and_map(np, 0); | 159 | data->irq = irq_of_parse_and_map(np, 0); |
@@ -164,7 +163,7 @@ static int pmi_of_probe(struct of_device *dev, | |||
164 | goto error_cleanup_iomap; | 163 | goto error_cleanup_iomap; |
165 | } | 164 | } |
166 | 165 | ||
167 | rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", data); | 166 | rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", NULL); |
168 | if (rc) { | 167 | if (rc) { |
169 | printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n", | 168 | printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n", |
170 | data->irq, rc); | 169 | data->irq, rc); |
@@ -187,12 +186,9 @@ out: | |||
187 | 186 | ||
188 | static int pmi_of_remove(struct of_device *dev) | 187 | static int pmi_of_remove(struct of_device *dev) |
189 | { | 188 | { |
190 | struct pmi_data *data; | ||
191 | struct pmi_handler *handler, *tmp; | 189 | struct pmi_handler *handler, *tmp; |
192 | 190 | ||
193 | data = dev->dev.driver_data; | 191 | free_irq(data->irq, NULL); |
194 | |||
195 | free_irq(data->irq, data); | ||
196 | iounmap(data->pmi_reg); | 192 | iounmap(data->pmi_reg); |
197 | 193 | ||
198 | spin_lock(&data->handler_spinlock); | 194 | spin_lock(&data->handler_spinlock); |
@@ -202,7 +198,8 @@ static int pmi_of_remove(struct of_device *dev) | |||
202 | 198 | ||
203 | spin_unlock(&data->handler_spinlock); | 199 | spin_unlock(&data->handler_spinlock); |
204 | 200 | ||
205 | kfree(dev->dev.driver_data); | 201 | kfree(data); |
202 | data = NULL; | ||
206 | 203 | ||
207 | return 0; | 204 | return 0; |
208 | } | 205 | } |
@@ -226,13 +223,13 @@ static void __exit pmi_module_exit(void) | |||
226 | } | 223 | } |
227 | module_exit(pmi_module_exit); | 224 | module_exit(pmi_module_exit); |
228 | 225 | ||
229 | void pmi_send_message(struct of_device *device, pmi_message_t msg) | 226 | int pmi_send_message(pmi_message_t msg) |
230 | { | 227 | { |
231 | struct pmi_data *data; | ||
232 | unsigned long flags; | 228 | unsigned long flags; |
233 | DECLARE_COMPLETION_ONSTACK(completion); | 229 | DECLARE_COMPLETION_ONSTACK(completion); |
234 | 230 | ||
235 | data = device->dev.driver_data; | 231 | if (!data) |
232 | return -ENODEV; | ||
236 | 233 | ||
237 | mutex_lock(&data->msg_mutex); | 234 | mutex_lock(&data->msg_mutex); |
238 | 235 | ||
@@ -256,30 +253,26 @@ void pmi_send_message(struct of_device *device, pmi_message_t msg) | |||
256 | data->completion = NULL; | 253 | data->completion = NULL; |
257 | 254 | ||
258 | mutex_unlock(&data->msg_mutex); | 255 | mutex_unlock(&data->msg_mutex); |
256 | |||
257 | return 0; | ||
259 | } | 258 | } |
260 | EXPORT_SYMBOL_GPL(pmi_send_message); | 259 | EXPORT_SYMBOL_GPL(pmi_send_message); |
261 | 260 | ||
262 | void pmi_register_handler(struct of_device *device, | 261 | int pmi_register_handler(struct pmi_handler *handler) |
263 | struct pmi_handler *handler) | ||
264 | { | 262 | { |
265 | struct pmi_data *data; | ||
266 | data = device->dev.driver_data; | ||
267 | |||
268 | if (!data) | 263 | if (!data) |
269 | return; | 264 | return -ENODEV; |
270 | 265 | ||
271 | spin_lock(&data->handler_spinlock); | 266 | spin_lock(&data->handler_spinlock); |
272 | list_add_tail(&handler->node, &data->handler); | 267 | list_add_tail(&handler->node, &data->handler); |
273 | spin_unlock(&data->handler_spinlock); | 268 | spin_unlock(&data->handler_spinlock); |
269 | |||
270 | return 0; | ||
274 | } | 271 | } |
275 | EXPORT_SYMBOL_GPL(pmi_register_handler); | 272 | EXPORT_SYMBOL_GPL(pmi_register_handler); |
276 | 273 | ||
277 | void pmi_unregister_handler(struct of_device *device, | 274 | void pmi_unregister_handler(struct pmi_handler *handler) |
278 | struct pmi_handler *handler) | ||
279 | { | 275 | { |
280 | struct pmi_data *data; | ||
281 | data = device->dev.driver_data; | ||
282 | |||
283 | if (!data) | 276 | if (!data) |
284 | return; | 277 | return; |
285 | 278 | ||