Skip to content

Commit 8734da2

Browse files
eilnjannau
authored andcommitted
media: apple: isp: Support system sleep
Signed-off-by: Eileen Yoon <[email protected]>
1 parent 4dff3fd commit 8734da2

File tree

5 files changed

+81
-9
lines changed

5 files changed

+81
-9
lines changed

drivers/media/platform/apple/isp/isp-drv.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,17 +551,42 @@ static const struct of_device_id apple_isp_of_match[] = {
551551
};
552552
MODULE_DEVICE_TABLE(of, apple_isp_of_match);
553553

554+
static __maybe_unused int apple_isp_runtime_suspend(struct device *dev)
555+
{
556+
/* RPM sleep is called when the V4L2 file handle is closed */
557+
return 0;
558+
}
559+
560+
static __maybe_unused int apple_isp_runtime_resume(struct device *dev)
561+
{
562+
return 0;
563+
}
564+
554565
static __maybe_unused int apple_isp_suspend(struct device *dev)
555566
{
567+
struct apple_isp *isp = dev_get_drvdata(dev);
568+
569+
/* We must restore V4L2 context on system resume. If we were streaming
570+
* before, we (essentially) stop streaming and start streaming again.
571+
*/
572+
apple_isp_video_suspend(isp);
573+
556574
return 0;
557575
}
558576

559577
static __maybe_unused int apple_isp_resume(struct device *dev)
560578
{
579+
struct apple_isp *isp = dev_get_drvdata(dev);
580+
581+
apple_isp_video_resume(isp);
582+
561583
return 0;
562584
}
563-
DEFINE_RUNTIME_DEV_PM_OPS(apple_isp_pm_ops, apple_isp_suspend, apple_isp_resume,
564-
NULL);
585+
586+
static const struct dev_pm_ops apple_isp_pm_ops = {
587+
SYSTEM_SLEEP_PM_OPS(apple_isp_suspend, apple_isp_resume)
588+
RUNTIME_PM_OPS(apple_isp_runtime_suspend, apple_isp_runtime_resume, NULL)
589+
};
565590

566591
static struct platform_driver apple_isp_driver = {
567592
.driver = {

drivers/media/platform/apple/isp/isp-drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ struct isp_buffer {
270270
enum {
271271
ISP_STATE_STREAMING,
272272
ISP_STATE_LOGGING,
273+
ISP_STATE_SLEEPING,
273274
};
274275

275276
#ifdef APPLE_ISP_DEBUG

drivers/media/platform/apple/isp/isp-fw.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,19 @@ static int isp_firmware_boot_stage1(struct apple_isp *isp)
277277

278278
isp_gpio_write32(isp, ISP_GPIO_CLOCK_EN, 0x1);
279279

280+
#if 0
281+
/* This doesn't work well with system sleep */
280282
val = isp_gpio_read32(isp, ISP_GPIO_1);
281283
if (val == 0xfeedbabe) {
282284
err = isp_reset_coproc(isp);
283285
if (err < 0)
284286
return err;
285287
}
288+
#endif
289+
290+
err = isp_reset_coproc(isp);
291+
if (err < 0)
292+
return err;
286293

287294
isp_gpio_write32(isp, ISP_GPIO_0, 0x0);
288295
isp_gpio_write32(isp, ISP_GPIO_1, 0x0);

drivers/media/platform/apple/isp/isp-v4l2.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,10 @@ static void isp_vb2_buf_queue(struct vb2_buffer *vb)
337337
isp_submit_buffers(isp);
338338
}
339339

340-
static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
340+
static int apple_isp_start_streaming(struct apple_isp *isp)
341341
{
342-
struct apple_isp *isp = vb2_get_drv_priv(q);
343342
int err;
344343

345-
isp->sequence = 0;
346-
347344
err = apple_isp_start_camera(isp);
348345
if (err) {
349346
dev_err(isp->dev, "failed to start camera: %d\n", err);
@@ -373,16 +370,55 @@ static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
373370
return err;
374371
}
375372

376-
static void isp_vb2_stop_streaming(struct vb2_queue *q)
373+
static void apple_isp_stop_streaming(struct apple_isp *isp)
377374
{
378-
struct apple_isp *isp = vb2_get_drv_priv(q);
379-
380375
clear_bit(ISP_STATE_STREAMING, &isp->state);
381376
apple_isp_stop_capture(isp);
382377
apple_isp_stop_camera(isp);
378+
}
379+
380+
static int isp_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
381+
{
382+
struct apple_isp *isp = vb2_get_drv_priv(q);
383+
384+
isp->sequence = 0;
385+
386+
return apple_isp_start_streaming(isp);
387+
}
388+
389+
static void isp_vb2_stop_streaming(struct vb2_queue *q)
390+
{
391+
struct apple_isp *isp = vb2_get_drv_priv(q);
392+
393+
apple_isp_stop_streaming(isp);
383394
isp_vb2_release_buffers(isp, VB2_BUF_STATE_ERROR);
384395
}
385396

397+
int apple_isp_video_suspend(struct apple_isp *isp)
398+
{
399+
/* Swap into STATE_SLEEPING as isp_vb2_buf_queue() submits on
400+
* STATE_STREAMING.
401+
*/
402+
if (test_bit(ISP_STATE_STREAMING, &isp->state)) {
403+
/* Signal buffers to be recycled for clean shutdown */
404+
isp_vb2_release_buffers(isp, VB2_BUF_STATE_QUEUED);
405+
apple_isp_stop_streaming(isp);
406+
set_bit(ISP_STATE_SLEEPING, &isp->state);
407+
}
408+
409+
return 0;
410+
}
411+
412+
int apple_isp_video_resume(struct apple_isp *isp)
413+
{
414+
if (test_bit(ISP_STATE_SLEEPING, &isp->state)) {
415+
clear_bit(ISP_STATE_SLEEPING, &isp->state);
416+
apple_isp_start_streaming(isp);
417+
}
418+
419+
return 0;
420+
}
421+
386422
static const struct vb2_ops isp_vb2_ops = {
387423
.queue_setup = isp_vb2_queue_setup,
388424
.buf_init = isp_vb2_buf_init,

drivers/media/platform/apple/isp/isp-v4l2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ int apple_isp_setup_video(struct apple_isp *isp);
1010
void apple_isp_remove_video(struct apple_isp *isp);
1111
int ipc_bt_handle(struct apple_isp *isp, struct isp_channel *chan);
1212

13+
int apple_isp_video_suspend(struct apple_isp *isp);
14+
int apple_isp_video_resume(struct apple_isp *isp);
15+
1316
#endif /* __ISP_V4L2_H__ */

0 commit comments

Comments
 (0)