Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branches 'asoc/topic/hdmi', 'asoc/topic/img' and 'asoc/topic/kirkwood' into asoc-next

+388 -82
+1 -4
sound/soc/codecs/hdmi-codec.c
··· 303 303 static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, 304 304 struct snd_ctl_elem_info *uinfo) 305 305 { 306 - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 307 - struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); 308 - 309 306 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 310 - uinfo->count = sizeof(hcp->eld); 307 + uinfo->count = FIELD_SIZEOF(struct hdmi_codec_priv, eld); 311 308 312 309 return 0; 313 310 }
+119 -13
sound/soc/img/img-i2s-in.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/of.h> 18 18 #include <linux/platform_device.h> 19 + #include <linux/pm_runtime.h> 19 20 #include <linux/reset.h> 20 21 21 22 #include <sound/core.h> ··· 61 60 void __iomem *channel_base; 62 61 unsigned int active_channels; 63 62 struct snd_soc_dai_driver dai_driver; 63 + u32 suspend_ctl; 64 + u32 *suspend_ch_ctl; 64 65 }; 66 + 67 + static int img_i2s_in_runtime_suspend(struct device *dev) 68 + { 69 + struct img_i2s_in *i2s = dev_get_drvdata(dev); 70 + 71 + clk_disable_unprepare(i2s->clk_sys); 72 + 73 + return 0; 74 + } 75 + 76 + static int img_i2s_in_runtime_resume(struct device *dev) 77 + { 78 + struct img_i2s_in *i2s = dev_get_drvdata(dev); 79 + int ret; 80 + 81 + ret = clk_prepare_enable(i2s->clk_sys); 82 + if (ret) { 83 + dev_err(dev, "Unable to enable sys clock\n"); 84 + return ret; 85 + } 86 + 87 + return 0; 88 + } 65 89 66 90 static inline void img_i2s_in_writel(struct img_i2s_in *i2s, u32 val, u32 reg) 67 91 { ··· 305 279 static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 306 280 { 307 281 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai); 308 - int i; 282 + int i, ret; 309 283 u32 chan_control_mask, lrd_set = 0, blkp_set = 0, chan_control_set = 0; 310 284 u32 reg; 311 285 ··· 345 319 346 320 chan_control_mask = IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK; 347 321 322 + ret = pm_runtime_get_sync(i2s->dev); 323 + if (ret < 0) 324 + return ret; 325 + 348 326 for (i = 0; i < i2s->active_channels; i++) 349 327 img_i2s_in_ch_disable(i2s, i); 350 328 ··· 367 337 368 338 for (i = 0; i < i2s->active_channels; i++) 369 339 img_i2s_in_ch_enable(i2s, i); 340 + 341 + pm_runtime_put(i2s->dev); 370 342 371 343 return 0; 372 344 } ··· 459 427 return PTR_ERR(i2s->clk_sys); 460 428 } 461 429 462 - ret = clk_prepare_enable(i2s->clk_sys); 463 - if (ret) 464 - return ret; 430 + pm_runtime_enable(&pdev->dev); 431 + if (!pm_runtime_enabled(&pdev->dev)) { 432 + ret = img_i2s_in_runtime_resume(&pdev->dev); 433 + if (ret) 434 + goto err_pm_disable; 435 + } 436 + ret = pm_runtime_get_sync(&pdev->dev); 437 + if (ret < 0) 438 + goto err_suspend; 465 439 466 440 i2s->active_channels = 1; 467 441 i2s->dma_data.addr = res->start + IMG_I2S_IN_RX_FIFO; ··· 485 447 if (IS_ERR(rst)) { 486 448 if (PTR_ERR(rst) == -EPROBE_DEFER) { 487 449 ret = -EPROBE_DEFER; 488 - goto err_clk_disable; 450 + goto err_suspend; 489 451 } 490 452 491 453 dev_dbg(dev, "No top level reset found\n"); ··· 507 469 IMG_I2S_IN_CH_CTL_JUST_MASK | 508 470 IMG_I2S_IN_CH_CTL_FW_MASK, IMG_I2S_IN_CH_CTL); 509 471 472 + pm_runtime_put(&pdev->dev); 473 + 474 + i2s->suspend_ch_ctl = devm_kzalloc(dev, 475 + sizeof(*i2s->suspend_ch_ctl) * i2s->max_i2s_chan, GFP_KERNEL); 476 + if (!i2s->suspend_ch_ctl) { 477 + ret = -ENOMEM; 478 + goto err_suspend; 479 + } 480 + 510 481 ret = devm_snd_soc_register_component(dev, &img_i2s_in_component, 511 482 &i2s->dai_driver, 1); 512 483 if (ret) 513 - goto err_clk_disable; 484 + goto err_suspend; 514 485 515 486 ret = devm_snd_dmaengine_pcm_register(dev, &img_i2s_in_dma_config, 0); 516 487 if (ret) 517 - goto err_clk_disable; 488 + goto err_suspend; 518 489 519 490 return 0; 520 491 521 - err_clk_disable: 522 - clk_disable_unprepare(i2s->clk_sys); 492 + err_suspend: 493 + if (!pm_runtime_enabled(&pdev->dev)) 494 + img_i2s_in_runtime_suspend(&pdev->dev); 495 + err_pm_disable: 496 + pm_runtime_disable(&pdev->dev); 523 497 524 498 return ret; 525 499 } 526 500 527 501 static int img_i2s_in_dev_remove(struct platform_device *pdev) 528 502 { 529 - struct img_i2s_in *i2s = platform_get_drvdata(pdev); 530 - 531 - clk_disable_unprepare(i2s->clk_sys); 503 + pm_runtime_disable(&pdev->dev); 504 + if (!pm_runtime_status_suspended(&pdev->dev)) 505 + img_i2s_in_runtime_suspend(&pdev->dev); 532 506 533 507 return 0; 534 508 } 509 + 510 + #ifdef CONFIG_PM_SLEEP 511 + static int img_i2s_in_suspend(struct device *dev) 512 + { 513 + struct img_i2s_in *i2s = dev_get_drvdata(dev); 514 + int i, ret; 515 + u32 reg; 516 + 517 + if (pm_runtime_status_suspended(dev)) { 518 + ret = img_i2s_in_runtime_resume(dev); 519 + if (ret) 520 + return ret; 521 + } 522 + 523 + for (i = 0; i < i2s->max_i2s_chan; i++) { 524 + reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL); 525 + i2s->suspend_ch_ctl[i] = reg; 526 + } 527 + 528 + i2s->suspend_ctl = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL); 529 + 530 + img_i2s_in_runtime_suspend(dev); 531 + 532 + return 0; 533 + } 534 + 535 + static int img_i2s_in_resume(struct device *dev) 536 + { 537 + struct img_i2s_in *i2s = dev_get_drvdata(dev); 538 + int i, ret; 539 + u32 reg; 540 + 541 + ret = img_i2s_in_runtime_resume(dev); 542 + if (ret) 543 + return ret; 544 + 545 + for (i = 0; i < i2s->max_i2s_chan; i++) { 546 + reg = i2s->suspend_ch_ctl[i]; 547 + img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); 548 + } 549 + 550 + img_i2s_in_writel(i2s, i2s->suspend_ctl, IMG_I2S_IN_CTL); 551 + 552 + if (pm_runtime_status_suspended(dev)) 553 + img_i2s_in_runtime_suspend(dev); 554 + 555 + return 0; 556 + } 557 + #endif 535 558 536 559 static const struct of_device_id img_i2s_in_of_match[] = { 537 560 { .compatible = "img,i2s-in" }, ··· 600 501 }; 601 502 MODULE_DEVICE_TABLE(of, img_i2s_in_of_match); 602 503 504 + static const struct dev_pm_ops img_i2s_in_pm_ops = { 505 + SET_RUNTIME_PM_OPS(img_i2s_in_runtime_suspend, 506 + img_i2s_in_runtime_resume, NULL) 507 + SET_SYSTEM_SLEEP_PM_OPS(img_i2s_in_suspend, img_i2s_in_resume) 508 + }; 509 + 603 510 static struct platform_driver img_i2s_in_driver = { 604 511 .driver = { 605 512 .name = "img-i2s-in", 606 - .of_match_table = img_i2s_in_of_match 513 + .of_match_table = img_i2s_in_of_match, 514 + .pm = &img_i2s_in_pm_ops 607 515 }, 608 516 .probe = img_i2s_in_probe, 609 517 .remove = img_i2s_in_dev_remove
+92 -30
sound/soc/img/img-i2s-out.c
··· 63 63 unsigned int active_channels; 64 64 struct reset_control *rst; 65 65 struct snd_soc_dai_driver dai_driver; 66 + u32 suspend_ctl; 67 + u32 *suspend_ch_ctl; 66 68 }; 67 69 68 - static int img_i2s_out_suspend(struct device *dev) 70 + static int img_i2s_out_runtime_suspend(struct device *dev) 69 71 { 70 72 struct img_i2s_out *i2s = dev_get_drvdata(dev); 71 73 72 - if (!i2s->force_clk_active) 73 - clk_disable_unprepare(i2s->clk_ref); 74 + clk_disable_unprepare(i2s->clk_ref); 75 + clk_disable_unprepare(i2s->clk_sys); 74 76 75 77 return 0; 76 78 } 77 79 78 - static int img_i2s_out_resume(struct device *dev) 80 + static int img_i2s_out_runtime_resume(struct device *dev) 79 81 { 80 82 struct img_i2s_out *i2s = dev_get_drvdata(dev); 81 83 int ret; 82 84 83 - if (!i2s->force_clk_active) { 84 - ret = clk_prepare_enable(i2s->clk_ref); 85 - if (ret) { 86 - dev_err(dev, "clk_enable failed: %d\n", ret); 87 - return ret; 88 - } 85 + ret = clk_prepare_enable(i2s->clk_sys); 86 + if (ret) { 87 + dev_err(dev, "clk_enable failed: %d\n", ret); 88 + return ret; 89 + } 90 + 91 + ret = clk_prepare_enable(i2s->clk_ref); 92 + if (ret) { 93 + dev_err(dev, "clk_enable failed: %d\n", ret); 94 + clk_disable_unprepare(i2s->clk_sys); 95 + return ret; 89 96 } 90 97 91 98 return 0; ··· 294 287 static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 295 288 { 296 289 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai); 297 - int i; 290 + int i, ret; 298 291 bool force_clk_active; 299 292 u32 chan_control_mask, control_mask, chan_control_set = 0; 300 293 u32 reg, control_set = 0; ··· 349 342 350 343 chan_control_mask = IMG_I2S_OUT_CHAN_CTL_CLKT_MASK; 351 344 345 + ret = pm_runtime_get_sync(i2s->dev); 346 + if (ret < 0) 347 + return ret; 348 + 352 349 img_i2s_out_disable(i2s); 353 350 354 351 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL); ··· 372 361 img_i2s_out_ch_enable(i2s, i); 373 362 374 363 img_i2s_out_enable(i2s); 364 + pm_runtime_put(i2s->dev); 375 365 376 366 i2s->force_clk_active = force_clk_active; 377 367 ··· 479 467 return PTR_ERR(i2s->clk_ref); 480 468 } 481 469 482 - ret = clk_prepare_enable(i2s->clk_sys); 483 - if (ret) 484 - return ret; 470 + i2s->suspend_ch_ctl = devm_kzalloc(dev, 471 + sizeof(*i2s->suspend_ch_ctl) * i2s->max_i2s_chan, GFP_KERNEL); 472 + if (!i2s->suspend_ch_ctl) 473 + return -ENOMEM; 474 + 475 + pm_runtime_enable(&pdev->dev); 476 + if (!pm_runtime_enabled(&pdev->dev)) { 477 + ret = img_i2s_out_runtime_resume(&pdev->dev); 478 + if (ret) 479 + goto err_pm_disable; 480 + } 481 + ret = pm_runtime_get_sync(&pdev->dev); 482 + if (ret < 0) 483 + goto err_suspend; 485 484 486 485 reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK; 487 486 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL); ··· 506 483 img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL); 507 484 508 485 img_i2s_out_reset(i2s); 509 - 510 - pm_runtime_enable(&pdev->dev); 511 - if (!pm_runtime_enabled(&pdev->dev)) { 512 - ret = img_i2s_out_resume(&pdev->dev); 513 - if (ret) 514 - goto err_pm_disable; 515 - } 486 + pm_runtime_put(&pdev->dev); 516 487 517 488 i2s->active_channels = 1; 518 489 i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO; ··· 534 517 535 518 err_suspend: 536 519 if (!pm_runtime_status_suspended(&pdev->dev)) 537 - img_i2s_out_suspend(&pdev->dev); 520 + img_i2s_out_runtime_suspend(&pdev->dev); 538 521 err_pm_disable: 539 522 pm_runtime_disable(&pdev->dev); 540 - clk_disable_unprepare(i2s->clk_sys); 541 523 542 524 return ret; 543 525 } 544 526 545 527 static int img_i2s_out_dev_remove(struct platform_device *pdev) 546 528 { 547 - struct img_i2s_out *i2s = platform_get_drvdata(pdev); 548 - 549 529 pm_runtime_disable(&pdev->dev); 550 530 if (!pm_runtime_status_suspended(&pdev->dev)) 551 - img_i2s_out_suspend(&pdev->dev); 552 - 553 - clk_disable_unprepare(i2s->clk_sys); 531 + img_i2s_out_runtime_suspend(&pdev->dev); 554 532 555 533 return 0; 556 534 } 535 + 536 + #ifdef CONFIG_PM_SLEEP 537 + static int img_i2s_out_suspend(struct device *dev) 538 + { 539 + struct img_i2s_out *i2s = dev_get_drvdata(dev); 540 + int i, ret; 541 + u32 reg; 542 + 543 + if (pm_runtime_status_suspended(dev)) { 544 + ret = img_i2s_out_runtime_resume(dev); 545 + if (ret) 546 + return ret; 547 + } 548 + 549 + for (i = 0; i < i2s->max_i2s_chan; i++) { 550 + reg = img_i2s_out_ch_readl(i2s, i, IMG_I2S_OUT_CH_CTL); 551 + i2s->suspend_ch_ctl[i] = reg; 552 + } 553 + 554 + i2s->suspend_ctl = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL); 555 + 556 + img_i2s_out_runtime_suspend(dev); 557 + 558 + return 0; 559 + } 560 + 561 + static int img_i2s_out_resume(struct device *dev) 562 + { 563 + struct img_i2s_out *i2s = dev_get_drvdata(dev); 564 + int i, ret; 565 + u32 reg; 566 + 567 + ret = img_i2s_out_runtime_resume(dev); 568 + if (ret) 569 + return ret; 570 + 571 + for (i = 0; i < i2s->max_i2s_chan; i++) { 572 + reg = i2s->suspend_ch_ctl[i]; 573 + img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL); 574 + } 575 + 576 + img_i2s_out_writel(i2s, i2s->suspend_ctl, IMG_I2S_OUT_CTL); 577 + 578 + if (pm_runtime_status_suspended(dev)) 579 + img_i2s_out_runtime_suspend(dev); 580 + 581 + return 0; 582 + } 583 + #endif 557 584 558 585 static const struct of_device_id img_i2s_out_of_match[] = { 559 586 { .compatible = "img,i2s-out" }, ··· 606 545 MODULE_DEVICE_TABLE(of, img_i2s_out_of_match); 607 546 608 547 static const struct dev_pm_ops img_i2s_out_pm_ops = { 609 - SET_RUNTIME_PM_OPS(img_i2s_out_suspend, 610 - img_i2s_out_resume, NULL) 548 + SET_RUNTIME_PM_OPS(img_i2s_out_runtime_suspend, 549 + img_i2s_out_runtime_resume, NULL) 550 + SET_SYSTEM_SLEEP_PM_OPS(img_i2s_out_suspend, img_i2s_out_resume) 611 551 }; 612 552 613 553 static struct platform_driver img_i2s_out_driver = {
+6
sound/soc/img/img-parallel-out.c
··· 153 153 { 154 154 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai); 155 155 u32 reg, control_set = 0; 156 + int ret; 156 157 157 158 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 158 159 case SND_SOC_DAIFMT_NB_NF: ··· 165 164 return -EINVAL; 166 165 } 167 166 167 + ret = pm_runtime_get_sync(prl->dev); 168 + if (ret < 0) 169 + return ret; 170 + 168 171 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL); 169 172 reg = (reg & ~IMG_PRL_OUT_CTL_EDGE_MASK) | control_set; 170 173 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL); 174 + pm_runtime_put(prl->dev); 171 175 172 176 return 0; 173 177 }
+100 -12
sound/soc/img/img-spdif-in.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/of.h> 18 18 #include <linux/platform_device.h> 19 + #include <linux/pm_runtime.h> 19 20 #include <linux/reset.h> 20 21 21 22 #include <sound/core.h> ··· 83 82 unsigned int single_freq; 84 83 unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN]; 85 84 bool active; 85 + u32 suspend_clkgen; 86 + u32 suspend_ctl; 86 87 87 88 /* Write-only registers */ 88 89 unsigned int aclkgen_regs[IMG_SPDIF_IN_NUM_ACLKGEN]; 89 90 }; 91 + 92 + static int img_spdif_in_runtime_suspend(struct device *dev) 93 + { 94 + struct img_spdif_in *spdif = dev_get_drvdata(dev); 95 + 96 + clk_disable_unprepare(spdif->clk_sys); 97 + 98 + return 0; 99 + } 100 + 101 + static int img_spdif_in_runtime_resume(struct device *dev) 102 + { 103 + struct img_spdif_in *spdif = dev_get_drvdata(dev); 104 + int ret; 105 + 106 + ret = clk_prepare_enable(spdif->clk_sys); 107 + if (ret) { 108 + dev_err(dev, "Unable to enable sys clock\n"); 109 + return ret; 110 + } 111 + 112 + return 0; 113 + } 90 114 91 115 static inline void img_spdif_in_writel(struct img_spdif_in *spdif, 92 116 u32 val, u32 reg) ··· 749 723 return PTR_ERR(spdif->clk_sys); 750 724 } 751 725 752 - ret = clk_prepare_enable(spdif->clk_sys); 753 - if (ret) 754 - return ret; 726 + pm_runtime_enable(&pdev->dev); 727 + if (!pm_runtime_enabled(&pdev->dev)) { 728 + ret = img_spdif_in_runtime_resume(&pdev->dev); 729 + if (ret) 730 + goto err_pm_disable; 731 + } 732 + ret = pm_runtime_get_sync(&pdev->dev); 733 + if (ret < 0) 734 + goto err_suspend; 755 735 756 736 rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); 757 737 if (IS_ERR(rst)) { 758 738 if (PTR_ERR(rst) == -EPROBE_DEFER) { 759 739 ret = -EPROBE_DEFER; 760 - goto err_clk_disable; 740 + goto err_pm_put; 761 741 } 762 742 dev_dbg(dev, "No top level reset found\n"); 763 743 img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK, ··· 791 759 IMG_SPDIF_IN_CTL_TRK_MASK; 792 760 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); 793 761 762 + pm_runtime_put(&pdev->dev); 763 + 794 764 ret = devm_snd_soc_register_component(&pdev->dev, 795 765 &img_spdif_in_component, &img_spdif_in_dai, 1); 796 766 if (ret) 797 - goto err_clk_disable; 767 + goto err_suspend; 798 768 799 769 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 800 770 if (ret) 801 - goto err_clk_disable; 771 + goto err_suspend; 802 772 803 773 return 0; 804 774 805 - err_clk_disable: 806 - clk_disable_unprepare(spdif->clk_sys); 775 + err_pm_put: 776 + pm_runtime_put(&pdev->dev); 777 + err_suspend: 778 + if (!pm_runtime_enabled(&pdev->dev)) 779 + img_spdif_in_runtime_suspend(&pdev->dev); 780 + err_pm_disable: 781 + pm_runtime_disable(&pdev->dev); 807 782 808 783 return ret; 809 784 } 810 785 811 786 static int img_spdif_in_dev_remove(struct platform_device *pdev) 812 787 { 813 - struct img_spdif_in *spdif = platform_get_drvdata(pdev); 814 - 815 - clk_disable_unprepare(spdif->clk_sys); 788 + pm_runtime_disable(&pdev->dev); 789 + if (!pm_runtime_status_suspended(&pdev->dev)) 790 + img_spdif_in_runtime_suspend(&pdev->dev); 816 791 817 792 return 0; 818 793 } 794 + 795 + #ifdef CONFIG_PM_SLEEP 796 + static int img_spdif_in_suspend(struct device *dev) 797 + { 798 + struct img_spdif_in *spdif = dev_get_drvdata(dev); 799 + int ret; 800 + 801 + if (pm_runtime_status_suspended(dev)) { 802 + ret = img_spdif_in_runtime_resume(dev); 803 + if (ret) 804 + return ret; 805 + } 806 + 807 + spdif->suspend_clkgen = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CLKGEN); 808 + spdif->suspend_ctl = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); 809 + 810 + img_spdif_in_runtime_suspend(dev); 811 + 812 + return 0; 813 + } 814 + 815 + static int img_spdif_in_resume(struct device *dev) 816 + { 817 + struct img_spdif_in *spdif = dev_get_drvdata(dev); 818 + int i, ret; 819 + 820 + ret = img_spdif_in_runtime_resume(dev); 821 + if (ret) 822 + return ret; 823 + 824 + for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) 825 + img_spdif_in_aclkgen_writel(spdif, i); 826 + 827 + img_spdif_in_writel(spdif, spdif->suspend_clkgen, IMG_SPDIF_IN_CLKGEN); 828 + img_spdif_in_writel(spdif, spdif->suspend_ctl, IMG_SPDIF_IN_CTL); 829 + 830 + if (pm_runtime_status_suspended(dev)) 831 + img_spdif_in_runtime_suspend(dev); 832 + 833 + return 0; 834 + } 835 + #endif 819 836 820 837 static const struct of_device_id img_spdif_in_of_match[] = { 821 838 { .compatible = "img,spdif-in" }, ··· 872 791 }; 873 792 MODULE_DEVICE_TABLE(of, img_spdif_in_of_match); 874 793 794 + static const struct dev_pm_ops img_spdif_in_pm_ops = { 795 + SET_RUNTIME_PM_OPS(img_spdif_in_runtime_suspend, 796 + img_spdif_in_runtime_resume, NULL) 797 + SET_SYSTEM_SLEEP_PM_OPS(img_spdif_in_suspend, img_spdif_in_resume) 798 + }; 799 + 875 800 static struct platform_driver img_spdif_in_driver = { 876 801 .driver = { 877 802 .name = "img-spdif-in", 878 - .of_match_table = img_spdif_in_of_match 803 + .of_match_table = img_spdif_in_of_match, 804 + .pm = &img_spdif_in_pm_ops 879 805 }, 880 806 .probe = img_spdif_in_probe, 881 807 .remove = img_spdif_in_dev_remove
+68 -21
sound/soc/img/img-spdif-out.c
··· 47 47 struct snd_dmaengine_dai_dma_data dma_data; 48 48 struct device *dev; 49 49 struct reset_control *rst; 50 + u32 suspend_ctl; 51 + u32 suspend_csl; 52 + u32 suspend_csh; 50 53 }; 51 54 52 - static int img_spdif_out_suspend(struct device *dev) 55 + static int img_spdif_out_runtime_suspend(struct device *dev) 53 56 { 54 57 struct img_spdif_out *spdif = dev_get_drvdata(dev); 55 58 56 59 clk_disable_unprepare(spdif->clk_ref); 60 + clk_disable_unprepare(spdif->clk_sys); 57 61 58 62 return 0; 59 63 } 60 64 61 - static int img_spdif_out_resume(struct device *dev) 65 + static int img_spdif_out_runtime_resume(struct device *dev) 62 66 { 63 67 struct img_spdif_out *spdif = dev_get_drvdata(dev); 64 68 int ret; 65 69 70 + ret = clk_prepare_enable(spdif->clk_sys); 71 + if (ret) { 72 + dev_err(dev, "clk_enable failed: %d\n", ret); 73 + return ret; 74 + } 75 + 66 76 ret = clk_prepare_enable(spdif->clk_ref); 67 77 if (ret) { 68 78 dev_err(dev, "clk_enable failed: %d\n", ret); 79 + clk_disable_unprepare(spdif->clk_sys); 69 80 return ret; 70 81 } 71 82 ··· 366 355 return PTR_ERR(spdif->clk_ref); 367 356 } 368 357 369 - ret = clk_prepare_enable(spdif->clk_sys); 370 - if (ret) 371 - return ret; 372 - 373 - img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK, 374 - IMG_SPDIF_OUT_CTL); 375 - 376 - img_spdif_out_reset(spdif); 377 - 378 358 pm_runtime_enable(&pdev->dev); 379 359 if (!pm_runtime_enabled(&pdev->dev)) { 380 - ret = img_spdif_out_resume(&pdev->dev); 360 + ret = img_spdif_out_runtime_resume(&pdev->dev); 381 361 if (ret) 382 362 goto err_pm_disable; 383 363 } 364 + ret = pm_runtime_get_sync(&pdev->dev); 365 + if (ret < 0) 366 + goto err_suspend; 367 + 368 + img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK, 369 + IMG_SPDIF_OUT_CTL); 370 + 371 + img_spdif_out_reset(spdif); 372 + pm_runtime_put(&pdev->dev); 384 373 385 374 spin_lock_init(&spdif->lock); 386 375 ··· 404 393 405 394 err_suspend: 406 395 if (!pm_runtime_status_suspended(&pdev->dev)) 407 - img_spdif_out_suspend(&pdev->dev); 396 + img_spdif_out_runtime_suspend(&pdev->dev); 408 397 err_pm_disable: 409 398 pm_runtime_disable(&pdev->dev); 410 - clk_disable_unprepare(spdif->clk_sys); 411 399 412 400 return ret; 413 401 } 414 402 415 403 static int img_spdif_out_dev_remove(struct platform_device *pdev) 416 404 { 417 - struct img_spdif_out *spdif = platform_get_drvdata(pdev); 418 - 419 405 pm_runtime_disable(&pdev->dev); 420 406 if (!pm_runtime_status_suspended(&pdev->dev)) 421 - img_spdif_out_suspend(&pdev->dev); 422 - 423 - clk_disable_unprepare(spdif->clk_sys); 407 + img_spdif_out_runtime_suspend(&pdev->dev); 424 408 425 409 return 0; 426 410 } 427 411 412 + #ifdef CONFIG_PM_SLEEP 413 + static int img_spdif_out_suspend(struct device *dev) 414 + { 415 + struct img_spdif_out *spdif = dev_get_drvdata(dev); 416 + int ret; 417 + 418 + if (pm_runtime_status_suspended(dev)) { 419 + ret = img_spdif_out_runtime_resume(dev); 420 + if (ret) 421 + return ret; 422 + } 423 + 424 + spdif->suspend_ctl = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL); 425 + spdif->suspend_csl = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL); 426 + spdif->suspend_csh = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV); 427 + 428 + img_spdif_out_runtime_suspend(dev); 429 + 430 + return 0; 431 + } 432 + 433 + static int img_spdif_out_resume(struct device *dev) 434 + { 435 + struct img_spdif_out *spdif = dev_get_drvdata(dev); 436 + int ret; 437 + 438 + ret = img_spdif_out_runtime_resume(dev); 439 + if (ret) 440 + return ret; 441 + 442 + img_spdif_out_writel(spdif, spdif->suspend_ctl, IMG_SPDIF_OUT_CTL); 443 + img_spdif_out_writel(spdif, spdif->suspend_csl, IMG_SPDIF_OUT_CSL); 444 + img_spdif_out_writel(spdif, spdif->suspend_csh, IMG_SPDIF_OUT_CSH_UV); 445 + 446 + if (pm_runtime_status_suspended(dev)) 447 + img_spdif_out_runtime_suspend(dev); 448 + 449 + return 0; 450 + } 451 + #endif 428 452 static const struct of_device_id img_spdif_out_of_match[] = { 429 453 { .compatible = "img,spdif-out" }, 430 454 {} ··· 467 421 MODULE_DEVICE_TABLE(of, img_spdif_out_of_match); 468 422 469 423 static const struct dev_pm_ops img_spdif_out_pm_ops = { 470 - SET_RUNTIME_PM_OPS(img_spdif_out_suspend, 471 - img_spdif_out_resume, NULL) 424 + SET_RUNTIME_PM_OPS(img_spdif_out_runtime_suspend, 425 + img_spdif_out_runtime_resume, NULL) 426 + SET_SYSTEM_SLEEP_PM_OPS(img_spdif_out_suspend, img_spdif_out_resume) 472 427 }; 473 428 474 429 static struct platform_driver img_spdif_out_driver = {
+1 -1
sound/soc/kirkwood/kirkwood-dma.c
··· 318 318 } 319 319 } 320 320 321 - struct snd_soc_platform_driver kirkwood_soc_platform = { 321 + const struct snd_soc_platform_driver kirkwood_soc_platform = { 322 322 .ops = &kirkwood_dma_ops, 323 323 .pcm_new = kirkwood_dma_new, 324 324 .pcm_free = kirkwood_dma_free_dma_buffers,
+1 -1
sound/soc/kirkwood/kirkwood.h
··· 143 143 int burst; 144 144 }; 145 145 146 - extern struct snd_soc_platform_driver kirkwood_soc_platform; 146 + extern const struct snd_soc_platform_driver kirkwood_soc_platform; 147 147 148 148 #endif