summaryrefslogtreecommitdiffstats
path: root/arch/mips/sni/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sni/pci.c')
-rw-r--r--arch/mips/sni/pci.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/mips/sni/pci.c b/arch/mips/sni/pci.c
index 06edb268f..917d07a81 100644
--- a/arch/mips/sni/pci.c
+++ b/arch/mips/sni/pci.c
@@ -7,6 +7,7 @@
*/
#include <linux/config.h>
#include <linux/bios32.h>
+#include <linux/init.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <asm/byteorder.h>
@@ -18,18 +19,26 @@
extern inline u32 mkaddr(unsigned char bus, unsigned char dev_fn,
unsigned char where)
{
- return (((bus & 0xff) << 0x10) |
- ((dev_fn & 0xff) << 0x08) |
- ((where & 0xfc)));
+ return ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) |
+ (where & 0xfc);
}
static unsigned long sni_rm200_pcibios_fixup (unsigned long memory_start,
unsigned long memory_end)
{
- /* I guess it's ok to do exactly nothing. */
+ /*
+ * TODO: Fix PCI_INTERRUPT_LINE register for onboard cards.
+ * Take care of RM300 revision D boards for where the network
+ * slot became an ordinary PCI slot.
+ */
return memory_start;
}
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
static int sni_rm200_pcibios_read_config_byte (unsigned char bus,
unsigned char dev_fn,
unsigned char where,
@@ -39,7 +48,7 @@ static int sni_rm200_pcibios_read_config_byte (unsigned char bus,
*(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
- res = le32_to_cpu(res);
+ res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
*val = res;
return PCIBIOS_SUCCESSFUL;
@@ -56,7 +65,7 @@ static int sni_rm200_pcibios_read_config_word (unsigned char bus,
return PCIBIOS_BAD_REGISTER_NUMBER;
*(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
- res = le32_to_cpu(res);
+ res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
*val = res;
return PCIBIOS_SUCCESSFUL;
@@ -110,7 +119,7 @@ static int sni_rm200_pcibios_write_config_dword (unsigned char bus,
return PCIBIOS_SUCCESSFUL;
}
-unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end)
+__initfunc(unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end))
{
_pcibios_fixup = sni_rm200_pcibios_fixup;
_pcibios_read_config_byte = sni_rm200_pcibios_read_config_byte;