diff options
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index b5a542fbd818..d9424bee0457 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -97,6 +97,8 @@ static struct { | |||
97 | 97 | ||
98 | /* protects dss_data */ | 98 | /* protects dss_data */ |
99 | static spinlock_t data_lock; | 99 | static spinlock_t data_lock; |
100 | /* lock for blocking functions */ | ||
101 | static DEFINE_MUTEX(apply_lock); | ||
100 | 102 | ||
101 | static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) | 103 | static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) |
102 | { | 104 | { |
@@ -639,14 +641,22 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) | |||
639 | 641 | ||
640 | void dss_mgr_enable(struct omap_overlay_manager *mgr) | 642 | void dss_mgr_enable(struct omap_overlay_manager *mgr) |
641 | { | 643 | { |
644 | mutex_lock(&apply_lock); | ||
645 | |||
642 | dispc_mgr_enable(mgr->id, true); | 646 | dispc_mgr_enable(mgr->id, true); |
643 | mgr->enabled = true; | 647 | mgr->enabled = true; |
648 | |||
649 | mutex_unlock(&apply_lock); | ||
644 | } | 650 | } |
645 | 651 | ||
646 | void dss_mgr_disable(struct omap_overlay_manager *mgr) | 652 | void dss_mgr_disable(struct omap_overlay_manager *mgr) |
647 | { | 653 | { |
654 | mutex_lock(&apply_lock); | ||
655 | |||
648 | dispc_mgr_enable(mgr->id, false); | 656 | dispc_mgr_enable(mgr->id, false); |
649 | mgr->enabled = false; | 657 | mgr->enabled = false; |
658 | |||
659 | mutex_unlock(&apply_lock); | ||
650 | } | 660 | } |
651 | 661 | ||
652 | int dss_mgr_set_info(struct omap_overlay_manager *mgr, | 662 | int dss_mgr_set_info(struct omap_overlay_manager *mgr, |
@@ -669,44 +679,65 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, | |||
669 | { | 679 | { |
670 | int r; | 680 | int r; |
671 | 681 | ||
682 | mutex_lock(&apply_lock); | ||
683 | |||
672 | if (dssdev->manager) { | 684 | if (dssdev->manager) { |
673 | DSSERR("display '%s' already has a manager '%s'\n", | 685 | DSSERR("display '%s' already has a manager '%s'\n", |
674 | dssdev->name, dssdev->manager->name); | 686 | dssdev->name, dssdev->manager->name); |
675 | return -EINVAL; | 687 | r = -EINVAL; |
688 | goto err; | ||
676 | } | 689 | } |
677 | 690 | ||
678 | if ((mgr->supported_displays & dssdev->type) == 0) { | 691 | if ((mgr->supported_displays & dssdev->type) == 0) { |
679 | DSSERR("display '%s' does not support manager '%s'\n", | 692 | DSSERR("display '%s' does not support manager '%s'\n", |
680 | dssdev->name, mgr->name); | 693 | dssdev->name, mgr->name); |
681 | return -EINVAL; | 694 | r = -EINVAL; |
695 | goto err; | ||
682 | } | 696 | } |
683 | 697 | ||
684 | dssdev->manager = mgr; | 698 | dssdev->manager = mgr; |
685 | mgr->device = dssdev; | 699 | mgr->device = dssdev; |
686 | mgr->device_changed = true; | 700 | mgr->device_changed = true; |
687 | 701 | ||
702 | mutex_unlock(&apply_lock); | ||
703 | |||
688 | return 0; | 704 | return 0; |
705 | err: | ||
706 | mutex_unlock(&apply_lock); | ||
707 | return r; | ||
689 | } | 708 | } |
690 | 709 | ||
691 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr) | 710 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr) |
692 | { | 711 | { |
712 | int r; | ||
713 | |||
714 | mutex_lock(&apply_lock); | ||
715 | |||
693 | if (!mgr->device) { | 716 | if (!mgr->device) { |
694 | DSSERR("failed to unset display, display not set.\n"); | 717 | DSSERR("failed to unset display, display not set.\n"); |
695 | return -EINVAL; | 718 | r = -EINVAL; |
719 | goto err; | ||
696 | } | 720 | } |
697 | 721 | ||
698 | /* | 722 | /* |
699 | * Don't allow currently enabled displays to have the overlay manager | 723 | * Don't allow currently enabled displays to have the overlay manager |
700 | * pulled out from underneath them | 724 | * pulled out from underneath them |
701 | */ | 725 | */ |
702 | if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) | 726 | if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) { |
703 | return -EINVAL; | 727 | r = -EINVAL; |
728 | goto err; | ||
729 | } | ||
704 | 730 | ||
705 | mgr->device->manager = NULL; | 731 | mgr->device->manager = NULL; |
706 | mgr->device = NULL; | 732 | mgr->device = NULL; |
707 | mgr->device_changed = true; | 733 | mgr->device_changed = true; |
708 | 734 | ||
735 | mutex_unlock(&apply_lock); | ||
736 | |||
709 | return 0; | 737 | return 0; |
738 | err: | ||
739 | mutex_unlock(&apply_lock); | ||
740 | return r; | ||
710 | } | 741 | } |
711 | 742 | ||
712 | 743 | ||
@@ -729,18 +760,24 @@ void dss_ovl_get_info(struct omap_overlay *ovl, | |||
729 | int dss_ovl_set_manager(struct omap_overlay *ovl, | 760 | int dss_ovl_set_manager(struct omap_overlay *ovl, |
730 | struct omap_overlay_manager *mgr) | 761 | struct omap_overlay_manager *mgr) |
731 | { | 762 | { |
763 | int r; | ||
764 | |||
732 | if (!mgr) | 765 | if (!mgr) |
733 | return -EINVAL; | 766 | return -EINVAL; |
734 | 767 | ||
768 | mutex_lock(&apply_lock); | ||
769 | |||
735 | if (ovl->manager) { | 770 | if (ovl->manager) { |
736 | DSSERR("overlay '%s' already has a manager '%s'\n", | 771 | DSSERR("overlay '%s' already has a manager '%s'\n", |
737 | ovl->name, ovl->manager->name); | 772 | ovl->name, ovl->manager->name); |
738 | return -EINVAL; | 773 | r = -EINVAL; |
774 | goto err; | ||
739 | } | 775 | } |
740 | 776 | ||
741 | if (ovl->info.enabled) { | 777 | if (ovl->info.enabled) { |
742 | DSSERR("overlay has to be disabled to change the manager\n"); | 778 | DSSERR("overlay has to be disabled to change the manager\n"); |
743 | return -EINVAL; | 779 | r = -EINVAL; |
780 | goto err; | ||
744 | } | 781 | } |
745 | 782 | ||
746 | ovl->manager = mgr; | 783 | ovl->manager = mgr; |
@@ -760,25 +797,41 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, | |||
760 | * the overlay, but before moving the overlay to TV. | 797 | * the overlay, but before moving the overlay to TV. |
761 | */ | 798 | */ |
762 | 799 | ||
800 | mutex_unlock(&apply_lock); | ||
801 | |||
763 | return 0; | 802 | return 0; |
803 | err: | ||
804 | mutex_unlock(&apply_lock); | ||
805 | return r; | ||
764 | } | 806 | } |
765 | 807 | ||
766 | int dss_ovl_unset_manager(struct omap_overlay *ovl) | 808 | int dss_ovl_unset_manager(struct omap_overlay *ovl) |
767 | { | 809 | { |
810 | int r; | ||
811 | |||
812 | mutex_lock(&apply_lock); | ||
813 | |||
768 | if (!ovl->manager) { | 814 | if (!ovl->manager) { |
769 | DSSERR("failed to detach overlay: manager not set\n"); | 815 | DSSERR("failed to detach overlay: manager not set\n"); |
770 | return -EINVAL; | 816 | r = -EINVAL; |
817 | goto err; | ||
771 | } | 818 | } |
772 | 819 | ||
773 | if (ovl->info.enabled) { | 820 | if (ovl->info.enabled) { |
774 | DSSERR("overlay has to be disabled to unset the manager\n"); | 821 | DSSERR("overlay has to be disabled to unset the manager\n"); |
775 | return -EINVAL; | 822 | r = -EINVAL; |
823 | goto err; | ||
776 | } | 824 | } |
777 | 825 | ||
778 | ovl->manager = NULL; | 826 | ovl->manager = NULL; |
779 | list_del(&ovl->list); | 827 | list_del(&ovl->list); |
780 | ovl->manager_changed = true; | 828 | ovl->manager_changed = true; |
781 | 829 | ||
830 | mutex_unlock(&apply_lock); | ||
831 | |||
782 | return 0; | 832 | return 0; |
833 | err: | ||
834 | mutex_unlock(&apply_lock); | ||
835 | return r; | ||
783 | } | 836 | } |
784 | 837 | ||