aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-01-05 16:08:06 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-06 14:38:19 -0500
commit09798eb9479da3413bdf96e7d22a84d8b21e05e1 (patch)
tree75e7b1d5475d3ab72bbc0f1d306718800523e604 /drivers
parent050855887236701c5e7ff803b42265824ce99885 (diff)
atyfb: Fix bootup hangs on sparc64.
After commit 25edd6946a1d74e5e77813c2324a0908c68bcf9e ("sparc64: Get rid of indirect p1275 PROM call buffer.") we can't pass virtual addresses >4GB to PROM calls. Largely this is never necessary in drivers because we have a copy of the entire PROM device tree in the kernel and a set of of_*() interfaces to access it. Unfortunately there were some lingering prom calls in the atyfb driver, in particular prom_finddevice() was being called with an on-stack address which could be anywhere. This code is actually probing for information we already have, the PROM choosen console output device is stored in of_console_device so all of this nasty code consolidates into a one-line comparison. Next we have some prom_getintdefault() calls which are trivially transformed into the equivalent of_getintprop_default(). Special thanks to Fabio, who figured out exactly where the bootup was hanging. That made this bug trivial to fix. Reported-by: Fabio M. Di NItto <fabbione@fabbione.net> Reported-by: Sam Ravnborg <sam@ravnborg.org> Reported-by: Frans van Berckel <fberckel@xs4all.nl> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Fabio M. Di NItto <fabbione@fabbione.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/aty/atyfb_base.c27
1 files changed, 5 insertions, 22 deletions
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 5bf91236c701..5a3ce3ad1ec8 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2969,10 +2969,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2969{ 2969{
2970 struct atyfb_par *par = info->par; 2970 struct atyfb_par *par = info->par;
2971 struct device_node *dp; 2971 struct device_node *dp;
2972 char prop[128];
2973 phandle node;
2974 int len, i, j, ret;
2975 u32 mem, chip_id; 2972 u32 mem, chip_id;
2973 int i, j, ret;
2976 2974
2977 /* 2975 /*
2978 * Map memory-mapped registers. 2976 * Map memory-mapped registers.
@@ -3088,23 +3086,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
3088 aty_st_le32(MEM_CNTL, mem, par); 3086 aty_st_le32(MEM_CNTL, mem, par);
3089 } 3087 }
3090 3088
3091 /*
3092 * If this is the console device, we will set default video
3093 * settings to what the PROM left us with.
3094 */
3095 node = prom_getchild(prom_root_node);
3096 node = prom_searchsiblings(node, "aliases");
3097 if (node) {
3098 len = prom_getproperty(node, "screen", prop, sizeof(prop));
3099 if (len > 0) {
3100 prop[len] = '\0';
3101 node = prom_finddevice(prop);
3102 } else
3103 node = 0;
3104 }
3105
3106 dp = pci_device_to_OF_node(pdev); 3089 dp = pci_device_to_OF_node(pdev);
3107 if (node == dp->phandle) { 3090 if (dp == of_console_device) {
3108 struct fb_var_screeninfo *var = &default_var; 3091 struct fb_var_screeninfo *var = &default_var;
3109 unsigned int N, P, Q, M, T, R; 3092 unsigned int N, P, Q, M, T, R;
3110 u32 v_total, h_total; 3093 u32 v_total, h_total;
@@ -3112,9 +3095,9 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
3112 u8 pll_regs[16]; 3095 u8 pll_regs[16];
3113 u8 clock_cntl; 3096 u8 clock_cntl;
3114 3097
3115 crtc.vxres = prom_getintdefault(node, "width", 1024); 3098 crtc.vxres = of_getintprop_default(dp, "width", 1024);
3116 crtc.vyres = prom_getintdefault(node, "height", 768); 3099 crtc.vyres = of_getintprop_default(dp, "height", 768);
3117 var->bits_per_pixel = prom_getintdefault(node, "depth", 8); 3100 var->bits_per_pixel = of_getintprop_default(dp, "depth", 8);
3118 var->xoffset = var->yoffset = 0; 3101 var->xoffset = var->yoffset = 0;
3119 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 3102 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
3120 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 3103 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);