Commit cd7ab7bd authored by Hanna V. Linder's avatar Hanna V. Linder Committed by Greg Kroah-Hartman

[PATCH] PCI: mips pci_ops changes

mips pci ops changes
parent 935583d7
...@@ -43,137 +43,118 @@ static void nile4_post_pci_access0(void) ...@@ -43,137 +43,118 @@ static void nile4_post_pci_access0(void)
} }
static int nile4_pci_read_config_dword(struct pci_dev *dev, static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
int where, u32 * val) int size, u32 * val)
{ {
int slot_num, func_num; int status, slot_num, func_num;
u32 base; u32 result, base;
/* switch (size) {
* For starters let's do configuration cycle 0 only (one bus only) case 4:
*/ /*
if (dev->bus->number) * For starters let's do configuration cycle 0 only
return PCIBIOS_FUNC_NOT_SUPPORTED; * (one bus only)
*/
slot_num = PCI_SLOT(dev->devfn); if (bus->number)
func_num = PCI_FUNC(dev->devfn); return PCIBIOS_FUNC_NOT_SUPPORTED;
if (slot_num == 5) {
/* slot_num = PCI_SLOT(devfn);
* This is Nile 4 and it will crash if we access it like other func_num = PCI_FUNC(devfn);
* devices if (slot_num == 5) {
*/ /*
*val = nile4_in32(NILE4_PCI_BASE + where); * This is Nile 4 and it will crash if we access it
return PCIBIOS_SUCCESSFUL; * like other devices
} */
base = nile4_pre_pci_access0(slot_num); *val = nile4_in32(NILE4_PCI_BASE + where);
*val = return PCIBIOS_SUCCESSFUL;
*((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))); }
nile4_post_pci_access0(); base = nile4_pre_pci_access0(slot_num);
return PCIBIOS_SUCCESSFUL; *val = *((volatile u32 *) (base + (func_num << 8) +
} (where & 0xfc)));
nile4_post_pci_access0();
static int nile4_pci_write_config_dword(struct pci_dev *dev, int where, return PCIBIOS_SUCCESSFUL;
u32 val)
{ case 2:
int slot_num, func_num; status = nile4_pci_read(bus, devfn, where, 4, &result);
u32 base; if (status != PCIBIOS_SUCCESSFUL)
return status;
/* if (where & 2)
* For starters let's do configuration cycle 0 only (one bus only) result >>= 16;
*/ *val = (u16)(result & 0xffff);
if (dev->bus->number) break;
return PCIBIOS_FUNC_NOT_SUPPORTED; case 1:
status = nile4_pci_read(bus, devfn, where, 4, &result);
slot_num = PCI_SLOT(dev->devfn); if (status != PCIBIOS_SUCCESSFUL)
func_num = PCI_FUNC(dev->devfn); return status;
if (slot_num == 5) { if (where & 1)
/* result >>= 8;
* This is Nile 4 and it will crash if we access it like other if (where & 2)
* devices result >>= 16;
*/ *val = (u8)(result & 0xff);
nile4_out32(NILE4_PCI_BASE + where, val); break;
return PCIBIOS_SUCCESSFUL;
} }
base = nile4_pre_pci_access0(slot_num);
*((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))) =
val;
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
result >>= 16;
*val = result & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_byte(struct pci_dev *dev, int where, static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
u8 * val) int size, u32 val)
{ {
int status; int status, slot_num, func_num, shift = 0;
u32 result; u32 result, base;
status = nile4_pci_read_config_dword(dev, where, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 1)
result >>= 8;
if (where & 2)
result >>= 16;
*val = result & 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_word(struct pci_dev *dev, int where, switch (size) {
u16 val) case 4:
{ /*
int status, shift = 0; * For starters let's do configuration cycle 0 only
u32 result; * (one bus only)
*/
status = nile4_pci_read_config_dword(dev, where, &result); if (bus->number)
if (status != PCIBIOS_SUCCESSFUL) return PCIBIOS_FUNC_NOT_SUPPORTED;
return status;
if (where & 2) slot_num = PCI_SLOT(devfn);
shift += 16; func_num = PCI_FUNC(devfn);
result &= ~(0xffff << shift); if (slot_num == 5) {
result |= val << shift; /*
return nile4_pci_write_config_dword(dev, where, result); * This is Nile 4 and it will crash if we access
} * it like other devices
*/
static int nile4_pci_write_config_byte(struct pci_dev *dev, int where, nile4_out32(NILE4_PCI_BASE + where, val);
u8 val) return PCIBIOS_SUCCESSFUL;
{ }
int status, shift = 0; base = nile4_pre_pci_access0(slot_num);
u32 result; *((volatile u32 *) (base + (func_num << 8) +
(where & 0xfc))) = val;
status = nile4_pci_read_config_dword(dev, where, &result); nile4_post_pci_access0();
if (status != PCIBIOS_SUCCESSFUL) return PCIBIOS_SUCCESSFUL;
return status;
if (where & 2) case 2:
shift += 16; status = nile4_pci_read(bus, devfn, where, 4, &result);
if (where & 1) if (status != PCIBIOS_SUCCESSFUL)
shift += 8; return status;
result &= ~(0xff << shift); if (where & 2)
result |= val << shift; shift += 16;
return nile4_pci_write_config_dword(dev, where, result); result &= ~(0xffff << shift);
result |= (u16)(val << shift);
break;
case 1:
status = nile4_pci_read(bus, devfn, where, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
shift += 16;
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= (u8)(val << shift);
break;
}
return nile4_pci_write(bus, devfn, where, 4, result);
} }
struct pci_ops nile4_pci_ops = { struct pci_ops nile4_pci_ops = {
nile4_pci_read_config_byte, .read = nile4_pci_read,
nile4_pci_read_config_word, .write = nile4_pci_write,
nile4_pci_read_config_dword,
nile4_pci_write_config_byte,
nile4_pci_write_config_word,
nile4_pci_write_config_dword
}; };
struct { struct {
......
...@@ -51,145 +51,106 @@ static void nile4_post_pci_access0(void) ...@@ -51,145 +51,106 @@ static void nile4_post_pci_access0(void)
nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000); nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
} }
static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
static int nile4_pci_read_config_dword(struct pci_dev *dev, int size, u32 * val)
int where, u32 * val)
{
int slot_num, func_num;
u32 base;
u32 addr;
/*
* Do we need to generate type 1 configure transaction?
*/
if (dev->bus->number) {
/* FIXME - not working yet */
return PCIBIOS_FUNC_NOT_SUPPORTED;
/*
* the largest type 1 configuration addr is 16M, < 256M
* config space
*/
slot_num = 0;
addr =
(dev->bus->number << 16) | (dev->devfn <
8) | where | 1;
} else {
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
addr = (func_num << 8) + where;
}
base = nile4_pre_pci_access0(slot_num);
*val = *(volatile u32 *) (base + addr);
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
{ {
int slot_num, func_num; int status, slot_num, func_num;
u32 base; u32 result, base, addr;
u32 addr;
if(size == 4) {
/* /* Do we need to generate type 1 configure transaction? */
* Do we need to generate type 1 configure transaction? if (bus->number) {
*/ /* FIXME - not working yet */
if (dev->bus->number) { return PCIBIOS_FUNC_NOT_SUPPORTED;
/* FIXME - not working yet */ /*
return PCIBIOS_FUNC_NOT_SUPPORTED; * the largest type 1 configuration addr is 16M,
* < 256M config space
/* the largest type 1 configuration addr is 16M, < 256M config space */ */
slot_num = 0; slot_num = 0;
addr = addr = (bus->number << 16) | (devfn < 8) | where | 1;
(dev->bus->number << 16) | (dev->devfn < } else {
8) | where | 1; slot_num = PCI_SLOT(devfn);
} else { func_num = PCI_FUNC(devfn);
slot_num = PCI_SLOT(dev->devfn); addr = (func_num << 8) + where;
func_num = PCI_FUNC(dev->devfn); }
addr = (func_num << 8) + where; base = nile4_pre_pci_access0(slot_num);
*val = *(volatile u32 *) (base + addr);
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
} }
base = nile4_pre_pci_access0(slot_num); status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
*(volatile u32 *) (base + addr) = val;
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
result >>= 16;
*val = result & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL) if (status != PCIBIOS_SUCCESSFUL)
return status; return status;
if (where & 1) switch (size) {
result >>= 8; case 1:
if (where & 2) if (where & 1)
result >>= 16; result >>= 8;
*val = result & 0xff; if (where & 2)
result >>= 16;
*val = (u8)(result & 0xff);
break;
case 2:
if (where & 2)
result >>= 16;
*val = (u16)(result & 0xffff);
break;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int nile4_pci_write_config_word(struct pci_dev *dev, int where, static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
u16 val) int size, u32 val)
{ {
int status, shift = 0; int status, slot_num, func_num, shift = 0;
u32 result; u32 result, base, addr;
status = nile4_pci_read_config_dword(dev, where & ~3, &result); status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
if (status != PCIBIOS_SUCCESSFUL) if (status != PCIBIOS_SUCCESSFUL)
return status; return status;
if (where & 2) switch (size) {
shift += 16; case 1:
result &= ~(0xffff << shift); if (where & 2)
result |= val << shift; shift += 16;
return nile4_pci_write_config_dword(dev, where & ~3, result); if (where & 1)
} shift += 8;
result &= ~(0xff << shift);
static int nile4_pci_write_config_byte(struct pci_dev *dev, int where, result |= val << shift;
u8 val) break;
{ case 2:
int status, shift = 0; if (where & 2)
u32 result; shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
break;
case 4:
/* Do we need to generate type 1 configure transaction? */
if (bus->number) {
/* FIXME - not working yet */
return PCIBIOS_FUNC_NOT_SUPPORTED;
/* the largest type 1 configuration addr is 16M,
* < 256M config space */
slot_num = 0;
addr = (bus->number << 16) | (devfn < 8) |
where | 1;
} else {
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
addr = (func_num << 8) + where;
}
status = nile4_pci_read_config_dword(dev, where & ~3, &result); base = nile4_pre_pci_access0(slot_num);
if (status != PCIBIOS_SUCCESSFUL) *(volatile u32 *) (base + addr) = val;
return status; nile4_post_pci_access0();
if (where & 2) return PCIBIOS_SUCCESSFUL;
shift += 16; }
if (where & 1) return nile4_pci_write(bus, devfn, where & ~3, 4, result);
shift += 8;
result &= ~(0xff << shift);
result |= val << shift;
return nile4_pci_write_config_dword(dev, where & ~3, result);
} }
struct pci_ops nile4_pci_ops = { struct pci_ops nile4_pci_ops = {
nile4_pci_read_config_byte, .read = nile4_pci_read,
nile4_pci_read_config_word, .write = nile4_pci_write,
nile4_pci_read_config_dword,
nile4_pci_write_config_byte,
nile4_pci_write_config_word,
nile4_pci_write_config_dword
}; };
struct { struct {
...@@ -274,13 +235,13 @@ static void __init ddb5476_pci_fixup(void) ...@@ -274,13 +235,13 @@ static void __init ddb5476_pci_fixup(void)
pci_pmu = dev; /* for LEDs D2 and D3 */ pci_pmu = dev; /* for LEDs D2 and D3 */
/* Program the lines for LEDs D2 and D3 to output */ /* Program the lines for LEDs D2 and D3 to output */
nile4_pci_read_config_byte(dev, 0x7d, &t8); nile4_pci_read(dev->bus, dev->devfn, 0x7d, 1, &t8);
t8 |= 0xc0; t8 |= 0xc0;
nile4_pci_write_config_byte(dev, 0x7d, t8); nile4_pci_write(dev->bus, dev->devfn, 0x7d, 1, t8);
/* Turn LEDs D2 and D3 off */ /* Turn LEDs D2 and D3 off */
nile4_pci_read_config_byte(dev, 0x7e, &t8); nile4_pci_read(dev->bus, dev->devfn, 0x7e, 1, &t8);
t8 |= 0xc0; t8 |= 0xc0;
nile4_pci_write_config_byte(dev, 0x7e, t8); nile4_pci_write(dev->bus, dev->devfn, 0x7e, 1, t8);
} else if (dev->vendor == PCI_VENDOR_ID_AL && } else if (dev->vendor == PCI_VENDOR_ID_AL &&
dev->device == 0x5229) { dev->device == 0x5229) {
int i; int i;
......
...@@ -134,173 +134,138 @@ static inline void ddb_close_config_base(struct pci_config_swap *swap) ...@@ -134,173 +134,138 @@ static inline void ddb_close_config_base(struct pci_config_swap *swap)
ddb_out32(swap->pmr, swap->pmr_backup); ddb_out32(swap->pmr, swap->pmr_backup);
} }
static int read_config_dword(struct pci_config_swap *swap, static int read_config(struct pci_config_swap *swap,
struct pci_dev *dev, struct pci_bus *bus,
unsigned int devfn,
u32 where, u32 where,
int size,
u32 *val) u32 *val)
{ {
u32 bus, slot_num, func_num; u32 busnum, slot_num, func_num, base, result;
u32 base; int status
MIPS_ASSERT((where & 3) == 0); switch (size) {
MIPS_ASSERT(where < (1 << 8)); case 4:
MIPS_ASSERT((where & 3) == 0);
MIPS_ASSERT(where < (1 << 8));
/* check if the bus is top-level */
if (bus->parent != NULL) {
busnum = bus->number;
MIPS_ASSERT(busnum != 0);
} else {
busnum = 0;
}
/* check if the bus is top-level */ slot_num = PCI_SLOT(devfn);
if (dev->bus->parent != NULL) { func_num = PCI_FUNC(devfn);
bus = dev->bus->number; base = ddb_access_config_base(swap, busnum, slot_num);
MIPS_ASSERT(bus != 0); *val = *(volatile u32*) (base + (func_num << 8) + where);
} else { ddb_close_config_base(swap);
bus = 0; return PCIBIOS_SUCCESSFUL;
case 2:
MIPS_ASSERT((where & 1) == 0);
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (where & 2) result >>= 16;
*val = (u16)(result & 0xffff);
return status;
case 1:
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (where & 1) result >>= 8;
if (where & 2) result >>= 16;
*val = (u8)(result & 0xff);
return status;
} }
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
base = ddb_access_config_base(swap, bus, slot_num);
*val = *(volatile u32*) (base + (func_num << 8) + where);
ddb_close_config_base(swap);
return PCIBIOS_SUCCESSFUL;
} }
static int read_config_word(struct pci_config_swap *swap, static int write_config(struct pci_config_swap *swap,
struct pci_dev *dev, struct pci_bus *bus,
u32 where, unsigned int devfn,
u16 *val)
{
int status;
u32 result;
MIPS_ASSERT((where & 1) == 0);
status = read_config_dword(swap, dev, where & ~3, &result);
if (where & 2) result >>= 16;
*val = result & 0xffff;
return status;
}
static int read_config_byte(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u8 *val)
{
int status;
u32 result;
status = read_config_dword(swap, dev, where & ~3, &result);
if (where & 1) result >>= 8;
if (where & 2) result >>= 16;
*val = result & 0xff;
return status;
}
static int write_config_dword(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where, u32 where,
int size,
u32 val) u32 val)
{ {
u32 bus, slot_num, func_num; u32 busnum, slot_num, func_num, base, results;
u32 base; int status, shift = 0;
MIPS_ASSERT((where & 3) == 0); switch (size) {
MIPS_ASSERT(where < (1 << 8)); case 4:
MIPS_ASSERT((where & 3) == 0);
MIPS_ASSERT(where < (1 << 8));
/* check if the bus is top-level */
if (bus->parent != NULL) {
busnum = bus->number;
MIPS_ASSERT(busnum != 0);
} else {
busnum = 0;
}
/* check if the bus is top-level */ slot_num = PCI_SLOT(devfn);
if (dev->bus->parent != NULL) { func_num = PCI_FUNC(devfn);
bus = dev->bus->number; base = ddb_access_config_base(swap, busnum, slot_num);
MIPS_ASSERT(bus != 0); *(volatile u32*) (base + (func_num << 8) + where) = val;
} else { ddb_close_config_base(swap);
bus = 0; return PCIBIOS_SUCCESSFUL;
case 2:
MIPS_ASSERT((where & 1) == 0);
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= (u16)(val << shift);
return write_config(swap, bus, devfn, where & ~3, size,
result);
case 1:
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
shift += 16;
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= (u8)(val << shift);
return write_config(swap, bus, devfn, where & ~3, size,
result);
} }
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
base = ddb_access_config_base(swap, bus, slot_num);
*(volatile u32*) (base + (func_num << 8) + where) = val;
ddb_close_config_base(swap);
return PCIBIOS_SUCCESSFUL;
}
static int write_config_word(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u16 val)
{
int status, shift=0;
u32 result;
MIPS_ASSERT((where & 1) == 0);
status = read_config_dword(swap, dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
return write_config_dword(swap, dev, where & ~3, result);
} }
static int write_config_byte(struct pci_config_swap *swap, #define MAKE_PCI_OPS(prefix, rw, pciswap) \
struct pci_dev *dev, static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, \
u32 where, int where, int size, u32 val) \
u8 val)
{
int status, shift=0;
u32 result;
status = read_config_dword(swap, dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
shift += 16;
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= val << shift;
return write_config_dword(swap, dev, where & ~3, result);
}
#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
{ \ { \
return rw##_config_##unitname(pciswap, \ return rw##_config(pciswap, bus, devfn, \
dev, \ where, size, val); \
where, \
val); \
} }
MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap) MAKE_PCI_OPS(extpci, read, &ext_pci_swap)
MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap) MAKE_PCI_OPS(extpci, write, &ext_pci_swap)
MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
MAKE_PCI_OPS(iopci, read, byte, u8 *, &io_pci_swap)
MAKE_PCI_OPS(iopci, read, word, u16 *, &io_pci_swap)
MAKE_PCI_OPS(iopci, read, dword, u32 *, &io_pci_swap)
MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
MAKE_PCI_OPS(iopci, write, byte, u8, &io_pci_swap) MAKE_PCI_OPS(iopci, read, &io_pci_swap)
MAKE_PCI_OPS(iopci, write, word, u16, &io_pci_swap) MAKE_PCI_OPS(iopci, write, &io_pci_swap)
MAKE_PCI_OPS(iopci, write, dword, u32, &io_pci_swap)
struct pci_ops ddb5477_ext_pci_ops ={ struct pci_ops ddb5477_ext_pci_ops ={
extpci_read_config_byte, .read = extpci_read_config,
extpci_read_config_word, .write = extpci_write_config,
extpci_read_config_dword,
extpci_write_config_byte,
extpci_write_config_word,
extpci_write_config_dword
}; };
struct pci_ops ddb5477_io_pci_ops ={ struct pci_ops ddb5477_io_pci_ops ={
iopci_read_config_byte, .read = iopci_read_config,
iopci_read_config_word, .write = iopci_write_config,
iopci_read_config_dword,
iopci_write_config_byte,
iopci_write_config_word,
iopci_write_config_dword
}; };
#if defined(CONFIG_LL_DEBUG) #if defined(CONFIG_LL_DEBUG)
......
This diff is collapsed.
...@@ -45,18 +45,17 @@ ...@@ -45,18 +45,17 @@
#undef DEBUG_CONFIG_CYCLES #undef DEBUG_CONFIG_CYCLES
static int static int
it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, it8172_pcibios_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, unsigned char where, u32 *data)
unsigned char where, u32 *data)
{ {
/* /*
* config cycles are on 4 byte boundary only * config cycles are on 4 byte boundary only
*/ */
unsigned char bus = dev->bus->number; unsigned char bus = bus->number;
unsigned char dev_fn = dev->devfn; unsigned char dev_fn = (char)devfn;
#ifdef DEBUG_CONFIG_CYCLES #ifdef DEBUG_CONFIG_CYCLES
printk("it config: type %d dev %x bus %d dev_fn %x data %x\n", printk("it config: type %d bus %d dev_fn %x data %x\n",
access_type, dev, bus, dev_fn, *data); access_type, bus, dev_fn, *data);
#endif #endif
...@@ -86,121 +85,63 @@ it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, ...@@ -86,121 +85,63 @@ it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
* read/write a 32bit word and mask/modify the data we actually want. * read/write a 32bit word and mask/modify the data we actually want.
*/ */
static int static int
it8172_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val) it8172_pcibios_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
{ {
u32 data = 0; u32 data = 0;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) if ((size == 2) && (where & 1))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xff;
#ifdef DEBUG
printk("cfg read byte: bus %d dev_fn %x where %x: val %x\n",
dev->bus->number, dev->devfn, where, *val);
#endif
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
else if ((size == 4) && (where & 3))
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xffff;
#ifdef DEBUG
printk("cfg read word: bus %d dev_fn %x where %x: val %x\n",
dev->bus->number, dev->devfn, where, *val);
#endif
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
{
u32 data = 0;
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1; return -1;
if (size == 1)
*val = (u8)(data >> ((where & 3) << 3)) & 0xff;
else if (size == 2)
*val = (u16)(data >> ((where & 3) << 3)) & 0xffff;
else if (size == 4)
*val = data;
*val = data;
#ifdef DEBUG #ifdef DEBUG
printk("cfg read dword: bus %d dev_fn %x where %x: val %x\n", printk("cfg read: bus %d devfn %x where %x size %x: val %x\n",
dev->bus->number, dev->devfn, where, *val); bus->number, devfn, where, size, *val);
#endif #endif
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int static int
it8172_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val) it8172_pcibios_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{ {
u32 data = 0; u32 data = 0;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) if ((size == 2) && (where & 1))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
else if (size == 4) {
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
return -1;
return PCIBIOS_SUCCESSFUL;
}
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) if (it8172_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1; return -1;
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
{
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val)) if(size == 1) {
return -1; data = (u8)(data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
} else if (size == 2) {
data = (u16)(data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
struct pci_ops it8172_pci_ops = { struct pci_ops it8172_pci_ops = {
it8172_pcibios_read_config_byte, .read = it8172_pcibios_read,
it8172_pcibios_read_config_word, .write = it8172_pcibios_write,
it8172_pcibios_read_config_dword,
it8172_pcibios_write_config_byte,
it8172_pcibios_write_config_word,
it8172_pcibios_write_config_dword
}; };
void __init pcibios_init(void) void __init pcibios_init(void)
......
...@@ -37,11 +37,9 @@ ...@@ -37,11 +37,9 @@
#define PCI_ACCESS_WRITE 1 #define PCI_ACCESS_WRITE 1
static int static int
mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, mips_pcibios_config_access(unsigned char access_type, struct pci_bus *bus_dev, unsigned int dev_fn, unsigned char where, u32 *data)
unsigned char where, u32 *data)
{ {
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned char dev_fn = dev->devfn;
u32 intr; u32 intr;
if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
...@@ -101,109 +99,56 @@ mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, ...@@ -101,109 +99,56 @@ mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
* read/write a 32bit word and mask/modify the data we actually want. * read/write a 32bit word and mask/modify the data we actually want.
*/ */
static int static int
mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val) mips_pcibios_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
{ {
u32 data = 0; u32 data = 0;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) if((size == 2) && (where & 1))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
else if ((size == 4) && (where & 3))
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
{
u32 data = 0;
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1; return -1;
if(size == 1)
*val = data; *val = (u8)(data >> ((where & 3) << 3)) & 0xff;
else if (size == 2)
*val = (u16)(data >> ((where & 3) << 3)) & 0xffff;
else if (size == 4)
*val = data;
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int static int
mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val) mips_pcibios_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{ {
u32 data = 0; u32 data = 0;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) if((size == 2) && (where & 1))
return -1;
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
{
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
else if (size == 4) {
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val)) if(where & 3)
return -1; return PCIBIOS_BAD_REGISTER_NUMBER;
if(mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &val))
return -1;
return PCIBIOS_SUCCESSFUL;
}
if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
if(size == 1) {
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
} else if (size == 2) {
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
struct pci_ops mips_pci_ops = { struct pci_ops mips_pci_ops = {
mips_pcibios_read_config_byte, .read = mips_pcibios_read,
mips_pcibios_read_config_word, .write = mips_pcibios_write,
mips_pcibios_read_config_dword,
mips_pcibios_write_config_byte,
mips_pcibios_write_config_word,
mips_pcibios_write_config_dword
}; };
void __init pcibios_init(void) void __init pcibios_init(void)
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
#define mkaddr(dev, where) \ #define mkaddr(bus, devfn, where) \
do { \ do { \
if ((dev)->bus->number == 0) \ if (bus->number == 0) \
return -1; \ return -1; \
*(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \
((dev->bus->number & 0xff) << 0x10) | \ ((bus->number & 0xff) << 0x10) | \
((dev->devfn & 0xff) << 0x08) | \ ((devfn & 0xff) << 0x08) | \
(where & 0xfc); \ (where & 0xfc); \
} while(0) } while(0)
...@@ -69,87 +69,67 @@ static void pcimt_pcibios_fixup (void) ...@@ -69,87 +69,67 @@ static void pcimt_pcibios_fixup (void)
* We can't address 8 and 16 bit words directly. Instead we have to * 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. * read/write a 32bit word and mask/modify the data we actually want.
*/ */
static int pcimt_read_config_byte (struct pci_dev *dev, static int pcimt_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
int where, unsigned char *val)
{ {
u32 res; u32 res;
mkaddr(dev, where); switch (size) {
res = *(volatile u32 *)PCIMT_CONFIG_DATA; case 1:
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; mkaddr(bus, devfn, where);
*val = res; res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
return PCIBIOS_SUCCESSFUL; *val = (u8)res;
} break;
case 2:
static int pcimt_read_config_word (struct pci_dev *dev, if (where & 1)
int where, unsigned short *val) return PCIBIOS_BAD_REGISTER_NUMBER;
{ mkaddr(bus, devfn, where);
u32 res; res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
if (where & 1) *val = (u16)res;
return PCIBIOS_BAD_REGISTER_NUMBER; break;
mkaddr(dev, where); case 4:
res = *(volatile u32 *)PCIMT_CONFIG_DATA; if (where & 3)
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; return PCIBIOS_BAD_REGISTER_NUMBER;
*val = res; mkaddr(bus, devfn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
return PCIBIOS_SUCCESSFUL; res = le32_to_cpu(res);
} *val = res;
break;
static int pcimt_read_config_dword (struct pci_dev *dev, }
int where, unsigned int *val)
{
u32 res;
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = le32_to_cpu(res);
*val = res;
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_write_config_byte (struct pci_dev *dev,
int where, unsigned char val)
{
mkaddr(dev, where);
*(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val;
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_write_config_word (struct pci_dev *dev,
int where, unsigned short val)
{
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
*(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int pcimt_write_config_dword (struct pci_dev *dev, static int pcimt_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
int where, unsigned int val)
{ {
if (where & 3) switch (size) {
return PCIBIOS_BAD_REGISTER_NUMBER; case 1:
mkaddr(dev, where); mkaddr(bus, devfn, where);
*(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) =
(u8)le32_to_cpu(val);
break;
case 2:
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(bus, devfn, where);
*(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) =
(u16)le32_to_cpu(val);
break;
case 4:
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(bus, devfn, where);
*(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val);
break;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
struct pci_ops sni_pci_ops = { struct pci_ops sni_pci_ops = {
pcimt_read_config_byte, .read = pcimt_read,
pcimt_read_config_word, .write = pcimt_write,
pcimt_read_config_dword,
pcimt_write_config_byte,
pcimt_write_config_word,
pcimt_write_config_dword
}; };
void __init void __init
......
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