diff options
author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2009-10-04 19:53:17 +0000 |
---|---|---|
committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2009-10-04 19:53:17 +0000 |
commit | 8fb9ab479d4b4df9d66ea4f2f92fa7cf7ff43db5 (patch) | |
tree | 00a7ec1f4de21518bc2c783975daa58de2885ed1 /target/linux/ramips/files/arch/mips/pci/ops-rt288x.c | |
parent | 63e4465014fd73e1b059cab09ed4a4c6466e1d72 (diff) |
adds pci support for rt288x
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@17855 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ramips/files/arch/mips/pci/ops-rt288x.c')
-rw-r--r-- | target/linux/ramips/files/arch/mips/pci/ops-rt288x.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/target/linux/ramips/files/arch/mips/pci/ops-rt288x.c b/target/linux/ramips/files/arch/mips/pci/ops-rt288x.c new file mode 100644 index 000000000..44dadc9af --- /dev/null +++ b/target/linux/ramips/files/arch/mips/pci/ops-rt288x.c @@ -0,0 +1,70 @@ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <asm/pci.h> +#include <asm/io.h> +#include <linux/init.h> +#include <linux/mod_devicetable.h> +#include <asm/mach-rt288x/rt288x.h> +#include <asm/mach-rt288x/rt288x_pci.h> + +#ifdef CONFIG_PCI + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +static int config_access(unsigned char access_type, struct pci_bus *bus, + unsigned int devfn, unsigned char where, u32 * data) +{ + unsigned int slot = PCI_SLOT(devfn); + unsigned int address; + u8 func = PCI_FUNC(devfn); + address = (bus->number << 16) | (slot << 11) | (func << 8) | (where& 0xfc) | 0x80000000; + writel(address, RT2880_PCI_CONFIG_ADDR); + if (access_type == PCI_ACCESS_WRITE) + writel(*data, RT2880_PCI_CONFIG_DATA); + else + *data = readl(RT2880_PCI_CONFIG_DATA); + return 0; +} + +int +pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) +{ + u32 data = 0; + if(config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + if(size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if(size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + return PCIBIOS_SUCCESSFUL; +} + +int +pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + if(size == 4) + { + data = val; + } else { + if(config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + 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)); + } + if(config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + return PCIBIOS_SUCCESSFUL; +} +#endif |