Skip to content

Commit 57efbeb

Browse files
eilnjannau
authored andcommitted
media: apple: isp: Support system sleep
Signed-off-by: Eileen Yoon <[email protected]>
1 parent 84e8ae8 commit 57efbeb

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

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

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

544+
static __maybe_unused int apple_isp_runtime_suspend(struct device *dev)
545+
{
546+
/* RPM sleep is called when the V4L2 file handle is closed */
547+
return 0;
548+
}
549+
550+
static __maybe_unused int apple_isp_runtime_resume(struct device *dev)
551+
{
552+
return 0;
553+
}
554+
544555
static __maybe_unused int apple_isp_suspend(struct device *dev)
545556
{
557+
struct apple_isp *isp = dev_get_drvdata(dev);
558+
559+
/* We must restore V4L2 context on system resume. If we were streaming
560+
* before, we (essentially) stop streaming and start streaming again.
561+
*/
562+
apple_isp_video_suspend(isp);
563+
546564
return 0;
547565
}
548566

549567
static __maybe_unused int apple_isp_resume(struct device *dev)
550568
{
569+
struct apple_isp *isp = dev_get_drvdata(dev);
570+
571+
apple_isp_video_resume(isp);
572+
551573
return 0;
552574
}
553-
DEFINE_RUNTIME_DEV_PM_OPS(apple_isp_pm_ops, apple_isp_suspend, apple_isp_resume,
554-
NULL);
575+
576+
static const struct dev_pm_ops apple_isp_pm_ops = {
577+
SYSTEM_SLEEP_PM_OPS(apple_isp_suspend, apple_isp_resume)
578+
RUNTIME_PM_OPS(apple_isp_runtime_suspend, apple_isp_runtime_resume, NULL)
579+
};
555580

556581
static struct platform_driver apple_isp_driver = {
557582
.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: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ static inline void isp_gpio_write32(struct apple_isp *isp, u32 reg, u32 val)
4242
writel(val, isp->gpio + reg);
4343
}
4444

45-
int apple_isp_power_up_domains(struct apple_isp *isp)
4645
static int apple_isp_power_up_domains(struct apple_isp *isp)
46+
{
4747
int ret;
4848

4949
if (isp->pds_active)
@@ -65,8 +65,8 @@ static int apple_isp_power_up_domains(struct apple_isp *isp)
6565
return 0;
6666
}
6767

68-
void apple_isp_power_down_domains(struct apple_isp *isp)
6968
static void apple_isp_power_down_domains(struct apple_isp *isp)
69+
{
7070
int ret;
7171

7272
if (!isp->pds_active)
@@ -270,7 +270,7 @@ static void isp_firmware_shutdown_stage1(struct apple_isp *isp)
270270
static int isp_firmware_boot_stage1(struct apple_isp *isp)
271271
{
272272
int err, retries;
273-
u32 val;
273+
// u32 val;
274274

275275
err = apple_isp_power_up_domains(isp);
276276
if (err < 0)
@@ -279,12 +279,19 @@ static int isp_firmware_boot_stage1(struct apple_isp *isp)
279279

280280
isp_gpio_write32(isp, ISP_GPIO_CLOCK_EN, 0x1);
281281

282+
#if 0
283+
/* This doesn't work well with system sleep */
282284
val = isp_gpio_read32(isp, ISP_GPIO_1);
283285
if (val == 0xfeedbabe) {
284286
err = isp_reset_coproc(isp);
285287
if (err < 0)
286288
return err;
287289
}
290+
#endif
291+
292+
err = isp_reset_coproc(isp);
293+
if (err < 0)
294+
return err;
288295

289296
isp_gpio_write32(isp, ISP_GPIO_0, 0x0);
290297
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)