Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions drivers/media/platform/apple/isp/isp-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,17 +551,42 @@ static const struct of_device_id apple_isp_of_match[] = {
};
MODULE_DEVICE_TABLE(of, apple_isp_of_match);

static __maybe_unused int apple_isp_runtime_suspend(struct device *dev)
{
/* RPM sleep is called when the V4L2 file handle is closed */
return 0;
}

static __maybe_unused int apple_isp_runtime_resume(struct device *dev)
{
return 0;
}

static __maybe_unused int apple_isp_suspend(struct device *dev)
{
struct apple_isp *isp = dev_get_drvdata(dev);

/* We must restore V4L2 context on system resume. If we were streaming
* before, we (essentially) stop streaming and start streaming again.
*/
apple_isp_video_suspend(isp);

return 0;
}

static __maybe_unused int apple_isp_resume(struct device *dev)
{
struct apple_isp *isp = dev_get_drvdata(dev);

apple_isp_video_resume(isp);

return 0;
}
DEFINE_RUNTIME_DEV_PM_OPS(apple_isp_pm_ops, apple_isp_suspend, apple_isp_resume,
NULL);

static const struct dev_pm_ops apple_isp_pm_ops = {
SYSTEM_SLEEP_PM_OPS(apple_isp_suspend, apple_isp_resume)
RUNTIME_PM_OPS(apple_isp_runtime_suspend, apple_isp_runtime_resume, NULL)
};

static struct platform_driver apple_isp_driver = {
.driver = {
Expand Down
1 change: 1 addition & 0 deletions drivers/media/platform/apple/isp/isp-drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ struct isp_buffer {
enum {
ISP_STATE_STREAMING,
ISP_STATE_LOGGING,
ISP_STATE_SLEEPING,
};

#ifdef APPLE_ISP_DEBUG
Expand Down
7 changes: 7 additions & 0 deletions drivers/media/platform/apple/isp/isp-fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,19 @@ static int isp_firmware_boot_stage1(struct apple_isp *isp)

isp_gpio_write32(isp, ISP_GPIO_CLOCK_EN, 0x1);

#if 0
/* This doesn't work well with system sleep */
val = isp_gpio_read32(isp, ISP_GPIO_1);
if (val == 0xfeedbabe) {
err = isp_reset_coproc(isp);
if (err < 0)
return err;
}
#endif

err = isp_reset_coproc(isp);
if (err < 0)
return err;

isp_gpio_write32(isp, ISP_GPIO_0, 0x0);
isp_gpio_write32(isp, ISP_GPIO_1, 0x0);
Expand Down
50 changes: 43 additions & 7 deletions drivers/media/platform/apple/isp/isp-v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,10 @@ static void isp_vb2_buf_queue(struct vb2_buffer *vb)
isp_submit_buffers(isp);
}

static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
static int apple_isp_start_streaming(struct apple_isp *isp)
{
struct apple_isp *isp = vb2_get_drv_priv(q);
int err;

isp->sequence = 0;

err = apple_isp_start_camera(isp);
if (err) {
dev_err(isp->dev, "failed to start camera: %d\n", err);
Expand Down Expand Up @@ -373,16 +370,55 @@ static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
return err;
}

static void isp_vb2_stop_streaming(struct vb2_queue *q)
static void apple_isp_stop_streaming(struct apple_isp *isp)
{
struct apple_isp *isp = vb2_get_drv_priv(q);

clear_bit(ISP_STATE_STREAMING, &isp->state);
apple_isp_stop_capture(isp);
apple_isp_stop_camera(isp);
}

static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct apple_isp *isp = vb2_get_drv_priv(q);

isp->sequence = 0;

return apple_isp_start_streaming(isp);
}

static void isp_vb2_stop_streaming(struct vb2_queue *q)
{
struct apple_isp *isp = vb2_get_drv_priv(q);

apple_isp_stop_streaming(isp);
isp_vb2_release_buffers(isp, VB2_BUF_STATE_ERROR);
}

int apple_isp_video_suspend(struct apple_isp *isp)
{
/* Swap into STATE_SLEEPING as isp_vb2_buf_queue() submits on
* STATE_STREAMING.
*/
if (test_bit(ISP_STATE_STREAMING, &isp->state)) {
/* Signal buffers to be recycled for clean shutdown */
isp_vb2_release_buffers(isp, VB2_BUF_STATE_QUEUED);
apple_isp_stop_streaming(isp);
set_bit(ISP_STATE_SLEEPING, &isp->state);
}

return 0;
}

int apple_isp_video_resume(struct apple_isp *isp)
{
if (test_bit(ISP_STATE_SLEEPING, &isp->state)) {
clear_bit(ISP_STATE_SLEEPING, &isp->state);
apple_isp_start_streaming(isp);
}

return 0;
}

static const struct vb2_ops isp_vb2_ops = {
.queue_setup = isp_vb2_queue_setup,
.buf_init = isp_vb2_buf_init,
Expand Down
3 changes: 3 additions & 0 deletions drivers/media/platform/apple/isp/isp-v4l2.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ int apple_isp_setup_video(struct apple_isp *isp);
void apple_isp_remove_video(struct apple_isp *isp);
int ipc_bt_handle(struct apple_isp *isp, struct isp_channel *chan);

int apple_isp_video_suspend(struct apple_isp *isp);
int apple_isp_video_resume(struct apple_isp *isp);

#endif /* __ISP_V4L2_H__ */