Commit 37b4b584 authored by David S. Miller's avatar David S. Miller Committed by Greg Kroah-Hartman

atyfb: Fix bootup hangs on sparc64.

[ Upstream commit 09798eb9 ]

After commit 25edd694 ("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: default avatarFabio M. Di NItto <fabbione@fabbione.net>
Reported-by: default avatarSam Ravnborg <sam@ravnborg.org>
Reported-by: default avatarFrans van Berckel <fberckel@xs4all.nl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarFabio M. Di NItto <fabbione@fabbione.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 69def87c
...@@ -2969,10 +2969,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, ...@@ -2969,10 +2969,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
{ {
struct atyfb_par *par = info->par; struct atyfb_par *par = info->par;
struct device_node *dp; struct device_node *dp;
char prop[128];
phandle node;
int len, i, j, ret;
u32 mem, chip_id; u32 mem, chip_id;
int i, j, ret;
/* /*
* Map memory-mapped registers. * Map memory-mapped registers.
...@@ -3088,23 +3086,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, ...@@ -3088,23 +3086,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
aty_st_le32(MEM_CNTL, mem, par); aty_st_le32(MEM_CNTL, mem, par);
} }
/*
* If this is the console device, we will set default video
* settings to what the PROM left us with.
*/
node = prom_getchild(prom_root_node);
node = prom_searchsiblings(node, "aliases");
if (node) {
len = prom_getproperty(node, "screen", prop, sizeof(prop));
if (len > 0) {
prop[len] = '\0';
node = prom_finddevice(prop);
} else
node = 0;
}
dp = pci_device_to_OF_node(pdev); dp = pci_device_to_OF_node(pdev);
if (node == dp->phandle) { if (dp == of_console_device) {
struct fb_var_screeninfo *var = &default_var; struct fb_var_screeninfo *var = &default_var;
unsigned int N, P, Q, M, T, R; unsigned int N, P, Q, M, T, R;
u32 v_total, h_total; u32 v_total, h_total;
...@@ -3112,9 +3095,9 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, ...@@ -3112,9 +3095,9 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
u8 pll_regs[16]; u8 pll_regs[16];
u8 clock_cntl; u8 clock_cntl;
crtc.vxres = prom_getintdefault(node, "width", 1024); crtc.vxres = of_getintprop_default(dp, "width", 1024);
crtc.vyres = prom_getintdefault(node, "height", 768); crtc.vyres = of_getintprop_default(dp, "height", 768);
var->bits_per_pixel = prom_getintdefault(node, "depth", 8); var->bits_per_pixel = of_getintprop_default(dp, "depth", 8);
var->xoffset = var->yoffset = 0; var->xoffset = var->yoffset = 0;
crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment