Merge branch 'linux-2.6'

This commit is contained in:
Paul Mackerras
2007-05-08 13:37:51 +10:00
2278 changed files with 148154 additions and 48518 deletions

View File

@@ -32,6 +32,8 @@
#include <linux/ioctl.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <asm/uaccess.h>
#include <linux/fb.h>
@@ -45,7 +47,7 @@
#include <asm/ps3.h>
#ifdef PS3FB_DEBUG
#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
#else
#define DPRINTK(fmt, args...)
#endif
@@ -129,7 +131,6 @@ struct ps3fb_priv {
u64 context_handle, memory_handle;
void *xdr_ea;
struct gpu_driver_info *dinfo;
struct semaphore sem;
u32 res_index;
u64 vblank_count; /* frame count */
@@ -139,6 +140,8 @@ struct ps3fb_priv {
atomic_t ext_flip; /* on/off flip with vsync */
atomic_t f_count; /* fb_open count */
int is_blanked;
int is_kicked;
struct task_struct *task;
};
static struct ps3fb_priv ps3fb;
@@ -294,10 +297,10 @@ static const struct fb_videomode ps3fb_modedb[] = {
#define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP)
#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
static int ps3fb_mode = 0;
static int ps3fb_mode;
module_param(ps3fb_mode, bool, 0);
static char *mode_option __initdata = NULL;
static char *mode_option __initdata;
static int ps3fb_get_res_table(u32 xres, u32 yres)
@@ -393,7 +396,7 @@ static int ps3fb_sync(u32 frame)
if (frame > ps3fb.num_frames - 1) {
printk(KERN_WARNING "%s: invalid frame number (%u)\n",
__FUNCTION__, frame);
__func__, frame);
return -EINVAL;
}
offset = xres * yres * BPP * frame;
@@ -406,23 +409,26 @@ static int ps3fb_sync(u32 frame)
(xres << 16) | yres,
xres * BPP); /* line_length */
if (status)
printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
__func__, status);
#ifdef HEAD_A
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
0, offset, 0, 0);
if (status)
printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute FLIP failed: %d\n",
__func__, status);
#endif
#ifdef HEAD_B
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
1, offset, 0, 0);
if (status)
printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute FLIP failed: %d\n",
__func__, status);
#endif
return 0;
}
@@ -631,7 +637,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
{
int retval;
DPRINTK("%s: blank:%d\n", __FUNCTION__, blank);
DPRINTK("%s: blank:%d\n", __func__, blank);
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_HSYNC_SUSPEND:
@@ -677,13 +683,10 @@ EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
void ps3fb_flip_ctl(int on)
{
if (on) {
if (atomic_read(&ps3fb.ext_flip) > 0) {
atomic_dec(&ps3fb.ext_flip);
}
} else {
if (on)
atomic_dec_if_positive(&ps3fb.ext_flip);
else
atomic_inc(&ps3fb.ext_flip);
}
}
EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
@@ -732,6 +735,11 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
if (copy_from_user(&val, argp, sizeof(val)))
break;
if (!(val & PS3AV_MODE_MASK)) {
u32 id = ps3av_get_auto_mode(0);
if (id > 0)
val = (val & ~PS3AV_MODE_MASK) | id;
}
DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val);
retval = -EINVAL;
old_mode = ps3fb_mode;
@@ -783,8 +791,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
case PS3FB_IOCTL_OFF:
DPRINTK("PS3FB_IOCTL_OFF:\n");
if (atomic_read(&ps3fb.ext_flip) > 0)
atomic_dec(&ps3fb.ext_flip);
atomic_dec_if_positive(&ps3fb.ext_flip);
retval = 0;
break;
@@ -805,11 +812,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
static int ps3fbd(void *arg)
{
daemonize("ps3fbd");
for (;;) {
down(&ps3fb.sem);
if (atomic_read(&ps3fb.ext_flip) == 0)
while (!kthread_should_stop()) {
try_to_freeze();
set_current_state(TASK_INTERRUPTIBLE);
if (ps3fb.is_kicked) {
ps3fb.is_kicked = 0;
ps3fb_sync(0); /* single buffer */
}
schedule();
}
return 0;
}
@@ -823,15 +833,18 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n",
__FUNCTION__, status);
__func__, status);
return IRQ_NONE;
}
if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
/* VSYNC */
ps3fb.vblank_count = head->vblank_count;
if (!ps3fb.is_blanked)
up(&ps3fb.sem);
if (ps3fb.task && !ps3fb.is_blanked &&
!atomic_read(&ps3fb.ext_flip)) {
ps3fb.is_kicked = 1;
wake_up_process(ps3fb.task);
}
wake_up_interruptible(&ps3fb.wait_vsync);
}
@@ -879,7 +892,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
printk(KERN_ERR "%s: version_driver err:%x\n", __FUNCTION__,
printk(KERN_ERR "%s: version_driver err:%x\n", __func__,
dinfo->version_driver);
return -EINVAL;
}
@@ -888,7 +901,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
&ps3fb.irq_no);
if (error) {
printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__,
printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__,
error);
return error;
}
@@ -896,7 +909,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
"ps3fb vsync", ps3fb.dev);
if (error) {
printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__,
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
error);
ps3_irq_plug_destroy(ps3fb.irq_no);
return error;
@@ -915,7 +928,7 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
xdr_lpar, ps3fb_videomemory.size, 0);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n",
__FUNCTION__, status);
__func__, status);
return -ENXIO;
}
DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
@@ -927,8 +940,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
xdr_lpar, ps3fb_videomemory.size,
GPU_IOIF, 0);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
__func__, status);
return -ENXIO;
}
return 0;
@@ -968,13 +982,14 @@ static int __init ps3fb_probe(struct platform_device *dev)
u64 xdr_lpar;
int status;
unsigned long offset;
struct task_struct *task;
/* get gpu context handle */
status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
&ps3fb.memory_handle, &ddr_lpar);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n",
__FUNCTION__, status);
__func__, status);
goto err;
}
DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar);
@@ -985,14 +1000,14 @@ static int __init ps3fb_probe(struct platform_device *dev)
&lpar_reports, &lpar_reports_size);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n",
__FUNCTION__, status);
__func__, status);
goto err_gpu_memory_free;
}
/* vsync interrupt */
ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
if (!ps3fb.dinfo) {
printk(KERN_ERR "%s: ioremap failed\n", __FUNCTION__);
printk(KERN_ERR "%s: ioremap failed\n", __func__);
goto err_gpu_context_free;
}
@@ -1050,9 +1065,18 @@ static int __init ps3fb_probe(struct platform_device *dev)
"fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
info->node, ps3fb_videomemory.size >> 10);
kernel_thread(ps3fbd, info, CLONE_KERNEL);
task = kthread_run(ps3fbd, info, "ps3fbd");
if (IS_ERR(task)) {
retval = PTR_ERR(task);
goto err_unregister_framebuffer;
}
ps3fb.task = task;
return 0;
err_unregister_framebuffer:
unregister_framebuffer(info);
err_fb_dealloc:
fb_dealloc_cmap(&info->cmap);
err_framebuffer_release:
@@ -1083,6 +1107,11 @@ void ps3fb_cleanup(void)
{
int status;
if (ps3fb.task) {
struct task_struct *task = ps3fb.task;
ps3fb.task = NULL;
kthread_stop(task);
}
if (ps3fb.irq_no) {
free_irq(ps3fb.irq_no, ps3fb.dev);
ps3_irq_plug_destroy(ps3fb.irq_no);
@@ -1137,8 +1166,9 @@ int ps3fb_set_sync(void)
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
__func__, status);
return -1;
}
#endif
@@ -1148,8 +1178,9 @@ int ps3fb_set_sync(void)
1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
if (status) {
printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
__FUNCTION__, status);
printk(KERN_ERR
"%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
__func__, status);
return -1;
}
#endif
@@ -1174,7 +1205,7 @@ static int __init ps3fb_init(void)
error = ps3av_dev_open();
if (error) {
printk(KERN_ERR "%s: ps3av_dev_open failed\n", __FUNCTION__);
printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
goto err;
}
@@ -1195,7 +1226,6 @@ static int __init ps3fb_init(void)
atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
init_MUTEX(&ps3fb.sem);
init_waitqueue_head(&ps3fb.wait_vsync);
ps3fb.num_frames = 1;