aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-02-07 21:10:18 -0500
committerDave Airlie <airlied@redhat.com>2013-02-07 21:10:18 -0500
commit6dc1c49da6dd3bf020a66b2a135b9625ac01c2c7 (patch)
tree38a6c5d4896de01449e9d224088ae223161fcd3c /drivers/video
parentcd17ef4114ad5c514b17e6a0bb02a309ab90b692 (diff)
parent5845b81bdad374f98f809a658ec747d92c9595c4 (diff)
Merge branch 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux into drm-next
This pulls in most of Linus tree up to -rc6, this fixes the worst lockdep reported issues and re-enables fbcon lockdep. (not the fbcon maintainer) * 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux: (529 commits) Revert "Revert "console: implement lockdep support for console_lock"" fbcon: fix locking harder fb: Yet another band-aid for fixing lockdep mess fb: rework locking to fix lock ordering on takeover
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/fbcon.c44
-rw-r--r--drivers/video/fbmem.c11
-rw-r--r--drivers/video/fbsysfs.c3
-rw-r--r--drivers/video/imxfb.c13
4 files changed, 61 insertions, 10 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index fdefa8fd72c4..2e2d959acae6 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -529,6 +529,33 @@ static int search_for_mapped_con(void)
529 return retval; 529 return retval;
530} 530}
531 531
532static int do_fbcon_takeover(int show_logo)
533{
534 int err, i;
535
536 if (!num_registered_fb)
537 return -ENODEV;
538
539 if (!show_logo)
540 logo_shown = FBCON_LOGO_DONTSHOW;
541
542 for (i = first_fb_vc; i <= last_fb_vc; i++)
543 con2fb_map[i] = info_idx;
544
545 err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
546 fbcon_is_default);
547
548 if (err) {
549 for (i = first_fb_vc; i <= last_fb_vc; i++)
550 con2fb_map[i] = -1;
551 info_idx = -1;
552 } else {
553 fbcon_has_console_bind = 1;
554 }
555
556 return err;
557}
558
532static int fbcon_takeover(int show_logo) 559static int fbcon_takeover(int show_logo)
533{ 560{
534 int err, i; 561 int err, i;
@@ -815,6 +842,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
815 * 842 *
816 * Maps a virtual console @unit to a frame buffer device 843 * Maps a virtual console @unit to a frame buffer device
817 * @newidx. 844 * @newidx.
845 *
846 * This should be called with the console lock held.
818 */ 847 */
819static int set_con2fb_map(int unit, int newidx, int user) 848static int set_con2fb_map(int unit, int newidx, int user)
820{ 849{
@@ -832,7 +861,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
832 861
833 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { 862 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
834 info_idx = newidx; 863 info_idx = newidx;
835 return fbcon_takeover(0); 864 return do_fbcon_takeover(0);
836 } 865 }
837 866
838 if (oldidx != -1) 867 if (oldidx != -1)
@@ -840,7 +869,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
840 869
841 found = search_fb_in_map(newidx); 870 found = search_fb_in_map(newidx);
842 871
843 console_lock();
844 con2fb_map[unit] = newidx; 872 con2fb_map[unit] = newidx;
845 if (!err && !found) 873 if (!err && !found)
846 err = con2fb_acquire_newinfo(vc, info, unit, oldidx); 874 err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -867,7 +895,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
867 if (!search_fb_in_map(info_idx)) 895 if (!search_fb_in_map(info_idx))
868 info_idx = newidx; 896 info_idx = newidx;
869 897
870 console_unlock();
871 return err; 898 return err;
872} 899}
873 900
@@ -2977,7 +3004,7 @@ static int fbcon_unbind(void)
2977{ 3004{
2978 int ret; 3005 int ret;
2979 3006
2980 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, 3007 ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
2981 fbcon_is_default); 3008 fbcon_is_default);
2982 3009
2983 if (!ret) 3010 if (!ret)
@@ -2992,6 +3019,7 @@ static inline int fbcon_unbind(void)
2992} 3019}
2993#endif /* CONFIG_VT_HW_CONSOLE_BINDING */ 3020#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
2994 3021
3022/* called with console_lock held */
2995static int fbcon_fb_unbind(int idx) 3023static int fbcon_fb_unbind(int idx)
2996{ 3024{
2997 int i, new_idx = -1, ret = 0; 3025 int i, new_idx = -1, ret = 0;
@@ -3018,6 +3046,7 @@ static int fbcon_fb_unbind(int idx)
3018 return ret; 3046 return ret;
3019} 3047}
3020 3048
3049/* called with console_lock held */
3021static int fbcon_fb_unregistered(struct fb_info *info) 3050static int fbcon_fb_unregistered(struct fb_info *info)
3022{ 3051{
3023 int i, idx; 3052 int i, idx;
@@ -3050,11 +3079,12 @@ static int fbcon_fb_unregistered(struct fb_info *info)
3050 primary_device = -1; 3079 primary_device = -1;
3051 3080
3052 if (!num_registered_fb) 3081 if (!num_registered_fb)
3053 unregister_con_driver(&fb_con); 3082 do_unregister_con_driver(&fb_con);
3054 3083
3055 return 0; 3084 return 0;
3056} 3085}
3057 3086
3087/* called with console_lock held */
3058static void fbcon_remap_all(int idx) 3088static void fbcon_remap_all(int idx)
3059{ 3089{
3060 int i; 3090 int i;
@@ -3099,6 +3129,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
3099} 3129}
3100#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ 3130#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
3101 3131
3132/* called with console_lock held */
3102static int fbcon_fb_registered(struct fb_info *info) 3133static int fbcon_fb_registered(struct fb_info *info)
3103{ 3134{
3104 int ret = 0, i, idx; 3135 int ret = 0, i, idx;
@@ -3115,7 +3146,7 @@ static int fbcon_fb_registered(struct fb_info *info)
3115 } 3146 }
3116 3147
3117 if (info_idx != -1) 3148 if (info_idx != -1)
3118 ret = fbcon_takeover(1); 3149 ret = do_fbcon_takeover(1);
3119 } else { 3150 } else {
3120 for (i = first_fb_vc; i <= last_fb_vc; i++) { 3151 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3121 if (con2fb_map_boot[i] == idx) 3152 if (con2fb_map_boot[i] == idx)
@@ -3251,6 +3282,7 @@ static int fbcon_event_notify(struct notifier_block *self,
3251 ret = fbcon_fb_unregistered(info); 3282 ret = fbcon_fb_unregistered(info);
3252 break; 3283 break;
3253 case FB_EVENT_SET_CONSOLE_MAP: 3284 case FB_EVENT_SET_CONSOLE_MAP:
3285 /* called with console lock held */
3254 con2fb = event->data; 3286 con2fb = event->data;
3255 ret = set_con2fb_map(con2fb->console - 1, 3287 ret = set_con2fb_map(con2fb->console - 1,
3256 con2fb->framebuffer, 1); 3288 con2fb->framebuffer, 1);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3ff0105a496a..dc61c12ecf8c 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1177,8 +1177,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1177 event.data = &con2fb; 1177 event.data = &con2fb;
1178 if (!lock_fb_info(info)) 1178 if (!lock_fb_info(info))
1179 return -ENODEV; 1179 return -ENODEV;
1180 console_lock();
1180 event.info = info; 1181 event.info = info;
1181 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); 1182 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
1183 console_unlock();
1182 unlock_fb_info(info); 1184 unlock_fb_info(info);
1183 break; 1185 break;
1184 case FBIOBLANK: 1186 case FBIOBLANK:
@@ -1650,7 +1652,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
1650 event.info = fb_info; 1652 event.info = fb_info;
1651 if (!lock_fb_info(fb_info)) 1653 if (!lock_fb_info(fb_info))
1652 return -ENODEV; 1654 return -ENODEV;
1655 console_lock();
1653 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); 1656 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1657 console_unlock();
1654 unlock_fb_info(fb_info); 1658 unlock_fb_info(fb_info);
1655 return 0; 1659 return 0;
1656} 1660}
@@ -1666,8 +1670,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1666 1670
1667 if (!lock_fb_info(fb_info)) 1671 if (!lock_fb_info(fb_info))
1668 return -ENODEV; 1672 return -ENODEV;
1673 console_lock();
1669 event.info = fb_info; 1674 event.info = fb_info;
1670 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); 1675 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1676 console_unlock();
1671 unlock_fb_info(fb_info); 1677 unlock_fb_info(fb_info);
1672 1678
1673 if (ret) 1679 if (ret)
@@ -1682,7 +1688,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1682 num_registered_fb--; 1688 num_registered_fb--;
1683 fb_cleanup_device(fb_info); 1689 fb_cleanup_device(fb_info);
1684 event.info = fb_info; 1690 event.info = fb_info;
1691 console_lock();
1685 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1692 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1693 console_unlock();
1686 1694
1687 /* this may free fb info */ 1695 /* this may free fb info */
1688 put_fb_info(fb_info); 1696 put_fb_info(fb_info);
@@ -1853,11 +1861,8 @@ int fb_new_modelist(struct fb_info *info)
1853 err = 1; 1861 err = 1;
1854 1862
1855 if (!list_empty(&info->modelist)) { 1863 if (!list_empty(&info->modelist)) {
1856 if (!lock_fb_info(info))
1857 return -ENODEV;
1858 event.info = info; 1864 event.info = info;
1859 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); 1865 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
1860 unlock_fb_info(info);
1861 } 1866 }
1862 1867
1863 return err; 1868 return err;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index a55e3669d135..ef476b02fbe5 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -177,6 +177,8 @@ static ssize_t store_modes(struct device *device,
177 if (i * sizeof(struct fb_videomode) != count) 177 if (i * sizeof(struct fb_videomode) != count)
178 return -EINVAL; 178 return -EINVAL;
179 179
180 if (!lock_fb_info(fb_info))
181 return -ENODEV;
180 console_lock(); 182 console_lock();
181 list_splice(&fb_info->modelist, &old_list); 183 list_splice(&fb_info->modelist, &old_list);
182 fb_videomode_to_modelist((const struct fb_videomode *)buf, i, 184 fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
@@ -188,6 +190,7 @@ static ssize_t store_modes(struct device *device,
188 fb_destroy_modelist(&old_list); 190 fb_destroy_modelist(&old_list);
189 191
190 console_unlock(); 192 console_unlock();
193 unlock_fb_info(fb_info);
191 194
192 return 0; 195 return 0;
193} 196}
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 12526787a7c7..0abf2bf20836 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -139,6 +139,7 @@ struct imxfb_info {
139 struct clk *clk_ahb; 139 struct clk *clk_ahb;
140 struct clk *clk_per; 140 struct clk *clk_per;
141 enum imxfb_type devtype; 141 enum imxfb_type devtype;
142 bool enabled;
142 143
143 /* 144 /*
144 * These are the addresses we mapped 145 * These are the addresses we mapped
@@ -536,6 +537,10 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
536 537
537static void imxfb_enable_controller(struct imxfb_info *fbi) 538static void imxfb_enable_controller(struct imxfb_info *fbi)
538{ 539{
540
541 if (fbi->enabled)
542 return;
543
539 pr_debug("Enabling LCD controller\n"); 544 pr_debug("Enabling LCD controller\n");
540 545
541 writel(fbi->screen_dma, fbi->regs + LCDC_SSA); 546 writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
@@ -556,6 +561,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
556 clk_prepare_enable(fbi->clk_ipg); 561 clk_prepare_enable(fbi->clk_ipg);
557 clk_prepare_enable(fbi->clk_ahb); 562 clk_prepare_enable(fbi->clk_ahb);
558 clk_prepare_enable(fbi->clk_per); 563 clk_prepare_enable(fbi->clk_per);
564 fbi->enabled = true;
559 565
560 if (fbi->backlight_power) 566 if (fbi->backlight_power)
561 fbi->backlight_power(1); 567 fbi->backlight_power(1);
@@ -565,6 +571,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
565 571
566static void imxfb_disable_controller(struct imxfb_info *fbi) 572static void imxfb_disable_controller(struct imxfb_info *fbi)
567{ 573{
574 if (!fbi->enabled)
575 return;
576
568 pr_debug("Disabling LCD controller\n"); 577 pr_debug("Disabling LCD controller\n");
569 578
570 if (fbi->backlight_power) 579 if (fbi->backlight_power)
@@ -575,6 +584,7 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
575 clk_disable_unprepare(fbi->clk_per); 584 clk_disable_unprepare(fbi->clk_per);
576 clk_disable_unprepare(fbi->clk_ipg); 585 clk_disable_unprepare(fbi->clk_ipg);
577 clk_disable_unprepare(fbi->clk_ahb); 586 clk_disable_unprepare(fbi->clk_ahb);
587 fbi->enabled = false;
578 588
579 writel(0, fbi->regs + LCDC_RMCR); 589 writel(0, fbi->regs + LCDC_RMCR);
580} 590}
@@ -729,6 +739,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
729 739
730 memset(fbi, 0, sizeof(struct imxfb_info)); 740 memset(fbi, 0, sizeof(struct imxfb_info));
731 741
742 fbi->devtype = pdev->id_entry->driver_data;
743
732 strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); 744 strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
733 745
734 info->fix.type = FB_TYPE_PACKED_PIXELS; 746 info->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -789,7 +801,6 @@ static int __init imxfb_probe(struct platform_device *pdev)
789 return -ENOMEM; 801 return -ENOMEM;
790 802
791 fbi = info->par; 803 fbi = info->par;
792 fbi->devtype = pdev->id_entry->driver_data;
793 804
794 if (!fb_mode) 805 if (!fb_mode)
795 fb_mode = pdata->mode[0].mode.name; 806 fb_mode = pdata->mode[0].mode.name;