[parisc-linux-cvs] primary sti selection
Thomas Bogendoerfer
tsbogend@alpha.franken.de
Sun, 6 Jan 2002 19:53:56 +0100
Hi,
I've implemented a way for selecting the primary sti for console, which
is consistent between sticon and stifb and works (at least for me:-)).
Before I'll commit it, I want to get a little feedback whether it's ok.
Below are two patchsets, the first one is for linux the second one for palo.
The sti selections now uses the kernel parameter sti= for passing the io path
of the wanted sti device. My palo changes will read the console path
and convert that to the right sti= parameter. The linux changes will
take that parameter and decide on the basis, what should be the
primary sti for sticon and stifb.
I've tested the patches on B132 (one VIS-EG), C100 (two HCRX8),
C160 (one VIS-EG and one HCRX24) and C200 (FX6), and everything worked as
expected.
Thomas.
Index: arch/parisc/kernel/drivers.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/drivers.c,v
retrieving revision 1.35
diff -u -p -r1.35 drivers.c
--- arch/parisc/kernel/drivers.c 2001/12/21 23:50:07 1.35
+++ arch/parisc/kernel/drivers.c 2002/01/06 02:50:32
@@ -204,7 +204,7 @@ get_node_path(struct parisc_device *dev,
}
}
-static void print_hwpath(struct parisc_device *dev, char *output)
+void print_hwpath(struct parisc_device *dev, char *output)
{
int i;
struct hardware_path path;
Index: drivers/gsc/dino.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/dino.c,v
retrieving revision 1.49
diff -u -p -r1.49 dino.c
--- drivers/gsc/dino.c 2001/12/26 22:00:32 1.49
+++ drivers/gsc/dino.c 2002/01/06 17:18:42
@@ -559,7 +559,7 @@ dino_fixup_bus(struct pci_bus *bus)
bus, bus->secondary, bus->sysdata);
/* Firmware doesn't set up card-mode dino, so we have to */
- if (is_card_dino(dino_dev->hba.iodc_info))
+ if (is_card_dino(&dino_dev->hba.dev->id))
dino_card_setup(bus, dino_dev->hba.base_addr);
/* If this is a PCI-PCI Bridge, read the window registers etc */
@@ -570,7 +570,7 @@ dino_fixup_bus(struct pci_bus *bus)
int i;
dev = pci_dev_b(ln);
- if (is_card_dino(dino_dev->hba.iodc_info))
+ if (is_card_dino(&dino_dev->hba.dev->id))
dino_card_fixup(dev);
/*
@@ -907,7 +907,7 @@ dino_driver_callback(struct parisc_devic
memset(dino_dev, 0, sizeof(struct dino_device));
- dino_dev->hba.iodc_info = &dev->id;
+ dino_dev->hba.dev = dev;
dino_dev->hba.base_addr = dev->hpa; /* faster access */
dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
dino_dev->dinosaur_pen = SPIN_LOCK_UNLOCKED;
Index: drivers/video/sti/sticore.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.30
diff -u -p -r1.30 sticore.c
--- drivers/video/sti/sticore.c 2001/12/04 02:12:40 1.30
+++ drivers/video/sti/sticore.c 2002/01/06 18:06:15
@@ -30,7 +30,7 @@
#include "sticore.h"
-struct sti_struct *default_sti;
+struct sti_struct *default_sti = NULL;
static int num_sti_roms; /* # of STI ROMS found */
static struct sti_struct *sti_roms[MAX_STI_ROMS]; /* ptr to each sti_struct */
@@ -242,16 +242,14 @@ sti_rom_copy(unsigned long base, unsigne
-static unsigned int __initdata sti_initial_index;
+static char default_sti_path[21] = { '\0' };
static int __init
sti_setup(char *str)
{
- char *end;
+ if (str)
+ strncpy (default_sti_path, str, sizeof (default_sti_path));
- if (str && *str)
- sti_initial_index = simple_strtoul(str, &end, 10);
-
return 0;
}
@@ -865,6 +863,11 @@ out_err:
return NULL;
}
+static void __init sticore_check_for_default_sti (struct sti_struct *sti, char *path)
+{
+ if (strcmp (path, default_sti_path) == 0)
+ default_sti = sti;
+}
/*
* on newer systems PDC gives the address of the ROM
@@ -874,21 +877,28 @@ out_err:
static int __init sticore_pa_init(struct parisc_device *dev)
{
unsigned long rom = 0;
-
+ char pa_path[21];
+ struct sti_struct *sti = NULL;
+
if(dev->num_addrs) {
rom = dev->addr[0];
}
if (!rom) {
rom = dev->hpa;
DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
- if (sti_try_rom_generic(rom, dev->hpa, NULL))
- return 0;
+ sti = sti_try_rom_generic(rom, dev->hpa, NULL);
rom = PAGE0->proc_sti;
}
- DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
- if (sti_try_rom_generic(rom, dev->hpa, NULL))
- return 0;
- return 1;
+ if (!sti) {
+ DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
+ sti = sti_try_rom_generic(rom, dev->hpa, NULL);
+ }
+ if (!sti)
+ return 1;
+
+ print_hwpath (dev, pa_path);
+ sticore_check_for_default_sti (sti, pa_path);
+ return 0;
}
@@ -939,6 +949,25 @@ static int __devinit sticore_pci_init(st
/* fall through */
default:
sti = sti_try_rom_generic(rom_base, fb_base, pd);
+ if (sti) {
+ unsigned char pci_path[4];
+ char pa_path[21];
+ struct pci_bus *root;
+ int i = 0;
+ char *p;
+
+ pci_path[i++] = PCI_FUNC(pd->devfn);
+ pci_path[i++] = PCI_SLOT(pd->devfn);
+ for (root = pd->bus; root->parent && i < 4; root = root->parent)
+ pci_path[i++] = root->number;
+ if (i >= 4)
+ break; /* too many bridges, shouldn't happen */
+ print_hwpath (HBA_DATA(root->sysdata)->dev, pa_path);
+ p = &pa_path[strlen(pa_path)];
+ while (i > 0)
+ p += sprintf (p, "/%d", pci_path[--i]);
+ sticore_check_for_default_sti(sti, pa_path);
+ }
break;
}
@@ -997,12 +1026,10 @@ struct sti_struct * __init sti_init_roms
/* Register drivers for native & PCI cards */
register_parisc_driver(&pa_sti_driver);
pci_module_init (&pci_sti_driver);
-
- /* check boot-value from "sti=<index>" */
- if (sti_initial_index >= num_sti_roms)
- sti_initial_index = 0;
- default_sti = sti_roms[sti_initial_index];
+ /* if we didn't find the given default sti, take the first one */
+ if (!default_sti)
+ default_sti = sti_roms[0];
out:
/* return default STI if available */
@@ -1013,11 +1040,26 @@ out:
return NULL;
}
+/*
+ * index = 0 gives default sti
+ * index > 0 gives other stis in detection order
+ */
struct sti_struct * __init sti_get_rom(int index)
{
- if (index >=0 && index < num_sti_roms)
- return sti_roms[index];
+ int i;
- return NULL;
+ if (index == 0)
+ return default_sti;
+
+ i = -1;
+ while (index > 0) {
+ i++;
+ if (i > num_sti_roms)
+ return NULL;
+ if (sti_roms[i] == default_sti)
+ continue;
+ index--;
+ }
+ return sti_roms[i];
}
Index: include/asm-parisc/pci.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/pci.h,v
retrieving revision 1.38
diff -u -p -r1.38 pci.h
--- include/asm-parisc/pci.h 2001/11/10 01:47:37 1.38
+++ include/asm-parisc/pci.h 2002/01/06 17:12:02
@@ -47,7 +47,7 @@
*/
struct pci_hba_data {
unsigned long base_addr; /* aka Host Physical Address */
- const struct parisc_device_id *iodc_info; /* Info from PA bus walk */
+ const struct parisc_device *dev; /* device from PA bus walk */
struct pci_bus *hba_bus; /* primary PCI bus below HBA */
int hba_num; /* I/O port space access "key" */
struct resource bus_num; /* PCI bus numbers */
@@ -249,6 +249,7 @@ extern inline void pcibios_register_hba(
struct parisc_device;
void * ccio_get_iommu(struct parisc_device *dev);
struct pci_dev * ccio_get_fake(struct parisc_device *dev);
+int ccio_request_resource(struct parisc_device *dev, struct resource *r);
#else /* !CONFIG_IOMMU_CCIO */
#define ccio_get_iommu(dev) (NULL)
#define ccio_get_fake(dev) (NULL)
----------------------------------------------------------------------------
Index: ipl/bootloader.h
===================================================================
RCS file: /home/cvs/parisc/palo/ipl/bootloader.h,v
retrieving revision 1.10
diff -u -p -r1.10 bootloader.h
--- ipl/bootloader.h 2001/12/31 19:36:32 1.10
+++ ipl/bootloader.h 2002/01/06 18:21:12
@@ -35,6 +35,7 @@ int pdc_os_bits();
#define OS_32 0x2
#define OS_64 0x1
int pdc_iodc_bootin(unsigned devaddr, char *memaddr, unsigned size);
+int pdc_read_conspath(unsigned char *memaddr);
typedef void (*describe_t)(int fd, int *bufalign, int *blocksize);
typedef int (*read_t)(int fd, char *buf, unsigned nbytes, unsigned devaddr);
Index: ipl/ipl.c
===================================================================
RCS file: /home/cvs/parisc/palo/ipl/ipl.c,v
retrieving revision 1.27
diff -u -p -r1.27 ipl.c
--- ipl/ipl.c 2001/12/31 19:36:32 1.27
+++ ipl/ipl.c 2002/01/06 18:29:29
@@ -333,7 +333,33 @@ iplmain(int is_interactive, char *initia
printf("(graphics).\n");
strcat(f.cmdline, "tty0");
if (strstr(f.cmdline, " sti=") == 0)
- strcat(f.cmdline, " sti=0");
+ {
+ struct {
+ unsigned char flags;
+ unsigned char bc[6];
+ unsigned char mod;
+ } cons;
+ int i;
+
+ strcat (f.cmdline, " sti=");
+ if (pdc_read_conspath ((unsigned char *)&cons) > 0)
+ {
+ char pathcomp[4];
+
+ for (i = 0; i < 6; i++)
+ {
+ if (cons.bc[i] < 64)
+ {
+ sprintf (pathcomp, "%d/", cons.bc[i]);
+ strcat (f.cmdline, pathcomp);
+ }
+ }
+ sprintf (pathcomp, "%d", cons.mod);
+ strcat (f.cmdline, pathcomp);
+ }
+ else
+ strcat (f.cmdline, "0");
+ }
if (strstr(f.cmdline, " sti_font=") == 0)
strcat(f.cmdline, " sti_font=VGA8x16");
if (strstr(f.cmdline, " TERM=") == 0)
Index: ipl/pdc_misc.c
===================================================================
RCS file: /home/cvs/parisc/palo/ipl/pdc_misc.c,v
retrieving revision 1.13
diff -u -p -r1.13 pdc_misc.c
--- ipl/pdc_misc.c 2001/11/19 03:54:42 1.13
+++ ipl/pdc_misc.c 2002/01/06 02:20:43
@@ -19,6 +19,7 @@
#define PDC_RETURN_MASK 0
#define PDC_RETURN_DEFAULTS 1
#define PDC_SET_DEFAULTS 2
+#define PDC_STABLE 10
void die(const char *s)
{
@@ -283,6 +284,21 @@ pdc_iodc_bootin(unsigned devaddr, char *
return 0; /* count = 0 at EOF */
}
else if (r >= 0)
+ {
+ convert_from_wide(pdc_result);
+ return pdc_result[0]; /* count */
+ }
+ return r; /* r < 0; error */
+}
+
+int
+pdc_read_conspath(unsigned char *memaddr)
+{
+ int r;
+
+ r = firmware_call(mem_pdc, PDC_STABLE, 0, 96, memaddr, 8);
+
+ if (r >= 0)
{
convert_from_wide(pdc_result);
return pdc_result[0]; /* count */
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ Alexander Viro on linux-kernel ]