Resend: Determine SCx200 CB address at run-time
PATCH 1/1 Resend: Determine SCx200 CB address at run-time
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.
This was first sent at Wed, 23 Feb 2005 13:53:33 +0100.
---
arch/i386/kernel/scx200.c +38 -13
@@ -13,6 +13,9 @@#include <linux/scx200.h> +/* 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(structint 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:
drivers/char/watchdog/Kconfig +2 -2
@@ -268,12 +268,12 @@ config SC1200_WDT config SCx200_WDT tristate "National Semiconductor SCx200 Watchdog" - depends on WATCHDOG && X86 && PCI + depends on WATCHDOG && SCx200 && PCI help Enable the built-in watchdog timer support on the National Semiconductor SCx200 processors. - If compiled as a module, it will be called scx200_watchdog. + If compiled as a module, it will be called scx200_wdt. config 60XX_WDT tristate "SBC-60XX Watchdog Timer"
drivers/char/watchdog/scx200_wdt.c +14 -28
95 lines not on this page · raw message
drivers/mtd/maps/Kconfig +1 -1
@@ -159,7 +159,7 @@ config MTD_VMAX config MTD_SCx200_DOCFLASH tristate "Flash device mapped with DOCCS on NatSemi SCx200" - depends on X86 && MTD_CFI && MTD_PARTITIONS + depends on SCx200 && MTD_CFI && MTD_PARTITIONS help Enable support for a flash chip mapped using the DOCCS signal on a National Semiconductor SCx200 processor.
drivers/mtd/maps/scx200_docflash.c +6 -7
@@ -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 & 0x07000000) != 0x07000000
@@ -155,14 +154,14 @@ static int __init init_scx200_docflash(vpci_write_config_dword (bridge, SCx200_DOCCS_BASE, docmem.start);pci_write_config_dword (bridge, SCx200_DOCCS_CTRL, ctrl); - pmr =inl (SCx200_CB_BASE + SCx200_PMR); + pmr =inl (scx200_cb_base + SCx200_PMR);if (width ==8 ) { pmr &= ~(1 <<6 ); }else { pmr |= (1 <<6 ); } -outl (pmr, SCx200_CB_BASE + SCx200_PMR); +outl (pmr, scx200_cb_base + SCx200_PMR); } printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
include/linux/pci_ids.h +2 -0
@@ -386,6 +386,8 @@#define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504#define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505#define PCI_DEVICE_ID_NS_SC1100_BRIDGE 0x0510 +#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 +#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515#define PCI_DEVICE_ID_NS_87410 0xd001#define PCI_VENDOR_ID_TSENG 0x100c
include/linux/scx200.h +6 -4
@@ -7,6 +7,10 @@/* Interesting stuff for the National Semiconductor SCx200 CPU */ +extern unsigned scx200_cb_base; + +#define scx200_cb_present () (scx200_cb_base!=0) +/* F0 PCI Header/Bridge Configuration Registers */ #define SCx200_DOCCS_BASE 0x78/* DOCCS Base Address Register */ #define SCx200_DOCCS_CTRL 0x7c/* DOCCS Control Register */
@@ -15,7 +19,7 @@#define SCx200_GPIO_SIZE 0x2c/* Size of GPIO register block */ /* General Configuration Block */ -#define SCx200_CB_BASE 0x9000/* Base fixed at 0x9000 according to errata */ +#define SCx200_CB_BASE_FIXED 0x9000/* Base fixed at 0x9000 according to errata? */ /* Watchdog Timer */ #define SCx200_WDT_OFFSET 0x00/* offset within configuration block */
@@ -44,9 +48,7 @@#define SCx200_IID 0x3c/* IA On a Chip Identification Number Reg */ #define SCx200_REV 0x3d/* Revision Register */ #define SCx200_CBA 0x3e/* Configuration Base Address Register */ - -/* Verify that the configuration block really is there */ -#define scx200_cb_probe (base) (inw((base) + SCx200_CBA) == (base)) +#define SCx200_CBA_SCRATCH 0x64/* Configuration Base Address Scratchpad */ /* Local variables:
Quoted 10 lines · Henrik Brix Andersen
The current SCx200 drivers use a fixed base address of
0x9000for the Configuration Block, but some systems (at least the Soekris net4801) uses a base address of0x6000. 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.This was first sent at Wed, 23 Feb 2005 13:53:33 +0100.
Signed-off-by Henrik Brix Andersen <[email protected]>
Seems like my GPG signature messed up the in-line patch - it's available from http://dev.gentoo.org/~brix/files/net4801/linux-2.6.11-scx200.patch
Sincerely,
Brix
Signature · 2 lines
Henrik Brix Andersen <[email protected]> Gentoo Linux