From: Geoff Levand <geoffrey.levand@am.sony.com>
To: paulus@samba.org
Cc: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>,
linuxppc-dev@ozlabs.org
Subject: [patch 17/30] PS3: Rework AV settings driver
Date: Tue, 12 Jun 2007 11:53:31 -0700 [thread overview]
Message-ID: <466EEBAB.4040509@am.sony.com> (raw)
In-Reply-To: <20070612181825.730300780@am.sony.com>>
Make the PS3 ps3av driver a loadable module.
- Replace static data with malloc'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>
---
drivers/ps3/Makefile | 3
drivers/ps3/ps3av.c | 369 +++++++++++++++++++++++---------------------
drivers/ps3/ps3av_cmd.c | 35 ----
include/asm-powerpc/ps3av.h | 36 ++--
4 files changed, 219 insertions(+), 224 deletions(-)
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_PS3_VUART) += vuart.o
-obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o
+obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o
+ps3av_mod-objs += ps3av.o ps3av_cmd.o
obj-$(CONFIG_PPC_PS3) += sys-manager-core.o
obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -1,32 +1,30 @@
/*
- * Copyright (C) 2006 Sony Computer Entertainment Inc.
- * Copyright 2006, 2007 Sony Corporation
+ * PS3 AV backend support.
*
- * AV backend support for PS3
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published
- * by the Free Software Foundation; version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/kernel.h>
#include <linux/ioctl.h>
#include <asm/firmware.h>
-#include <asm/lv1call.h>
#include <asm/ps3av.h>
#include <asm/ps3.h>
@@ -39,13 +37,12 @@ static int timeout = 5000; /* in msec (
module_param(timeout, int, 0644);
static struct ps3av {
- int available;
struct mutex mutex;
struct work_struct work;
struct completion done;
struct workqueue_struct *wq;
int open_count;
- struct ps3_vuart_port_device *dev;
+ struct ps3_system_bus_device *dev;
int region;
struct ps3av_pkt_av_get_hw_conf av_hw_conf;
@@ -55,11 +52,13 @@ static struct ps3av {
u32 audio_port;
int ps3av_mode;
int ps3av_mode_old;
-} ps3av;
-
-static struct ps3_vuart_port_device ps3av_dev = {
- .match_id = PS3_MATCH_ID_AV_SETTINGS
-};
+ union {
+ struct ps3av_reply_hdr reply_hdr;
+ u8 raw[PS3AV_BUF_SIZE];
+ } recv_buf;
+ void (*flip_ctl)(int on, void *data);
+ void *flip_data;
+} *ps3av;
/* color space */
#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
@@ -169,7 +168,7 @@ static int ps3av_parse_event_packet(cons
if (hdr->cid & PS3AV_EVENT_CMD_MASK) {
table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK);
if (table)
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"recv event packet cid:%08x port:0x%x size:%d\n",
hdr->cid, ps3av_event_get_port_id(hdr->cid),
hdr->size);
@@ -182,6 +181,41 @@ static int ps3av_parse_event_packet(cons
return 0;
}
+
+#define POLLING_INTERVAL 25 /* in msec */
+
+static int ps3av_vuart_write(struct ps3_system_bus_device *dev,
+ const void *buf, unsigned long size)
+{
+ int error;
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
+ error = ps3_vuart_write(dev, buf, size);
+ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
+ return error ? error : size;
+}
+
+static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf,
+ unsigned long size, int timeout)
+{
+ int error;
+ int loopcnt = 0;
+
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
+ timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
+ while (loopcnt++ <= timeout) {
+ error = ps3_vuart_read(dev, buf, size);
+ if (!error)
+ return size;
+ if (error != -EAGAIN) {
+ printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
+ __func__, error);
+ return error;
+ }
+ msleep(POLLING_INTERVAL);
+ }
+ return -EWOULDBLOCK;
+}
+
static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
struct ps3av_reply_hdr *recv_buf, int write_len,
int read_len)
@@ -190,13 +224,13 @@ static int ps3av_send_cmd_pkt(const stru
u32 cmd;
int event;
- if (!ps3av.available)
+ if (!ps3av)
return -ENODEV;
/* send pkt */
- res = ps3av_vuart_write(ps3av.dev, send_buf, write_len);
+ res = ps3av_vuart_write(ps3av->dev, send_buf, write_len);
if (res < 0) {
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"%s: ps3av_vuart_write() failed (result=%d)\n",
__func__, res);
return res;
@@ -206,20 +240,20 @@ static int ps3av_send_cmd_pkt(const stru
cmd = send_buf->cid;
do {
/* read header */
- res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE,
+ res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE,
timeout);
if (res != PS3AV_HDR_SIZE) {
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"%s: ps3av_vuart_read() failed (result=%d)\n",
__func__, res);
return res;
}
/* read body */
- res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid,
+ res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid,
recv_buf->size, timeout);
if (res < 0) {
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"%s: ps3av_vuart_read() failed (result=%d)\n",
__func__, res);
return res;
@@ -230,7 +264,7 @@ static int ps3av_send_cmd_pkt(const stru
} while (event);
if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
- dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n",
+ dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n",
__func__, recv_buf->cid);
return -EINVAL;
}
@@ -245,7 +279,7 @@ static int ps3av_process_reply_packet(st
int return_len;
if (recv_buf->version != PS3AV_VERSION) {
- dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n",
+ dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n",
recv_buf->version);
return -EFAULT;
}
@@ -267,16 +301,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len,
struct ps3av_send_hdr *buf)
{
int res = 0;
- static union {
- struct ps3av_reply_hdr reply_hdr;
- u8 raw[PS3AV_BUF_SIZE];
- } recv_buf;
-
u32 *table;
- BUG_ON(!ps3av.available);
+ BUG_ON(!ps3av);
- mutex_lock(&ps3av.mutex);
+ mutex_lock(&ps3av->mutex);
table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
BUG_ON(!table);
@@ -288,7 +317,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len,
ps3av_set_hdr(cid, send_len, buf);
/* send packet via vuart */
- res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len,
+ res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len,
usr_buf_size);
if (res < 0) {
printk(KERN_ERR
@@ -298,7 +327,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len,
}
/* process reply packet */
- res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr,
+ res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr,
usr_buf_size);
if (res < 0) {
printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
@@ -306,11 +335,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len,
goto err;
}
- mutex_unlock(&ps3av.mutex);
+ mutex_unlock(&ps3av->mutex);
return 0;
err:
- mutex_unlock(&ps3av.mutex);
+ mutex_unlock(&ps3av->mutex);
printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
return res;
}
@@ -319,11 +348,11 @@ static int ps3av_set_av_video_mute(u32 m
{
int i, num_of_av_port, res;
- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
- ps3av.av_hw_conf.num_of_avmulti;
+ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
+ ps3av->av_hw_conf.num_of_avmulti;
/* video mute on */
for (i = 0; i < num_of_av_port; i++) {
- res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute);
+ res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute);
if (res < 0)
return -1;
}
@@ -335,13 +364,13 @@ static int ps3av_set_video_disable_sig(v
{
int i, num_of_hdmi_port, num_of_av_port, res;
- num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi;
- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
- ps3av.av_hw_conf.num_of_avmulti;
+ num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi;
+ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
+ ps3av->av_hw_conf.num_of_avmulti;
/* tv mute */
for (i = 0; i < num_of_hdmi_port; i++) {
- res = ps3av_cmd_av_tv_mute(ps3av.av_port[i],
+ res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
PS3AV_CMD_MUTE_ON);
if (res < 0)
return -1;
@@ -350,11 +379,11 @@ static int ps3av_set_video_disable_sig(v
/* video mute on */
for (i = 0; i < num_of_av_port; i++) {
- res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]);
+ res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]);
if (res < 0)
return -1;
if (i < num_of_hdmi_port) {
- res = ps3av_cmd_av_tv_mute(ps3av.av_port[i],
+ res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
PS3AV_CMD_MUTE_OFF);
if (res < 0)
return -1;
@@ -369,17 +398,17 @@ static int ps3av_set_audio_mute(u32 mute
{
int i, num_of_av_port, num_of_opt_port, res;
- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
- ps3av.av_hw_conf.num_of_avmulti;
- num_of_opt_port = ps3av.av_hw_conf.num_of_spdif;
+ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
+ ps3av->av_hw_conf.num_of_avmulti;
+ num_of_opt_port = ps3av->av_hw_conf.num_of_spdif;
for (i = 0; i < num_of_av_port; i++) {
- res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute);
+ res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute);
if (res < 0)
return -1;
}
for (i = 0; i < num_of_opt_port; i++) {
- res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute);
+ res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute);
if (res < 0)
return -1;
}
@@ -394,40 +423,40 @@ int ps3av_set_audio_mode(u32 ch, u32 fs,
struct ps3av_pkt_audio_mode audio_mode;
u32 len = 0;
- num_of_audio = ps3av.av_hw_conf.num_of_hdmi +
- ps3av.av_hw_conf.num_of_avmulti +
- ps3av.av_hw_conf.num_of_spdif;
+ num_of_audio = ps3av->av_hw_conf.num_of_hdmi +
+ ps3av->av_hw_conf.num_of_avmulti +
+ ps3av->av_hw_conf.num_of_spdif;
avb_param.num_of_video_pkt = 0;
avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */
avb_param.num_of_av_video_pkt = 0;
- avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi;
+ avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi;
- vid = video_mode_table[ps3av.ps3av_mode].vid;
+ vid = video_mode_table[ps3av->ps3av_mode].vid;
/* audio mute */
ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON);
/* audio inactive */
- res = ps3av_cmd_audio_active(0, ps3av.audio_port);
+ res = ps3av_cmd_audio_active(0, ps3av->audio_port);
if (res < 0)
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"ps3av_cmd_audio_active OFF failed\n");
/* audio_pkt */
for (i = 0; i < num_of_audio; i++) {
- ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs,
- word_bits, format, source);
- if (i < ps3av.av_hw_conf.num_of_hdmi) {
+ ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch,
+ fs, word_bits, format, source);
+ if (i < ps3av->av_hw_conf.num_of_hdmi) {
/* hdmi only */
len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len],
- ps3av.av_port[i],
+ ps3av->av_port[i],
&audio_mode, vid);
}
/* audio_mode pkt should be sent separately */
res = ps3av_cmd_audio_mode(&audio_mode);
if (res < 0)
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"ps3av_cmd_audio_mode failed, port:%x\n", i);
}
@@ -435,15 +464,15 @@ int ps3av_set_audio_mode(u32 ch, u32 fs,
len += offsetof(struct ps3av_pkt_avb_param, buf);
res = ps3av_cmd_avb_param(&avb_param, len);
if (res < 0)
- dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
+ dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
/* audio mute */
ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF);
/* audio active */
- res = ps3av_cmd_audio_active(1, ps3av.audio_port);
+ res = ps3av_cmd_audio_active(1, ps3av->audio_port);
if (res < 0)
- dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n");
+ dev_dbg(&ps3av->dev->core, "ps3av_cmd_audio_active ON failed\n");
return 0;
}
@@ -456,7 +485,7 @@ static int ps3av_set_videomode(void)
ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
/* wake up ps3avd to do the actual video mode setting */
- queue_work(ps3av.wq, &ps3av.work);
+ queue_work(ps3av->wq, &ps3av->work);
return 0;
}
@@ -473,8 +502,8 @@ static void ps3av_set_videomode_cont(u32
avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */
avb_param.num_of_audio_pkt = 0;
- avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi +
- ps3av.av_hw_conf.num_of_avmulti;
+ avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi +
+ ps3av->av_hw_conf.num_of_avmulti;
avb_param.num_of_av_audio_pkt = 0;
/* video signal off */
@@ -484,21 +513,21 @@ static void ps3av_set_videomode_cont(u32
if (id & PS3AV_MODE_HDCP_OFF) {
res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
- dev_dbg(&ps3av_dev.core, "Not supported\n");
+ dev_dbg(&ps3av->dev->core, "Not supported\n");
else if (res)
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"ps3av_cmd_av_hdmi_mode failed\n");
} else if (old_id & PS3AV_MODE_HDCP_OFF) {
res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
- dev_dbg(&ps3av_dev.core,
+ dev_dbg(&ps3av->dev->core,
"ps3av_cmd_av_hdmi_mode failed\n");
}
/* video_pkt */
for (i = 0; i < avb_param.num_of_video_pkt; i++)
len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
- ps3av.head[i], video_mode->vid,
+ ps3av->head[i], video_mode->vid,
video_mode->fmt, id);
/* av_video_pkt */
for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
@@ -507,12 +536,12 @@ static void ps3av_set_videomode_cont(u32
else
av_video_cs = video_mode->cs;
#ifndef PS3AV_HDMI_YUV
- if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
- ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
+ if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
+ ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
av_video_cs = RGB8; /* use RGB for HDMI */
#endif
len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len],
- ps3av.av_port[i],
+ ps3av->av_port[i],
video_mode->vid, av_video_cs,
video_mode->aspect, id);
}
@@ -524,7 +553,7 @@ static void ps3av_set_videomode_cont(u32
"%s: Command failed. Please try your request again. \n",
__func__);
else if (res)
- dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
+ dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
msleep(1500);
/* av video mute */
@@ -533,8 +562,8 @@ static void ps3av_set_videomode_cont(u32
static void ps3avd(struct work_struct *work)
{
- ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old);
- complete(&ps3av.done);
+ ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old);
+ complete(&ps3av->done);
}
static int ps3av_vid2table_id(int vid)
@@ -601,7 +630,7 @@ static int ps3av_hdmi_get_vid(struct ps3
return vid;
}
- if (ps3av.region & PS3AV_REGION_60)
+ if (ps3av->region & PS3AV_REGION_60)
vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
else
vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
@@ -643,16 +672,16 @@ static int ps3av_auto_videomode(struct p
vid = PS3AV_DEFAULT_DVI_VID;
} else if (vid == -1) {
/* no HDMI interface or HDMI is off */
- if (ps3av.region & PS3AV_REGION_60)
+ if (ps3av->region & PS3AV_REGION_60)
vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60;
else
vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50;
- if (ps3av.region & PS3AV_REGION_RGB)
+ if (ps3av->region & PS3AV_REGION_RGB)
rgb = PS3AV_MODE_RGB;
} else if (boot) {
/* HDMI: using DEFAULT HDMI_VID while booting up */
info = &monitor_info.info;
- if (ps3av.region & PS3AV_REGION_60) {
+ if (ps3av->region & PS3AV_REGION_60) {
if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
@@ -715,14 +744,14 @@ int ps3av_set_video_mode(u32 id, int boo
size = ARRAY_SIZE(video_mode_table);
if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
- dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id);
+ dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id);
return -EINVAL;
}
/* auto mode */
option = id & ~PS3AV_MODE_MASK;
if ((id & PS3AV_MODE_MASK) == 0) {
- id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
+ id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
if (id < 1) {
printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
return -EINVAL;
@@ -731,11 +760,11 @@ int ps3av_set_video_mode(u32 id, int boo
}
/* set videomode */
- wait_for_completion(&ps3av.done);
- ps3av.ps3av_mode_old = ps3av.ps3av_mode;
- ps3av.ps3av_mode = id;
+ wait_for_completion(&ps3av->done);
+ ps3av->ps3av_mode_old = ps3av->ps3av_mode;
+ ps3av->ps3av_mode = id;
if (ps3av_set_videomode())
- ps3av.ps3av_mode = ps3av.ps3av_mode_old;
+ ps3av->ps3av_mode = ps3av->ps3av_mode_old;
return 0;
}
@@ -744,7 +773,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
int ps3av_get_auto_mode(int boot)
{
- return ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
+ return ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
}
EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
@@ -772,7 +801,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_mode);
int ps3av_get_mode(void)
{
- return ps3av.ps3av_mode;
+ return ps3av ? ps3av->ps3av_mode : 0;
}
EXPORT_SYMBOL_GPL(ps3av_get_mode);
@@ -842,82 +871,65 @@ int ps3av_audio_mute(int mute)
EXPORT_SYMBOL_GPL(ps3av_audio_mute);
-int ps3av_dev_open(void)
+void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
+ void *flip_data)
{
- int status = 0;
-
- mutex_lock(&ps3av.mutex);
- if (!ps3av.open_count++) {
- status = lv1_gpu_open(0);
- if (status) {
- printk(KERN_ERR "%s: lv1_gpu_open failed %d\n",
- __func__, status);
- ps3av.open_count--;
- }
- }
- mutex_unlock(&ps3av.mutex);
-
- return status;
+ mutex_lock(&ps3av->mutex);
+ ps3av->flip_ctl = flip_ctl;
+ ps3av->flip_data = flip_data;
+ mutex_unlock(&ps3av->mutex);
}
+EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl);
-EXPORT_SYMBOL_GPL(ps3av_dev_open);
-
-int ps3av_dev_close(void)
+void ps3av_flip_ctl(int on)
{
- int status = 0;
-
- mutex_lock(&ps3av.mutex);
- if (ps3av.open_count <= 0) {
- printk(KERN_ERR "%s: GPU already closed\n", __func__);
- status = -1;
- } else if (!--ps3av.open_count) {
- status = lv1_gpu_close();
- if (status)
- printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n",
- __func__, status);
- }
- mutex_unlock(&ps3av.mutex);
-
- return status;
+ mutex_lock(&ps3av->mutex);
+ if (ps3av->flip_ctl)
+ ps3av->flip_ctl(on, ps3av->flip_data);
+ mutex_unlock(&ps3av->mutex);
}
-EXPORT_SYMBOL_GPL(ps3av_dev_close);
-
-static int ps3av_probe(struct ps3_vuart_port_device *dev)
+static int ps3av_probe(struct ps3_system_bus_device *dev)
{
int res;
u32 id;
- dev_dbg(&ps3av_dev.core, "init ...\n");
- dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout);
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
+ dev_dbg(&dev->core, " timeout=%d\n", timeout);
- memset(&ps3av, 0, sizeof(ps3av));
+ if (ps3av) {
+ dev_err(&dev->core, "Only one ps3av device is supported\n");
+ return -EBUSY;
+ }
- mutex_init(&ps3av.mutex);
- ps3av.ps3av_mode = 0;
- ps3av.dev = dev;
-
- INIT_WORK(&ps3av.work, ps3avd);
- init_completion(&ps3av.done);
- complete(&ps3av.done);
- ps3av.wq = create_singlethread_workqueue("ps3avd");
- if (!ps3av.wq)
+ ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL);
+ if (!ps3av)
return -ENOMEM;
- ps3av.available = 1;
+ mutex_init(&ps3av->mutex);
+ ps3av->ps3av_mode = 0;
+ ps3av->dev = dev;
+
+ INIT_WORK(&ps3av->work, ps3avd);
+ init_completion(&ps3av->done);
+ complete(&ps3av->done);
+ ps3av->wq = create_singlethread_workqueue("ps3avd");
+ if (!ps3av->wq)
+ goto fail;
+
switch (ps3_os_area_get_av_multi_out()) {
case PS3_PARAM_AV_MULTI_OUT_NTSC:
- ps3av.region = PS3AV_REGION_60;
+ ps3av->region = PS3AV_REGION_60;
break;
case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR:
case PS3_PARAM_AV_MULTI_OUT_SECAM:
- ps3av.region = PS3AV_REGION_50;
+ ps3av->region = PS3AV_REGION_50;
break;
case PS3_PARAM_AV_MULTI_OUT_PAL_RGB:
- ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
+ ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
break;
default:
- ps3av.region = PS3AV_REGION_60;
+ ps3av->region = PS3AV_REGION_60;
break;
}
@@ -927,38 +939,48 @@ static int ps3av_probe(struct ps3_vuart_
printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__,
res);
- ps3av_get_hw_conf(&ps3av);
- id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1);
- mutex_lock(&ps3av.mutex);
- ps3av.ps3av_mode = id;
- mutex_unlock(&ps3av.mutex);
+ ps3av_get_hw_conf(ps3av);
+ id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1);
+ mutex_lock(&ps3av->mutex);
+ ps3av->ps3av_mode = id;
+ mutex_unlock(&ps3av->mutex);
- dev_dbg(&ps3av_dev.core, "init...done\n");
+ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
return 0;
+
+fail:
+ kfree(ps3av);
+ ps3av = NULL;
+ return -ENOMEM;
}
-static int ps3av_remove(struct ps3_vuart_port_device *dev)
+static int ps3av_remove(struct ps3_system_bus_device *dev)
{
- if (ps3av.available) {
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
+ if (ps3av) {
ps3av_cmd_fin();
- if (ps3av.wq)
- destroy_workqueue(ps3av.wq);
- ps3av.available = 0;
+ if (ps3av->wq)
+ destroy_workqueue(ps3av->wq);
+ kfree(ps3av);
+ ps3av = NULL;
}
+ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
return 0;
}
-static void ps3av_shutdown(struct ps3_vuart_port_device *dev)
+static void ps3av_shutdown(struct ps3_system_bus_device *dev)
{
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
ps3av_remove(dev);
+ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
}
static struct ps3_vuart_port_driver ps3av_driver = {
- .match_id = PS3_MATCH_ID_AV_SETTINGS,
.core = {
- .name = "ps3_av",
+ .match_id = PS3_MATCH_ID_AV_SETTINGS,
+ .core = {.name = "ps3_av",},
},
.probe = ps3av_probe,
.remove = ps3av_remove,
@@ -972,6 +994,8 @@ static int ps3av_module_init(void)
if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
return -ENODEV;
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
error = ps3_vuart_port_driver_register(&ps3av_driver);
if (error) {
printk(KERN_ERR
@@ -980,20 +1004,21 @@ static int ps3av_module_init(void)
return error;
}
- error = ps3_vuart_port_device_register(&ps3av_dev);
- if (error)
- printk(KERN_ERR
- "%s: ps3_vuart_port_device_register failed %d\n",
- __func__, error);
-
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
return error;
}
static void __exit ps3av_module_exit(void)
{
- device_unregister(&ps3av_dev.core);
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
ps3_vuart_port_driver_unregister(&ps3av_driver);
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
subsys_initcall(ps3av_module_init);
module_exit(ps3av_module_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PS3 AV Settings Driver");
+MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS);
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -868,7 +868,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt
{
int res;
- ps3fb_flip_ctl(0); /* flip off */
+ ps3av_flip_ctl(0); /* flip off */
/* avb packet */
res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb),
@@ -882,7 +882,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt
res);
out:
- ps3fb_flip_ctl(1); /* flip on */
+ ps3av_flip_ctl(1); /* flip on */
return res;
}
@@ -1003,34 +1003,3 @@ void ps3av_cmd_av_monitor_info_dump(cons
| PS3AV_CMD_AV_LAYOUT_176 \
| PS3AV_CMD_AV_LAYOUT_192)
-/************************* vuart ***************************/
-
-#define POLLING_INTERVAL 25 /* in msec */
-
-int ps3av_vuart_write(struct ps3_vuart_port_device *dev, const void *buf,
- unsigned long size)
-{
- int error = ps3_vuart_write(dev, buf, size);
- return error ? error : size;
-}
-
-int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
- unsigned long size, int timeout)
-{
- int error;
- int loopcnt = 0;
-
- timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
- while (loopcnt++ <= timeout) {
- error = ps3_vuart_read(dev, buf, size);
- if (!error)
- return size;
- if (error != -EAGAIN) {
- printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
- __func__, error);
- return error;
- }
- msleep(POLLING_INTERVAL);
- }
- return -EWOULDBLOCK;
-}
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -1,20 +1,23 @@
/*
- * Copyright (C) 2006 Sony Computer Entertainment Inc.
- * Copyright 2006, 2007 Sony Corporation
+ * PS3 AV backend support.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published
- * by the Free Software Foundation; version 2 of the License.
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#ifndef _ASM_POWERPC_PS3AV_H_
#define _ASM_POWERPC_PS3AV_H_
@@ -704,12 +707,6 @@ static inline void ps3av_cmd_av_monitor_
extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
u32);
-struct ps3_vuart_port_device;
-extern int ps3av_vuart_write(struct ps3_vuart_port_device *dev,
- const void *buf, unsigned long size);
-extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
- unsigned long size, int timeout);
-
extern int ps3av_set_video_mode(u32, int);
extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
extern int ps3av_get_auto_mode(int);
@@ -722,5 +719,8 @@ extern int ps3av_video_mute(int);
extern int ps3av_audio_mute(int);
extern int ps3av_dev_open(void);
extern int ps3av_dev_close(void);
+extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
+ void *flip_data);
+extern void ps3av_flip_ctl(int on);
#endif /* _ASM_POWERPC_PS3AV_H_ */
--
next prev parent reply other threads:[~2007-06-12 18:55 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20070612181825.730300780@am.sony.com>
2007-06-12 18:42 ` [patch 01/30] Cell: Add spu shutdown method Geoff Levand
2007-06-12 18:43 ` [patch 02/30] PS3: Rename IPI symbols Geoff Levand
2007-06-12 18:43 ` [patch 03/30] PS3: Use __maybe_unused Geoff Levand
2007-06-12 18:43 ` [patch 04/30] PS3: Compare firmware version Geoff Levand
2007-06-12 18:43 ` [patch 05/30] PS3: Use ioremap_flags Geoff Levand
2007-06-13 9:10 ` Arnd Bergmann
2007-06-14 1:42 ` Geoff Levand
2007-06-14 2:31 ` Takao Shinohara
2007-06-14 19:03 ` [patch 05/30 v2] " Geoff Levand
2007-06-14 23:43 ` Arnd Bergmann
2007-06-12 18:43 ` [patch 06/30] PS3: Fix sparse warnings Geoff Levand
2007-06-12 18:44 ` [patch 07/30] PS3: Add support for HDMI RGB Full Range mode Geoff Levand
2007-06-12 18:44 ` [patch 08/30] PS3: Move chip mask defs up Geoff Levand
2007-06-12 18:44 ` [patch 09/30] PS3: Use inline DBG Geoff Levand
2007-06-12 18:44 ` [patch 10/30] PS3: Kexec support Geoff Levand
2007-06-12 18:52 ` [patch 11/30] PS3: System-bus rework Geoff Levand
2007-06-12 18:52 ` [patch 12/30] PS3: System-bus uevent Geoff Levand
2007-06-12 18:52 ` [patch 13/30] PS3: System-bus modinfo attribute Geoff Levand
2007-06-12 18:53 ` [patch 14/30] PS3: Repository probe cleanups Geoff Levand
2007-06-12 18:53 ` [patch 15/30] PS3: Vuart rework Geoff Levand
2007-06-12 18:53 ` [patch 16/30] PS3: System manager re-work Geoff Levand
2007-06-12 18:53 ` Geoff Levand [this message]
2007-06-12 18:53 ` [patch 18/30] PS3: Frame buffer system-bus rework Geoff Levand
2007-06-12 18:53 ` Geoff Levand
2007-06-12 18:53 ` [patch 19/30] PS3: Device registration routines Geoff Levand
2007-06-12 18:53 ` [patch 20/30] PS3: Rename processor id symbols Geoff Levand
2007-06-12 18:54 ` [patch 21/30] PS3: Use clear_bit Geoff Levand
2007-06-12 18:54 ` [patch 22/30] Powerpc: Output params value in early_init_devtree Geoff Levand
2007-06-12 18:54 ` [patch 23/30] powerpc: Localize mmu_off Geoff Levand
2007-06-12 18:54 ` [patch 24/30] powerpc: Correct __secondary_hold comment Geoff Levand
2007-06-12 18:54 ` [patch 25/30] Powerpc: Add signed types to bootwrapper Geoff Levand
2007-06-12 18:54 ` [patch 26/30] Powerpc: Add u64 printf " Geoff Levand
2007-06-12 18:54 ` [patch 27/30] Powerpc: Fix constantness of bootwrapper arg Geoff Levand
2007-06-12 18:54 ` [patch 28/30] powerpc: Bootwrapper global scope kernel_entry_t Geoff Levand
2007-06-12 18:54 ` [patch 29/30] PS3: Device tree source Geoff Levand
2007-06-13 4:52 ` Segher Boessenkool
2007-06-13 8:40 ` Olaf Hering
2007-06-13 9:05 ` Segher Boessenkool
2007-06-13 11:24 ` Olaf Hering
2007-06-13 11:59 ` Segher Boessenkool
2007-06-13 12:28 ` Olaf Hering
2007-06-13 13:51 ` Segher Boessenkool
2007-06-13 16:04 ` Olaf Hering
2007-06-13 13:43 ` Geert Uytterhoeven
2007-06-13 13:52 ` Segher Boessenkool
2007-06-13 14:09 ` Geert Uytterhoeven
2007-06-13 14:18 ` Segher Boessenkool
2007-06-13 14:20 ` Geert Uytterhoeven
2007-06-13 17:36 ` Geoff Levand
2007-06-13 22:42 ` Benjamin Herrenschmidt
2007-06-14 7:31 ` Segher Boessenkool
2007-06-14 10:11 ` Benjamin Herrenschmidt
2007-06-14 10:25 ` Segher Boessenkool
2007-06-13 17:35 ` Geoff Levand
2007-06-13 18:18 ` Olaf Hering
2007-06-13 22:46 ` Benjamin Herrenschmidt
2007-06-14 7:32 ` Segher Boessenkool
2007-06-14 14:39 ` Yoder Stuart-B08248
2007-06-14 15:36 ` Segher Boessenkool
2007-06-14 15:53 ` Yoder Stuart-B08248
2007-06-15 8:32 ` Segher Boessenkool
2007-06-15 0:16 ` Benjamin Herrenschmidt
2007-06-15 8:37 ` Segher Boessenkool
2007-06-13 22:44 ` Benjamin Herrenschmidt
2007-06-14 1:31 ` Geoff Levand
2007-06-14 7:39 ` Segher Boessenkool
2007-06-14 1:31 ` [patch 29/30 v2] " Geoff Levand
2007-06-14 7:55 ` Geert Uytterhoeven
2007-06-14 17:05 ` Geoff Levand
2007-06-12 18:55 ` [patch 30/30] PS3: Bootwrapper support Geoff Levand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=466EEBAB.4040509@am.sony.com \
--to=geoffrey.levand@am.sony.com \
--cc=Geert.Uytterhoeven@sonycom.com \
--cc=linuxppc-dev@ozlabs.org \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.