The current SCx200 drivers use a fixed base address of 0x9000 for the
Configuration Block, but some systems (at least the Soekris net4801)
uses a base address of 0x6000. This patch first tries the fixed address
then - if no configuration block could be found - tries the address
written to the Configuration Block Address Scratchpad register by the
BIOS.
Signed-off-by: Henrik Brix Andersen <[EMAIL PROTECTED]>
---
--- linux-2.6.11-rc4/arch/i386/kernel/scx200.c.orig 2005-02-22
12:44:24.0 +0100
+++ linux-2.6.11-rc4/arch/i386/kernel/scx200.c 2005-02-23 11:48:39.0
+0100
@@ -13,6 +13,9 @@
#include
+/* Verify that the configuration block really is there */
+#define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
+
#define NAME "scx200"
MODULE_AUTHOR("Christer Weinigel <[EMAIL PROTECTED]>");
@@ -22,9 +25,13 @@ MODULE_LICENSE("GPL");
unsigned scx200_gpio_base = 0;
long scx200_gpio_shadow[2];
+unsigned scx200_cb_base = 0;
+
static struct pci_device_id scx200_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_XBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_XBUS) },
{ },
};
MODULE_DEVICE_TABLE(pci,scx200_tbl);
@@ -45,22 +52,39 @@ static int __devinit scx200_probe(struct
int bank;
unsigned base;
- base = pci_resource_start(pdev, 0);
- printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
-
- if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0)
{
- printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
- return -EBUSY;
+ if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE ||
+ pdev->device == PCI_DEVICE_ID_NS_SC1100_BRIDGE) {
+ base = pci_resource_start(pdev, 0);
+ printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
+
+ if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200
GPIO") == 0) {
+ printk(KERN_ERR NAME ": can't allocate I/O for
GPIOs\n");
+ return -EBUSY;
+ }
+
+ scx200_gpio_base = base;
+
+ /* read the current values driven on the GPIO signals */
+ for (bank = 0; bank < 2; ++bank)
+ scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10
* bank);
+
+ } else {
+ /* find the base of the Configuration Block */
+ if (scx200_cb_probe(SCx200_CB_BASE_FIXED)) {
+ scx200_cb_base = SCx200_CB_BASE_FIXED;
+ } else {
+ pci_read_config_dword(pdev, SCx200_CBA_SCRATCH, &base);
+ if (scx200_cb_probe(base)) {
+ scx200_cb_base = base;
+ } else {
+ printk(KERN_WARNING NAME ": Configuration Block
not found\n");
+ return -ENODEV;
+ }
+ }
+ printk(KERN_INFO NAME ": Configuration Block base 0x%x\n",
scx200_cb_base);
}
- scx200_gpio_base = base;
-
- /* read the current values driven on the GPIO signals */
- for (bank = 0; bank < 2; ++bank)
- scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
-
return 0;
-
}
u32 scx200_gpio_configure(int index, u32 mask, u32 bits)
@@ -134,6 +158,7 @@ EXPORT_SYMBOL(scx200_gpio_shadow);
EXPORT_SYMBOL(scx200_gpio_lock);
EXPORT_SYMBOL(scx200_gpio_configure);
EXPORT_SYMBOL(scx200_gpio_dump);
+EXPORT_SYMBOL(scx200_cb_base);
/*
Local variables:
--- linux-2.6.11-rc4/drivers/mtd/maps/scx200_docflash.c.orig2005-02-22
14:27:59.0 +0100
+++ linux-2.6.11-rc4/drivers/mtd/maps/scx200_docflash.c 2005-02-22
16:12:00.0 +0100
@@ -92,17 +92,16 @@ static int __init init_scx200_docflash(v
PCI_DEVICE_ID_NS_SCx200_BRIDGE,
NULL)) == NULL)
return -ENODEV;
-
- if (!scx200_cb_probe(SCx200_CB_BASE)) {
- printk(KERN_WARNING NAME ": no configuration block found\n");
+
+ /* check that we have found the configuration block */
+ if (!scx200_cb_present())
return -ENODEV;
- }
if (probe) {
/* Try to use the present flash mapping if any */
pci_read_config_dword(bridge, SCx200_DOCCS_BASE, &base);
pci_read_config_dword(bridge, SCx200_DOCCS_CTRL, &ctrl);
- pmr = inl(SCx200_CB_BASE + SCx200_PMR);
+ pmr = inl(scx200_cb_base + SCx200_PMR);
if (base == 0
|| (ctrl & 0x0700) != 0x0700
@@ -155,14 +154,14 @@ static int __init init_scx200_docflash(v
pci_w