Commit 7eae642f authored by David S. Miller's avatar David S. Miller

[SPARC64]: Implement SUN4V PCI config space access.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bade5622
...@@ -74,15 +74,47 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { ...@@ -74,15 +74,47 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = {
static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value) int where, int size, u32 *value)
{ {
/* XXX Implement me! XXX */ struct pci_pbm_info *pbm = bus_dev->sysdata;
return 0; unsigned long devhandle = pbm->devhandle;
unsigned int bus = bus_dev->number;
unsigned int device = PCI_SLOT(devfn);
unsigned int func = PCI_FUNC(devfn);
unsigned long ret;
ret = pci_sun4v_config_get(devhandle,
HV_PCI_DEVICE_BUILD(bus, device, func),
where, size);
switch (size) {
case 1:
*value = ret & 0xff;
break;
case 2:
*value = ret & 0xffff;
break;
case 4:
*value = ret & 0xffffffff;
break;
};
return PCIBIOS_SUCCESSFUL;
} }
static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value) int where, int size, u32 value)
{ {
/* XXX Implement me! XXX */ struct pci_pbm_info *pbm = bus_dev->sysdata;
return 0; unsigned long devhandle = pbm->devhandle;
unsigned int bus = bus_dev->number;
unsigned int device = PCI_SLOT(devfn);
unsigned int func = PCI_FUNC(devfn);
unsigned long ret;
ret = pci_sun4v_config_put(devhandle,
HV_PCI_DEVICE_BUILD(bus, device, func),
where, size, value);
return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops pci_sun4v_ops = { static struct pci_ops pci_sun4v_ops = {
......
...@@ -16,5 +16,14 @@ extern unsigned long pci_sun4v_iommu_map(unsigned long devhandle, ...@@ -16,5 +16,14 @@ extern unsigned long pci_sun4v_iommu_map(unsigned long devhandle,
extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle,
unsigned long tsbid, unsigned long tsbid,
unsigned long num_ttes); unsigned long num_ttes);
extern unsigned long pci_sun4v_config_get(unsigned long devhandle,
unsigned long pci_device,
unsigned long config_offset,
unsigned long size);
extern int pci_sun4v_config_put(unsigned long devhandle,
unsigned long pci_device,
unsigned long config_offset,
unsigned long size,
unsigned long data);
#endif /* !(_PCI_SUN4V_H) */ #endif /* !(_PCI_SUN4V_H) */
...@@ -54,3 +54,51 @@ pci_sun4v_iommu_demap: ...@@ -54,3 +54,51 @@ pci_sun4v_iommu_demap:
ta HV_FAST_TRAP ta HV_FAST_TRAP
retl retl
mov %o1, %o0 mov %o1, %o0
/* %o0: devhandle
* %o1: pci_device
* %o2: pci_config_offset
* %o3: size
*
* returns %o0: data
*
* If there is an error, the data will be returned
* as all 1's.
*/
.globl pci_sun4v_config_get
pci_sun4v_config_get:
mov %o3, %o4
mov %o2, %o3
mov %o1, %o2
mov %o0, %o1
mov HV_FAST_PCI_CONFIG_GET, %o0
ta HV_FAST_TRAP
brnz,a,pn %o1, 1f
mov -1, %o2
1: retl
mov %o2, %o0
/* %o0: devhandle
* %o1: pci_device
* %o2: pci_config_offset
* %o3: size
* %o4: data
*
* returns %o0: status
*
* status will be zero if the operation completed
* successfully, else -1 if not
*/
.globl pci_sun4v_config_put
pci_sun4v_config_put:
mov %o3, %o4
mov %o2, %o3
mov %o1, %o2
mov %o0, %o1
mov HV_FAST_PCI_CONFIG_PUT, %o0
ta HV_FAST_TRAP
brnz,a,pn %o1, 1f
mov -1, %o1
1: retl
mov %o1, %o0
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