.. | .. |
---|
31 | 31 | #include <linux/clk.h> |
---|
32 | 32 | #include <linux/regulator/consumer.h> |
---|
33 | 33 | #include <linux/mali/mali_utgard.h> |
---|
| 34 | +#include <linux/pm_runtime.h> |
---|
34 | 35 | #include <soc/rockchip/rockchip_opp_select.h> |
---|
35 | 36 | |
---|
36 | 37 | #include "mali_kernel_common.h" |
---|
.. | .. |
---|
177 | 178 | |
---|
178 | 179 | static int mali_open(struct inode *inode, struct file *filp); |
---|
179 | 180 | static int mali_release(struct inode *inode, struct file *filp); |
---|
180 | | -#ifdef HAVE_UNLOCKED_IOCTL |
---|
181 | 181 | static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); |
---|
182 | | -#else |
---|
183 | | -static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); |
---|
184 | | -#endif |
---|
185 | 182 | |
---|
186 | 183 | static int mali_probe(struct platform_device *pdev); |
---|
187 | 184 | static int mali_remove(struct platform_device *pdev); |
---|
.. | .. |
---|
275 | 272 | .owner = THIS_MODULE, |
---|
276 | 273 | .open = mali_open, |
---|
277 | 274 | .release = mali_release, |
---|
278 | | -#ifdef HAVE_UNLOCKED_IOCTL |
---|
279 | 275 | .unlocked_ioctl = mali_ioctl, |
---|
280 | | -#else |
---|
281 | | - .ioctl = mali_ioctl, |
---|
282 | | -#endif |
---|
283 | 276 | .compat_ioctl = mali_ioctl, |
---|
284 | 277 | .mmap = mali_mmap |
---|
285 | 278 | }; |
---|
.. | .. |
---|
521 | 514 | int err; |
---|
522 | 515 | #ifdef CONFIG_MALI_DEVFREQ |
---|
523 | 516 | struct mali_device *mdev; |
---|
| 517 | + const char *name = "mali"; |
---|
524 | 518 | #endif |
---|
525 | 519 | |
---|
526 | 520 | MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name)); |
---|
.. | .. |
---|
575 | 569 | mdev->regulator = NULL; |
---|
576 | 570 | /* Allow probe to continue without regulator */ |
---|
577 | 571 | } |
---|
| 572 | + if (mdev->regulator) { |
---|
| 573 | + mdev->opp_table = dev_pm_opp_set_regulators(mdev->dev, &name, 1); |
---|
| 574 | + if (IS_ERR(mdev->opp_table)) { |
---|
| 575 | + mdev->opp_table = NULL; |
---|
| 576 | + MALI_DEBUG_PRINT(2, ("Continuing without opp regulator\n")); |
---|
| 577 | + } |
---|
| 578 | + } |
---|
578 | 579 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
| 580 | + |
---|
| 581 | + mdev->num_clks = devm_clk_bulk_get_all(mdev->dev, &mdev->clks); |
---|
| 582 | + if (mdev->num_clks < 1) { |
---|
| 583 | + MALI_DEBUG_PRINT(2, ("Continuing without Mali clock control\n")); |
---|
| 584 | + mdev->num_clks = 0; |
---|
| 585 | + mdev->clock = NULL; |
---|
| 586 | + } else { |
---|
| 587 | + /* Get "clk_mali" in the device tree for gpu dvfs */ |
---|
| 588 | + mdev->clock = clk_get(mdev->dev, "clk_mali"); |
---|
| 589 | + if (IS_ERR_OR_NULL(mdev->clock)) { |
---|
| 590 | + MALI_DEBUG_PRINT(2, ("Continuing without Mali dvfs clock\n")); |
---|
| 591 | + /* Allow probe to continue without clock. */ |
---|
| 592 | + mdev->clock = NULL; |
---|
| 593 | + } |
---|
| 594 | + } |
---|
| 595 | + err = clk_bulk_prepare_enable(mdev->num_clks, mdev->clks); |
---|
| 596 | + if (err) { |
---|
| 597 | + MALI_PRINT_ERROR(("Failed to prepare clock (%d)\n", err)); |
---|
| 598 | + goto clock_prepare_failed; |
---|
| 599 | + } |
---|
579 | 600 | |
---|
580 | 601 | err = rk_platform_init_opp_table(mdev->dev); |
---|
581 | 602 | if (err) |
---|
582 | 603 | MALI_DEBUG_PRINT(3, ("Failed to init_opp_table\n")); |
---|
583 | | - |
---|
584 | | - /* Need to name the gpu clock "clk_mali" in the device tree */ |
---|
585 | | - mdev->clock = clk_get(mdev->dev, "clk_mali"); |
---|
586 | | - if (IS_ERR_OR_NULL(mdev->clock)) { |
---|
587 | | - MALI_DEBUG_PRINT(2, ("Continuing without Mali clock control\n")); |
---|
588 | | - mdev->clock = NULL; |
---|
589 | | - /* Allow probe to continue without clock. */ |
---|
590 | | - } else { |
---|
591 | | - err = clk_prepare(mdev->clock); |
---|
592 | | - if (err) { |
---|
593 | | - MALI_PRINT_ERROR(("Failed to prepare clock (%d)\n", err)); |
---|
594 | | - goto clock_prepare_failed; |
---|
595 | | - } |
---|
596 | | - } |
---|
597 | 604 | |
---|
598 | 605 | /* initilize pm metrics related */ |
---|
599 | 606 | if (mali_pm_metrics_init(mdev) < 0) { |
---|
.. | .. |
---|
605 | 612 | MALI_DEBUG_PRINT(2, ("mali devfreq init failed\n")); |
---|
606 | 613 | goto devfreq_init_failed; |
---|
607 | 614 | } |
---|
| 615 | + clk_bulk_disable(mdev->num_clks, mdev->clks); |
---|
608 | 616 | #endif |
---|
609 | 617 | |
---|
610 | 618 | |
---|
.. | .. |
---|
640 | 648 | devfreq_init_failed: |
---|
641 | 649 | mali_pm_metrics_term(mdev); |
---|
642 | 650 | pm_metrics_init_failed: |
---|
643 | | - clk_unprepare(mdev->clock); |
---|
| 651 | + clk_bulk_disable_unprepare(mdev->num_clks, mdev->clks); |
---|
644 | 652 | clock_prepare_failed: |
---|
| 653 | + clk_bulk_put(mdev->num_clks, mdev->clks); |
---|
645 | 654 | clk_put(mdev->clock); |
---|
646 | 655 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \ |
---|
647 | 656 | && defined(CONFIG_PM_OPP) |
---|
.. | .. |
---|
651 | 660 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \ |
---|
652 | 661 | && defined(CONFIG_REGULATOR) |
---|
653 | 662 | regulator_put(mdev->regulator); |
---|
| 663 | + dev_pm_opp_put_regulators(mdev->opp_table); |
---|
654 | 664 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
655 | 665 | mali_device_free(mdev); |
---|
656 | 666 | #endif |
---|
.. | .. |
---|
680 | 690 | mali_pm_metrics_term(mdev); |
---|
681 | 691 | |
---|
682 | 692 | if (mdev->clock) { |
---|
683 | | - clk_unprepare(mdev->clock); |
---|
684 | 693 | clk_put(mdev->clock); |
---|
685 | 694 | mdev->clock = NULL; |
---|
686 | 695 | } |
---|
| 696 | + clk_bulk_unprepare(mdev->num_clks, mdev->clks); |
---|
| 697 | + clk_bulk_put(mdev->num_clks, mdev->clks); |
---|
| 698 | + |
---|
687 | 699 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \ |
---|
688 | 700 | && defined(CONFIG_PM_OPP) |
---|
689 | 701 | dev_pm_opp_of_remove_table(mdev->dev); |
---|
.. | .. |
---|
692 | 704 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \ |
---|
693 | 705 | && defined(CONFIG_REGULATOR) |
---|
694 | 706 | regulator_put(mdev->regulator); |
---|
| 707 | + dev_pm_opp_put_regulators(mdev->opp_table); |
---|
695 | 708 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
696 | 709 | mali_device_free(mdev); |
---|
697 | 710 | #endif |
---|
.. | .. |
---|
733 | 746 | return -ENODEV; |
---|
734 | 747 | #endif |
---|
735 | 748 | |
---|
| 749 | + pm_runtime_force_suspend(dev); |
---|
736 | 750 | #if defined(CONFIG_MALI_DEVFREQ) && \ |
---|
737 | 751 | (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) |
---|
738 | 752 | devfreq_suspend_device(mdev->devfreq); |
---|
.. | .. |
---|
777 | 791 | (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) |
---|
778 | 792 | devfreq_resume_device(mdev->devfreq); |
---|
779 | 793 | #endif |
---|
| 794 | + pm_runtime_force_resume(dev); |
---|
780 | 795 | |
---|
781 | 796 | return 0; |
---|
782 | 797 | } |
---|
.. | .. |
---|
917 | 932 | } |
---|
918 | 933 | } |
---|
919 | 934 | |
---|
920 | | -#ifdef HAVE_UNLOCKED_IOCTL |
---|
921 | 935 | static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
---|
922 | | -#else |
---|
923 | | -static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) |
---|
924 | | -#endif |
---|
925 | 936 | { |
---|
926 | 937 | int err; |
---|
927 | 938 | struct mali_session_data *session_data; |
---|
928 | | - |
---|
929 | | -#ifndef HAVE_UNLOCKED_IOCTL |
---|
930 | | - /* inode not used */ |
---|
931 | | - (void)inode; |
---|
932 | | -#endif |
---|
933 | 939 | |
---|
934 | 940 | MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); |
---|
935 | 941 | |
---|