I've hacked the linux driver for a bit and for me suspend now works it seems. Maybe a bit more gifted hacker can figure out the real issue here and correct it.
A little background (kernel 3.0.0):
I found out that in crystalhd_cmds.c crystalhd_resume get's an uninitialized ctx->hw_ctx . I have no clue why yet.
So I added:
Code:
if(ctx->hw_ctx == NULL) {
ctx->hw_ctx = (struct crystalhd_hw*)kmalloc(sizeof(struct crystalhd_hw), GFP_KERNEL);
if(ctx->hw_ctx != NULL)
memset(ctx->hw_ctx, 0, sizeof(struct crystalhd_hw));
else
return BC_STS_ERROR;
}
Before the crystalhd_hw_resume. This did not work entirely. I got a Failed to Start Device error for obvious reasons (struct not initalized). So I added crystalhd_hw_open(ctx->hw_ctx, ctx->adp). This got me a bit further, but XBMC switched to software rendering and the driver complained at the console about something not being valid. So I looked at the init function for the hardware and decided to add crystalhd_hw_close(ctx->hw_ctx, ctx->adp); which seems to do the trick. I did have to set the ctx->state to BC_LINK_INVALID; to make sure it did not complain about a wrong state as well.
Finally this is my 'working' function (not it isn't really clean):
Code:
BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
{
BC_STATUS sts = BC_STS_SUCCESS;
if(ctx->hw_ctx == NULL) {
ctx->hw_ctx = (struct crystalhd_hw*)kmalloc(sizeof(struct crystalhd_hw), GFP_KERNEL);
if(ctx->hw_ctx != NULL)
memset(ctx->hw_ctx, 0, sizeof(struct crystalhd_hw));
else
return BC_STS_ERROR;
}
crystalhd_hw_open(ctx->hw_ctx, ctx->adp);
crystalhd_hw_close(ctx->hw_ctx, ctx->adp);
kfree(ctx->hw_ctx);
ctx->hw_ctx = NULL;
/*sts = crystalhd_hw_resume(ctx->hw_ctx);*/
if (sts != BC_STS_SUCCESS)
return sts;
/*bc_cproc_mark_pwr_state(ctx, BC_HW_RESUME); /* Starting resume */
ctx->state = BC_LINK_INVALID;
dev_dbg(chddev(), "crystalhd_resume Success %x\n", ctx->state);
return BC_STS_SUCCESS;
}
Which does a basic re-init of the HW. Use at your own risk and I hope it works for you.
For the osx driver I can see something happening along the same lines. Partial re-init. Haven't tried though.