diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2007-06-15 18:05:01 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-06-28 05:16:42 -0400 |
commit | 13a5e30cf7407415387b5592b15ef4b352d28283 (patch) | |
tree | 8db7937b82960d0f59f3bbdf4715b347fc7a04d1 /drivers/ps3/ps3av.c | |
parent | 66c63b84b23d39ce191a18833b5a769370114ec9 (diff) |
[POWERPC] PS3: Rework AV settings driver
Make the PS3 ps3av driver a loadable module.
- Replace static data with kmalloc()'ed.
o Allocate struct ps3av dynamically, as it contains data used as vuart
receive/transmit buffers
o Move static recv_buf from ps3av_do_pkt() to struct ps3av
- Move ps3av_vuart_{read,write}() from drivers/ps3/ps3av_cmd.c to
drivers/ps3/ps3av.c and make them static as they're used in that file only.
- Make device a PS3 system-bus device.
- Update copyright formatting.
- Make two new routines ps3av_register_flip_ctl() and ps3av_flip_ctl() to
support late binding of the frame buffer flip control routine.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/ps3/ps3av.c')
-rw-r--r-- | drivers/ps3/ps3av.c | 372 |
1 files changed, 198 insertions, 174 deletions
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 1393e64335f9..85e21614f868 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c | |||
@@ -1,32 +1,30 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | 2 | * PS3 AV backend support. |
3 | * Copyright 2006, 2007 Sony Corporation | ||
4 | * | 3 | * |
5 | * AV backend support for PS3 | 4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. |
5 | * Copyright 2007 Sony Corp. | ||
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * under the terms of the GNU General Public License as published | 8 | * it under the terms of the GNU General Public License as published by |
9 | * by the Free Software Foundation; version 2 of the License. | 9 | * the Free Software Foundation; version 2 of the License. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, but | 11 | * This program is distributed in the hope that it will be useful, |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License along | 16 | * You should have received a copy of the GNU General Public License |
17 | * with this program; if not, write to the Free Software Foundation, Inc., | 17 | * along with this program; if not, write to the Free Software |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
23 | #include <linux/notifier.h> | 24 | #include <linux/notifier.h> |
24 | #include <linux/reboot.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/ioctl.h> | 25 | #include <linux/ioctl.h> |
27 | 26 | ||
28 | #include <asm/firmware.h> | 27 | #include <asm/firmware.h> |
29 | #include <asm/lv1call.h> | ||
30 | #include <asm/ps3av.h> | 28 | #include <asm/ps3av.h> |
31 | #include <asm/ps3.h> | 29 | #include <asm/ps3.h> |
32 | 30 | ||
@@ -39,13 +37,12 @@ static int timeout = 5000; /* in msec ( 5 sec ) */ | |||
39 | module_param(timeout, int, 0644); | 37 | module_param(timeout, int, 0644); |
40 | 38 | ||
41 | static struct ps3av { | 39 | static struct ps3av { |
42 | int available; | ||
43 | struct mutex mutex; | 40 | struct mutex mutex; |
44 | struct work_struct work; | 41 | struct work_struct work; |
45 | struct completion done; | 42 | struct completion done; |
46 | struct workqueue_struct *wq; | 43 | struct workqueue_struct *wq; |
47 | int open_count; | 44 | int open_count; |
48 | struct ps3_vuart_port_device *dev; | 45 | struct ps3_system_bus_device *dev; |
49 | 46 | ||
50 | int region; | 47 | int region; |
51 | struct ps3av_pkt_av_get_hw_conf av_hw_conf; | 48 | struct ps3av_pkt_av_get_hw_conf av_hw_conf; |
@@ -55,11 +52,13 @@ static struct ps3av { | |||
55 | u32 audio_port; | 52 | u32 audio_port; |
56 | int ps3av_mode; | 53 | int ps3av_mode; |
57 | int ps3av_mode_old; | 54 | int ps3av_mode_old; |
58 | } ps3av; | 55 | union { |
59 | 56 | struct ps3av_reply_hdr reply_hdr; | |
60 | static struct ps3_vuart_port_device ps3av_dev = { | 57 | u8 raw[PS3AV_BUF_SIZE]; |
61 | .match_id = PS3_MATCH_ID_AV_SETTINGS | 58 | } recv_buf; |
62 | }; | 59 | void (*flip_ctl)(int on, void *data); |
60 | void *flip_data; | ||
61 | } *ps3av; | ||
63 | 62 | ||
64 | /* color space */ | 63 | /* color space */ |
65 | #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 | 64 | #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 |
@@ -169,7 +168,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr) | |||
169 | if (hdr->cid & PS3AV_EVENT_CMD_MASK) { | 168 | if (hdr->cid & PS3AV_EVENT_CMD_MASK) { |
170 | table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); | 169 | table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); |
171 | if (table) | 170 | if (table) |
172 | dev_dbg(&ps3av_dev.core, | 171 | dev_dbg(&ps3av->dev->core, |
173 | "recv event packet cid:%08x port:0x%x size:%d\n", | 172 | "recv event packet cid:%08x port:0x%x size:%d\n", |
174 | hdr->cid, ps3av_event_get_port_id(hdr->cid), | 173 | hdr->cid, ps3av_event_get_port_id(hdr->cid), |
175 | hdr->size); | 174 | hdr->size); |
@@ -182,6 +181,41 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr) | |||
182 | return 0; | 181 | return 0; |
183 | } | 182 | } |
184 | 183 | ||
184 | |||
185 | #define POLLING_INTERVAL 25 /* in msec */ | ||
186 | |||
187 | static int ps3av_vuart_write(struct ps3_system_bus_device *dev, | ||
188 | const void *buf, unsigned long size) | ||
189 | { | ||
190 | int error; | ||
191 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); | ||
192 | error = ps3_vuart_write(dev, buf, size); | ||
193 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | ||
194 | return error ? error : size; | ||
195 | } | ||
196 | |||
197 | static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf, | ||
198 | unsigned long size, int timeout) | ||
199 | { | ||
200 | int error; | ||
201 | int loopcnt = 0; | ||
202 | |||
203 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); | ||
204 | timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL; | ||
205 | while (loopcnt++ <= timeout) { | ||
206 | error = ps3_vuart_read(dev, buf, size); | ||
207 | if (!error) | ||
208 | return size; | ||
209 | if (error != -EAGAIN) { | ||
210 | printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", | ||
211 | __func__, error); | ||
212 | return error; | ||
213 | } | ||
214 | msleep(POLLING_INTERVAL); | ||
215 | } | ||
216 | return -EWOULDBLOCK; | ||
217 | } | ||
218 | |||
185 | static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, | 219 | static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, |
186 | struct ps3av_reply_hdr *recv_buf, int write_len, | 220 | struct ps3av_reply_hdr *recv_buf, int write_len, |
187 | int read_len) | 221 | int read_len) |
@@ -190,13 +224,13 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, | |||
190 | u32 cmd; | 224 | u32 cmd; |
191 | int event; | 225 | int event; |
192 | 226 | ||
193 | if (!ps3av.available) | 227 | if (!ps3av) |
194 | return -ENODEV; | 228 | return -ENODEV; |
195 | 229 | ||
196 | /* send pkt */ | 230 | /* send pkt */ |
197 | res = ps3av_vuart_write(ps3av.dev, send_buf, write_len); | 231 | res = ps3av_vuart_write(ps3av->dev, send_buf, write_len); |
198 | if (res < 0) { | 232 | if (res < 0) { |
199 | dev_dbg(&ps3av_dev.core, | 233 | dev_dbg(&ps3av->dev->core, |
200 | "%s: ps3av_vuart_write() failed (result=%d)\n", | 234 | "%s: ps3av_vuart_write() failed (result=%d)\n", |
201 | __func__, res); | 235 | __func__, res); |
202 | return res; | 236 | return res; |
@@ -206,20 +240,20 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, | |||
206 | cmd = send_buf->cid; | 240 | cmd = send_buf->cid; |
207 | do { | 241 | do { |
208 | /* read header */ | 242 | /* read header */ |
209 | res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE, | 243 | res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE, |
210 | timeout); | 244 | timeout); |
211 | if (res != PS3AV_HDR_SIZE) { | 245 | if (res != PS3AV_HDR_SIZE) { |
212 | dev_dbg(&ps3av_dev.core, | 246 | dev_dbg(&ps3av->dev->core, |
213 | "%s: ps3av_vuart_read() failed (result=%d)\n", | 247 | "%s: ps3av_vuart_read() failed (result=%d)\n", |
214 | __func__, res); | 248 | __func__, res); |
215 | return res; | 249 | return res; |
216 | } | 250 | } |
217 | 251 | ||
218 | /* read body */ | 252 | /* read body */ |
219 | res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid, | 253 | res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid, |
220 | recv_buf->size, timeout); | 254 | recv_buf->size, timeout); |
221 | if (res < 0) { | 255 | if (res < 0) { |
222 | dev_dbg(&ps3av_dev.core, | 256 | dev_dbg(&ps3av->dev->core, |
223 | "%s: ps3av_vuart_read() failed (result=%d)\n", | 257 | "%s: ps3av_vuart_read() failed (result=%d)\n", |
224 | __func__, res); | 258 | __func__, res); |
225 | return res; | 259 | return res; |
@@ -230,7 +264,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, | |||
230 | } while (event); | 264 | } while (event); |
231 | 265 | ||
232 | if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { | 266 | if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { |
233 | dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", | 267 | dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n", |
234 | __func__, recv_buf->cid); | 268 | __func__, recv_buf->cid); |
235 | return -EINVAL; | 269 | return -EINVAL; |
236 | } | 270 | } |
@@ -245,7 +279,7 @@ static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf, | |||
245 | int return_len; | 279 | int return_len; |
246 | 280 | ||
247 | if (recv_buf->version != PS3AV_VERSION) { | 281 | if (recv_buf->version != PS3AV_VERSION) { |
248 | dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n", | 282 | dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n", |
249 | recv_buf->version); | 283 | recv_buf->version); |
250 | return -EFAULT; | 284 | return -EFAULT; |
251 | } | 285 | } |
@@ -267,16 +301,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, | |||
267 | struct ps3av_send_hdr *buf) | 301 | struct ps3av_send_hdr *buf) |
268 | { | 302 | { |
269 | int res = 0; | 303 | int res = 0; |
270 | static union { | ||
271 | struct ps3av_reply_hdr reply_hdr; | ||
272 | u8 raw[PS3AV_BUF_SIZE]; | ||
273 | } recv_buf; | ||
274 | |||
275 | u32 *table; | 304 | u32 *table; |
276 | 305 | ||
277 | BUG_ON(!ps3av.available); | 306 | BUG_ON(!ps3av); |
278 | 307 | ||
279 | mutex_lock(&ps3av.mutex); | 308 | mutex_lock(&ps3av->mutex); |
280 | 309 | ||
281 | table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); | 310 | table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); |
282 | BUG_ON(!table); | 311 | BUG_ON(!table); |
@@ -288,7 +317,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, | |||
288 | ps3av_set_hdr(cid, send_len, buf); | 317 | ps3av_set_hdr(cid, send_len, buf); |
289 | 318 | ||
290 | /* send packet via vuart */ | 319 | /* send packet via vuart */ |
291 | res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len, | 320 | res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len, |
292 | usr_buf_size); | 321 | usr_buf_size); |
293 | if (res < 0) { | 322 | if (res < 0) { |
294 | printk(KERN_ERR | 323 | printk(KERN_ERR |
@@ -298,7 +327,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, | |||
298 | } | 327 | } |
299 | 328 | ||
300 | /* process reply packet */ | 329 | /* process reply packet */ |
301 | res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr, | 330 | res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr, |
302 | usr_buf_size); | 331 | usr_buf_size); |
303 | if (res < 0) { | 332 | if (res < 0) { |
304 | printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", | 333 | printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", |
@@ -306,11 +335,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, | |||
306 | goto err; | 335 | goto err; |
307 | } | 336 | } |
308 | 337 | ||
309 | mutex_unlock(&ps3av.mutex); | 338 | mutex_unlock(&ps3av->mutex); |
310 | return 0; | 339 | return 0; |
311 | 340 | ||
312 | err: | 341 | err: |
313 | mutex_unlock(&ps3av.mutex); | 342 | mutex_unlock(&ps3av->mutex); |
314 | printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); | 343 | printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); |
315 | return res; | 344 | return res; |
316 | } | 345 | } |
@@ -319,11 +348,11 @@ static int ps3av_set_av_video_mute(u32 mute) | |||
319 | { | 348 | { |
320 | int i, num_of_av_port, res; | 349 | int i, num_of_av_port, res; |
321 | 350 | ||
322 | num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + | 351 | num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + |
323 | ps3av.av_hw_conf.num_of_avmulti; | 352 | ps3av->av_hw_conf.num_of_avmulti; |
324 | /* video mute on */ | 353 | /* video mute on */ |
325 | for (i = 0; i < num_of_av_port; i++) { | 354 | for (i = 0; i < num_of_av_port; i++) { |
326 | res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute); | 355 | res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute); |
327 | if (res < 0) | 356 | if (res < 0) |
328 | return -1; | 357 | return -1; |
329 | } | 358 | } |
@@ -335,13 +364,13 @@ static int ps3av_set_video_disable_sig(void) | |||
335 | { | 364 | { |
336 | int i, num_of_hdmi_port, num_of_av_port, res; | 365 | int i, num_of_hdmi_port, num_of_av_port, res; |
337 | 366 | ||
338 | num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi; | 367 | num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi; |
339 | num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + | 368 | num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + |
340 | ps3av.av_hw_conf.num_of_avmulti; | 369 | ps3av->av_hw_conf.num_of_avmulti; |
341 | 370 | ||
342 | /* tv mute */ | 371 | /* tv mute */ |
343 | for (i = 0; i < num_of_hdmi_port; i++) { | 372 | for (i = 0; i < num_of_hdmi_port; i++) { |
344 | res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], | 373 | res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], |
345 | PS3AV_CMD_MUTE_ON); | 374 | PS3AV_CMD_MUTE_ON); |
346 | if (res < 0) | 375 | if (res < 0) |
347 | return -1; | 376 | return -1; |
@@ -350,11 +379,11 @@ static int ps3av_set_video_disable_sig(void) | |||
350 | 379 | ||
351 | /* video mute on */ | 380 | /* video mute on */ |
352 | for (i = 0; i < num_of_av_port; i++) { | 381 | for (i = 0; i < num_of_av_port; i++) { |
353 | res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]); | 382 | res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]); |
354 | if (res < 0) | 383 | if (res < 0) |
355 | return -1; | 384 | return -1; |
356 | if (i < num_of_hdmi_port) { | 385 | if (i < num_of_hdmi_port) { |
357 | res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], | 386 | res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], |
358 | PS3AV_CMD_MUTE_OFF); | 387 | PS3AV_CMD_MUTE_OFF); |
359 | if (res < 0) | 388 | if (res < 0) |
360 | return -1; | 389 | return -1; |
@@ -369,17 +398,17 @@ static int ps3av_set_audio_mute(u32 mute) | |||
369 | { | 398 | { |
370 | int i, num_of_av_port, num_of_opt_port, res; | 399 | int i, num_of_av_port, num_of_opt_port, res; |
371 | 400 | ||
372 | num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + | 401 | num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + |
373 | ps3av.av_hw_conf.num_of_avmulti; | 402 | ps3av->av_hw_conf.num_of_avmulti; |
374 | num_of_opt_port = ps3av.av_hw_conf.num_of_spdif; | 403 | num_of_opt_port = ps3av->av_hw_conf.num_of_spdif; |
375 | 404 | ||
376 | for (i = 0; i < num_of_av_port; i++) { | 405 | for (i = 0; i < num_of_av_port; i++) { |
377 | res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute); | 406 | res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute); |
378 | if (res < 0) | 407 | if (res < 0) |
379 | return -1; | 408 | return -1; |
380 | } | 409 | } |
381 | for (i = 0; i < num_of_opt_port; i++) { | 410 | for (i = 0; i < num_of_opt_port; i++) { |
382 | res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute); | 411 | res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute); |
383 | if (res < 0) | 412 | if (res < 0) |
384 | return -1; | 413 | return -1; |
385 | } | 414 | } |
@@ -394,40 +423,40 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source) | |||
394 | struct ps3av_pkt_audio_mode audio_mode; | 423 | struct ps3av_pkt_audio_mode audio_mode; |
395 | u32 len = 0; | 424 | u32 len = 0; |
396 | 425 | ||
397 | num_of_audio = ps3av.av_hw_conf.num_of_hdmi + | 426 | num_of_audio = ps3av->av_hw_conf.num_of_hdmi + |
398 | ps3av.av_hw_conf.num_of_avmulti + | 427 | ps3av->av_hw_conf.num_of_avmulti + |
399 | ps3av.av_hw_conf.num_of_spdif; | 428 | ps3av->av_hw_conf.num_of_spdif; |
400 | 429 | ||
401 | avb_param.num_of_video_pkt = 0; | 430 | avb_param.num_of_video_pkt = 0; |
402 | avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ | 431 | avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ |
403 | avb_param.num_of_av_video_pkt = 0; | 432 | avb_param.num_of_av_video_pkt = 0; |
404 | avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi; | 433 | avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi; |
405 | 434 | ||
406 | vid = video_mode_table[ps3av.ps3av_mode].vid; | 435 | vid = video_mode_table[ps3av->ps3av_mode].vid; |
407 | 436 | ||
408 | /* audio mute */ | 437 | /* audio mute */ |
409 | ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); | 438 | ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); |
410 | 439 | ||
411 | /* audio inactive */ | 440 | /* audio inactive */ |
412 | res = ps3av_cmd_audio_active(0, ps3av.audio_port); | 441 | res = ps3av_cmd_audio_active(0, ps3av->audio_port); |
413 | if (res < 0) | 442 | if (res < 0) |
414 | dev_dbg(&ps3av_dev.core, | 443 | dev_dbg(&ps3av->dev->core, |
415 | "ps3av_cmd_audio_active OFF failed\n"); | 444 | "ps3av_cmd_audio_active OFF failed\n"); |
416 | 445 | ||
417 | /* audio_pkt */ | 446 | /* audio_pkt */ |
418 | for (i = 0; i < num_of_audio; i++) { | 447 | for (i = 0; i < num_of_audio; i++) { |
419 | ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs, | 448 | ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch, |
420 | word_bits, format, source); | 449 | fs, word_bits, format, source); |
421 | if (i < ps3av.av_hw_conf.num_of_hdmi) { | 450 | if (i < ps3av->av_hw_conf.num_of_hdmi) { |
422 | /* hdmi only */ | 451 | /* hdmi only */ |
423 | len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], | 452 | len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], |
424 | ps3av.av_port[i], | 453 | ps3av->av_port[i], |
425 | &audio_mode, vid); | 454 | &audio_mode, vid); |
426 | } | 455 | } |
427 | /* audio_mode pkt should be sent separately */ | 456 | /* audio_mode pkt should be sent separately */ |
428 | res = ps3av_cmd_audio_mode(&audio_mode); | 457 | res = ps3av_cmd_audio_mode(&audio_mode); |
429 | if (res < 0) | 458 | if (res < 0) |
430 | dev_dbg(&ps3av_dev.core, | 459 | dev_dbg(&ps3av->dev->core, |
431 | "ps3av_cmd_audio_mode failed, port:%x\n", i); | 460 | "ps3av_cmd_audio_mode failed, port:%x\n", i); |
432 | } | 461 | } |
433 | 462 | ||
@@ -435,15 +464,16 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source) | |||
435 | len += offsetof(struct ps3av_pkt_avb_param, buf); | 464 | len += offsetof(struct ps3av_pkt_avb_param, buf); |
436 | res = ps3av_cmd_avb_param(&avb_param, len); | 465 | res = ps3av_cmd_avb_param(&avb_param, len); |
437 | if (res < 0) | 466 | if (res < 0) |
438 | dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); | 467 | dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); |
439 | 468 | ||
440 | /* audio mute */ | 469 | /* audio mute */ |
441 | ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); | 470 | ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); |
442 | 471 | ||
443 | /* audio active */ | 472 | /* audio active */ |
444 | res = ps3av_cmd_audio_active(1, ps3av.audio_port); | 473 | res = ps3av_cmd_audio_active(1, ps3av->audio_port); |
445 | if (res < 0) | 474 | if (res < 0) |
446 | dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n"); | 475 | dev_dbg(&ps3av->dev->core, |
476 | "ps3av_cmd_audio_active ON failed\n"); | ||
447 | 477 | ||
448 | return 0; | 478 | return 0; |
449 | } | 479 | } |
@@ -456,7 +486,7 @@ static int ps3av_set_videomode(void) | |||
456 | ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); | 486 | ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); |
457 | 487 | ||
458 | /* wake up ps3avd to do the actual video mode setting */ | 488 | /* wake up ps3avd to do the actual video mode setting */ |
459 | queue_work(ps3av.wq, &ps3av.work); | 489 | queue_work(ps3av->wq, &ps3av->work); |
460 | 490 | ||
461 | return 0; | 491 | return 0; |
462 | } | 492 | } |
@@ -473,8 +503,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
473 | 503 | ||
474 | avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ | 504 | avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ |
475 | avb_param.num_of_audio_pkt = 0; | 505 | avb_param.num_of_audio_pkt = 0; |
476 | avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi + | 506 | avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi + |
477 | ps3av.av_hw_conf.num_of_avmulti; | 507 | ps3av->av_hw_conf.num_of_avmulti; |
478 | avb_param.num_of_av_audio_pkt = 0; | 508 | avb_param.num_of_av_audio_pkt = 0; |
479 | 509 | ||
480 | /* video signal off */ | 510 | /* video signal off */ |
@@ -484,21 +514,21 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
484 | if (id & PS3AV_MODE_HDCP_OFF) { | 514 | if (id & PS3AV_MODE_HDCP_OFF) { |
485 | res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); | 515 | res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); |
486 | if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) | 516 | if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) |
487 | dev_dbg(&ps3av_dev.core, "Not supported\n"); | 517 | dev_dbg(&ps3av->dev->core, "Not supported\n"); |
488 | else if (res) | 518 | else if (res) |
489 | dev_dbg(&ps3av_dev.core, | 519 | dev_dbg(&ps3av->dev->core, |
490 | "ps3av_cmd_av_hdmi_mode failed\n"); | 520 | "ps3av_cmd_av_hdmi_mode failed\n"); |
491 | } else if (old_id & PS3AV_MODE_HDCP_OFF) { | 521 | } else if (old_id & PS3AV_MODE_HDCP_OFF) { |
492 | res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); | 522 | res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); |
493 | if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) | 523 | if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) |
494 | dev_dbg(&ps3av_dev.core, | 524 | dev_dbg(&ps3av->dev->core, |
495 | "ps3av_cmd_av_hdmi_mode failed\n"); | 525 | "ps3av_cmd_av_hdmi_mode failed\n"); |
496 | } | 526 | } |
497 | 527 | ||
498 | /* video_pkt */ | 528 | /* video_pkt */ |
499 | for (i = 0; i < avb_param.num_of_video_pkt; i++) | 529 | for (i = 0; i < avb_param.num_of_video_pkt; i++) |
500 | len += ps3av_cmd_set_video_mode(&avb_param.buf[len], | 530 | len += ps3av_cmd_set_video_mode(&avb_param.buf[len], |
501 | ps3av.head[i], video_mode->vid, | 531 | ps3av->head[i], video_mode->vid, |
502 | video_mode->fmt, id); | 532 | video_mode->fmt, id); |
503 | /* av_video_pkt */ | 533 | /* av_video_pkt */ |
504 | for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { | 534 | for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { |
@@ -507,12 +537,12 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
507 | else | 537 | else |
508 | av_video_cs = video_mode->cs; | 538 | av_video_cs = video_mode->cs; |
509 | #ifndef PS3AV_HDMI_YUV | 539 | #ifndef PS3AV_HDMI_YUV |
510 | if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || | 540 | if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || |
511 | ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) | 541 | ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) |
512 | av_video_cs = RGB8; /* use RGB for HDMI */ | 542 | av_video_cs = RGB8; /* use RGB for HDMI */ |
513 | #endif | 543 | #endif |
514 | len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], | 544 | len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], |
515 | ps3av.av_port[i], | 545 | ps3av->av_port[i], |
516 | video_mode->vid, av_video_cs, | 546 | video_mode->vid, av_video_cs, |
517 | video_mode->aspect, id); | 547 | video_mode->aspect, id); |
518 | } | 548 | } |
@@ -524,7 +554,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
524 | "%s: Command failed. Please try your request again. \n", | 554 | "%s: Command failed. Please try your request again. \n", |
525 | __func__); | 555 | __func__); |
526 | else if (res) | 556 | else if (res) |
527 | dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); | 557 | dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); |
528 | 558 | ||
529 | msleep(1500); | 559 | msleep(1500); |
530 | /* av video mute */ | 560 | /* av video mute */ |
@@ -533,8 +563,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
533 | 563 | ||
534 | static void ps3avd(struct work_struct *work) | 564 | static void ps3avd(struct work_struct *work) |
535 | { | 565 | { |
536 | ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old); | 566 | ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old); |
537 | complete(&ps3av.done); | 567 | complete(&ps3av->done); |
538 | } | 568 | } |
539 | 569 | ||
540 | static int ps3av_vid2table_id(int vid) | 570 | static int ps3av_vid2table_id(int vid) |
@@ -601,7 +631,7 @@ static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info) | |||
601 | return vid; | 631 | return vid; |
602 | } | 632 | } |
603 | 633 | ||
604 | if (ps3av.region & PS3AV_REGION_60) | 634 | if (ps3av->region & PS3AV_REGION_60) |
605 | vid = PS3AV_DEFAULT_HDMI_VID_REG_60; | 635 | vid = PS3AV_DEFAULT_HDMI_VID_REG_60; |
606 | else | 636 | else |
607 | vid = PS3AV_DEFAULT_HDMI_VID_REG_50; | 637 | vid = PS3AV_DEFAULT_HDMI_VID_REG_50; |
@@ -643,16 +673,16 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, | |||
643 | vid = PS3AV_DEFAULT_DVI_VID; | 673 | vid = PS3AV_DEFAULT_DVI_VID; |
644 | } else if (vid == -1) { | 674 | } else if (vid == -1) { |
645 | /* no HDMI interface or HDMI is off */ | 675 | /* no HDMI interface or HDMI is off */ |
646 | if (ps3av.region & PS3AV_REGION_60) | 676 | if (ps3av->region & PS3AV_REGION_60) |
647 | vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; | 677 | vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; |
648 | else | 678 | else |
649 | vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; | 679 | vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; |
650 | if (ps3av.region & PS3AV_REGION_RGB) | 680 | if (ps3av->region & PS3AV_REGION_RGB) |
651 | rgb = PS3AV_MODE_RGB; | 681 | rgb = PS3AV_MODE_RGB; |
652 | } else if (boot) { | 682 | } else if (boot) { |
653 | /* HDMI: using DEFAULT HDMI_VID while booting up */ | 683 | /* HDMI: using DEFAULT HDMI_VID while booting up */ |
654 | info = &monitor_info.info; | 684 | info = &monitor_info.info; |
655 | if (ps3av.region & PS3AV_REGION_60) { | 685 | if (ps3av->region & PS3AV_REGION_60) { |
656 | if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) | 686 | if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) |
657 | vid = PS3AV_DEFAULT_HDMI_VID_REG_60; | 687 | vid = PS3AV_DEFAULT_HDMI_VID_REG_60; |
658 | else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) | 688 | else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) |
@@ -715,14 +745,14 @@ int ps3av_set_video_mode(u32 id, int boot) | |||
715 | 745 | ||
716 | size = ARRAY_SIZE(video_mode_table); | 746 | size = ARRAY_SIZE(video_mode_table); |
717 | if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { | 747 | if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { |
718 | dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id); | 748 | dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id); |
719 | return -EINVAL; | 749 | return -EINVAL; |
720 | } | 750 | } |
721 | 751 | ||
722 | /* auto mode */ | 752 | /* auto mode */ |
723 | option = id & ~PS3AV_MODE_MASK; | 753 | option = id & ~PS3AV_MODE_MASK; |
724 | if ((id & PS3AV_MODE_MASK) == 0) { | 754 | if ((id & PS3AV_MODE_MASK) == 0) { |
725 | id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); | 755 | id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot); |
726 | if (id < 1) { | 756 | if (id < 1) { |
727 | printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); | 757 | printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); |
728 | return -EINVAL; | 758 | return -EINVAL; |
@@ -731,11 +761,11 @@ int ps3av_set_video_mode(u32 id, int boot) | |||
731 | } | 761 | } |
732 | 762 | ||
733 | /* set videomode */ | 763 | /* set videomode */ |
734 | wait_for_completion(&ps3av.done); | 764 | wait_for_completion(&ps3av->done); |
735 | ps3av.ps3av_mode_old = ps3av.ps3av_mode; | 765 | ps3av->ps3av_mode_old = ps3av->ps3av_mode; |
736 | ps3av.ps3av_mode = id; | 766 | ps3av->ps3av_mode = id; |
737 | if (ps3av_set_videomode()) | 767 | if (ps3av_set_videomode()) |
738 | ps3av.ps3av_mode = ps3av.ps3av_mode_old; | 768 | ps3av->ps3av_mode = ps3av->ps3av_mode_old; |
739 | 769 | ||
740 | return 0; | 770 | return 0; |
741 | } | 771 | } |
@@ -744,7 +774,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_video_mode); | |||
744 | 774 | ||
745 | int ps3av_get_auto_mode(int boot) | 775 | int ps3av_get_auto_mode(int boot) |
746 | { | 776 | { |
747 | return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); | 777 | return ps3av_auto_videomode(&ps3av->av_hw_conf, boot); |
748 | } | 778 | } |
749 | 779 | ||
750 | EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); | 780 | EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); |
@@ -772,7 +802,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_mode); | |||
772 | 802 | ||
773 | int ps3av_get_mode(void) | 803 | int ps3av_get_mode(void) |
774 | { | 804 | { |
775 | return ps3av.ps3av_mode; | 805 | return ps3av ? ps3av->ps3av_mode : 0; |
776 | } | 806 | } |
777 | 807 | ||
778 | EXPORT_SYMBOL_GPL(ps3av_get_mode); | 808 | EXPORT_SYMBOL_GPL(ps3av_get_mode); |
@@ -842,82 +872,65 @@ int ps3av_audio_mute(int mute) | |||
842 | 872 | ||
843 | EXPORT_SYMBOL_GPL(ps3av_audio_mute); | 873 | EXPORT_SYMBOL_GPL(ps3av_audio_mute); |
844 | 874 | ||
845 | int ps3av_dev_open(void) | 875 | void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), |
876 | void *flip_data) | ||
846 | { | 877 | { |
847 | int status = 0; | 878 | mutex_lock(&ps3av->mutex); |
848 | 879 | ps3av->flip_ctl = flip_ctl; | |
849 | mutex_lock(&ps3av.mutex); | 880 | ps3av->flip_data = flip_data; |
850 | if (!ps3av.open_count++) { | 881 | mutex_unlock(&ps3av->mutex); |
851 | status = lv1_gpu_open(0); | ||
852 | if (status) { | ||
853 | printk(KERN_ERR "%s: lv1_gpu_open failed %d\n", | ||
854 | __func__, status); | ||
855 | ps3av.open_count--; | ||
856 | } | ||
857 | } | ||
858 | mutex_unlock(&ps3av.mutex); | ||
859 | |||
860 | return status; | ||
861 | } | 882 | } |
883 | EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl); | ||
862 | 884 | ||
863 | EXPORT_SYMBOL_GPL(ps3av_dev_open); | 885 | void ps3av_flip_ctl(int on) |
864 | |||
865 | int ps3av_dev_close(void) | ||
866 | { | 886 | { |
867 | int status = 0; | 887 | mutex_lock(&ps3av->mutex); |
868 | 888 | if (ps3av->flip_ctl) | |
869 | mutex_lock(&ps3av.mutex); | 889 | ps3av->flip_ctl(on, ps3av->flip_data); |
870 | if (ps3av.open_count <= 0) { | 890 | mutex_unlock(&ps3av->mutex); |
871 | printk(KERN_ERR "%s: GPU already closed\n", __func__); | ||
872 | status = -1; | ||
873 | } else if (!--ps3av.open_count) { | ||
874 | status = lv1_gpu_close(); | ||
875 | if (status) | ||
876 | printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n", | ||
877 | __func__, status); | ||
878 | } | ||
879 | mutex_unlock(&ps3av.mutex); | ||
880 | |||
881 | return status; | ||
882 | } | 891 | } |
883 | 892 | ||
884 | EXPORT_SYMBOL_GPL(ps3av_dev_close); | 893 | static int ps3av_probe(struct ps3_system_bus_device *dev) |
885 | |||
886 | static int ps3av_probe(struct ps3_vuart_port_device *dev) | ||
887 | { | 894 | { |
888 | int res; | 895 | int res; |
889 | u32 id; | 896 | u32 id; |
890 | 897 | ||
891 | dev_dbg(&ps3av_dev.core, "init ...\n"); | 898 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); |
892 | dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout); | 899 | dev_dbg(&dev->core, " timeout=%d\n", timeout); |
893 | 900 | ||
894 | memset(&ps3av, 0, sizeof(ps3av)); | 901 | if (ps3av) { |
895 | 902 | dev_err(&dev->core, "Only one ps3av device is supported\n"); | |
896 | mutex_init(&ps3av.mutex); | 903 | return -EBUSY; |
897 | ps3av.ps3av_mode = 0; | 904 | } |
898 | ps3av.dev = dev; | ||
899 | 905 | ||
900 | INIT_WORK(&ps3av.work, ps3avd); | 906 | ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL); |
901 | init_completion(&ps3av.done); | 907 | if (!ps3av) |
902 | complete(&ps3av.done); | ||
903 | ps3av.wq = create_singlethread_workqueue("ps3avd"); | ||
904 | if (!ps3av.wq) | ||
905 | return -ENOMEM; | 908 | return -ENOMEM; |
906 | 909 | ||
907 | ps3av.available = 1; | 910 | mutex_init(&ps3av->mutex); |
911 | ps3av->ps3av_mode = 0; | ||
912 | ps3av->dev = dev; | ||
913 | |||
914 | INIT_WORK(&ps3av->work, ps3avd); | ||
915 | init_completion(&ps3av->done); | ||
916 | complete(&ps3av->done); | ||
917 | ps3av->wq = create_singlethread_workqueue("ps3avd"); | ||
918 | if (!ps3av->wq) | ||
919 | goto fail; | ||
920 | |||
908 | switch (ps3_os_area_get_av_multi_out()) { | 921 | switch (ps3_os_area_get_av_multi_out()) { |
909 | case PS3_PARAM_AV_MULTI_OUT_NTSC: | 922 | case PS3_PARAM_AV_MULTI_OUT_NTSC: |
910 | ps3av.region = PS3AV_REGION_60; | 923 | ps3av->region = PS3AV_REGION_60; |
911 | break; | 924 | break; |
912 | case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: | 925 | case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: |
913 | case PS3_PARAM_AV_MULTI_OUT_SECAM: | 926 | case PS3_PARAM_AV_MULTI_OUT_SECAM: |
914 | ps3av.region = PS3AV_REGION_50; | 927 | ps3av->region = PS3AV_REGION_50; |
915 | break; | 928 | break; |
916 | case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: | 929 | case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: |
917 | ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB; | 930 | ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB; |
918 | break; | 931 | break; |
919 | default: | 932 | default: |
920 | ps3av.region = PS3AV_REGION_60; | 933 | ps3av->region = PS3AV_REGION_60; |
921 | break; | 934 | break; |
922 | } | 935 | } |
923 | 936 | ||
@@ -927,39 +940,47 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev) | |||
927 | printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, | 940 | printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, |
928 | res); | 941 | res); |
929 | 942 | ||
930 | ps3av_get_hw_conf(&ps3av); | 943 | ps3av_get_hw_conf(ps3av); |
931 | id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1); | 944 | id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1); |
932 | mutex_lock(&ps3av.mutex); | 945 | mutex_lock(&ps3av->mutex); |
933 | ps3av.ps3av_mode = id; | 946 | ps3av->ps3av_mode = id; |
934 | mutex_unlock(&ps3av.mutex); | 947 | mutex_unlock(&ps3av->mutex); |
935 | 948 | ||
936 | dev_dbg(&ps3av_dev.core, "init...done\n"); | 949 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); |
937 | 950 | ||
938 | return 0; | 951 | return 0; |
952 | |||
953 | fail: | ||
954 | kfree(ps3av); | ||
955 | ps3av = NULL; | ||
956 | return -ENOMEM; | ||
939 | } | 957 | } |
940 | 958 | ||
941 | static int ps3av_remove(struct ps3_vuart_port_device *dev) | 959 | static int ps3av_remove(struct ps3_system_bus_device *dev) |
942 | { | 960 | { |
943 | if (ps3av.available) { | 961 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); |
962 | if (ps3av) { | ||
944 | ps3av_cmd_fin(); | 963 | ps3av_cmd_fin(); |
945 | if (ps3av.wq) | 964 | if (ps3av->wq) |
946 | destroy_workqueue(ps3av.wq); | 965 | destroy_workqueue(ps3av->wq); |
947 | ps3av.available = 0; | 966 | kfree(ps3av); |
967 | ps3av = NULL; | ||
948 | } | 968 | } |
949 | 969 | ||
970 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | ||
950 | return 0; | 971 | return 0; |
951 | } | 972 | } |
952 | 973 | ||
953 | static void ps3av_shutdown(struct ps3_vuart_port_device *dev) | 974 | static void ps3av_shutdown(struct ps3_system_bus_device *dev) |
954 | { | 975 | { |
976 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); | ||
955 | ps3av_remove(dev); | 977 | ps3av_remove(dev); |
978 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | ||
956 | } | 979 | } |
957 | 980 | ||
958 | static struct ps3_vuart_port_driver ps3av_driver = { | 981 | static struct ps3_vuart_port_driver ps3av_driver = { |
959 | .match_id = PS3_MATCH_ID_AV_SETTINGS, | 982 | .core.match_id = PS3_MATCH_ID_AV_SETTINGS, |
960 | .core = { | 983 | .core.core.name = "ps3_av", |
961 | .name = "ps3_av", | ||
962 | }, | ||
963 | .probe = ps3av_probe, | 984 | .probe = ps3av_probe, |
964 | .remove = ps3av_remove, | 985 | .remove = ps3av_remove, |
965 | .shutdown = ps3av_shutdown, | 986 | .shutdown = ps3av_shutdown, |
@@ -972,6 +993,8 @@ static int ps3av_module_init(void) | |||
972 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | 993 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) |
973 | return -ENODEV; | 994 | return -ENODEV; |
974 | 995 | ||
996 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | ||
997 | |||
975 | error = ps3_vuart_port_driver_register(&ps3av_driver); | 998 | error = ps3_vuart_port_driver_register(&ps3av_driver); |
976 | if (error) { | 999 | if (error) { |
977 | printk(KERN_ERR | 1000 | printk(KERN_ERR |
@@ -980,20 +1003,21 @@ static int ps3av_module_init(void) | |||
980 | return error; | 1003 | return error; |
981 | } | 1004 | } |
982 | 1005 | ||
983 | error = ps3_vuart_port_device_register(&ps3av_dev); | 1006 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
984 | if (error) | ||
985 | printk(KERN_ERR | ||
986 | "%s: ps3_vuart_port_device_register failed %d\n", | ||
987 | __func__, error); | ||
988 | |||
989 | return error; | 1007 | return error; |
990 | } | 1008 | } |
991 | 1009 | ||
992 | static void __exit ps3av_module_exit(void) | 1010 | static void __exit ps3av_module_exit(void) |
993 | { | 1011 | { |
994 | device_unregister(&ps3av_dev.core); | 1012 | pr_debug(" -> %s:%d\n", __func__, __LINE__); |
995 | ps3_vuart_port_driver_unregister(&ps3av_driver); | 1013 | ps3_vuart_port_driver_unregister(&ps3av_driver); |
1014 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
996 | } | 1015 | } |
997 | 1016 | ||
998 | subsys_initcall(ps3av_module_init); | 1017 | subsys_initcall(ps3av_module_init); |
999 | module_exit(ps3av_module_exit); | 1018 | module_exit(ps3av_module_exit); |
1019 | |||
1020 | MODULE_LICENSE("GPL v2"); | ||
1021 | MODULE_DESCRIPTION("PS3 AV Settings Driver"); | ||
1022 | MODULE_AUTHOR("Sony Computer Entertainment Inc."); | ||
1023 | MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS); | ||