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

[SPARC64]: Implement SUN4V PCI config space access.

parent bade5622
Loading
Loading
Loading
Loading
+36 −4
Original line number Diff line number Diff line
@@ -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,
				  int where, int size, u32 *value)
{
	/* XXX Implement me! XXX */
	return 0;
	struct pci_pbm_info *pbm = bus_dev->sysdata;
	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,
				   int where, int size, u32 value)
{
	/* XXX Implement me! XXX */
	return 0;
	struct pci_pbm_info *pbm = bus_dev->sysdata;
	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 = {
+9 −0
Original line number Diff line number Diff line
@@ -16,5 +16,14 @@ extern unsigned long pci_sun4v_iommu_map(unsigned long devhandle,
extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle,
					   unsigned long tsbid,
					   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) */
+48 −0
Original line number Diff line number Diff line
@@ -54,3 +54,51 @@ pci_sun4v_iommu_demap:
	ta	HV_FAST_TRAP
	retl
	 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