/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
 */

#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/sn_sal.h>
#include "xtalk/hubdev.h"
#include <linux/acpi.h>
#include <linux/slab.h>
#include <linux/export.h>


/*
 * The code in this file will only be executed when running with
 * a PROM that has ACPI IO support. (i.e., SN_ACPI_BASE_SUPPORT() == 1)
 */


/*
 * This value must match the UUID the PROM uses
 * (io/acpi/defblk.c) when building a vendor descriptor.
 */
struct acpi_vendor_uuid sn_uuid = {
	.subtype = 0,
	.data	= { 0x2c, 0xc6, 0xa6, 0xfe, 0x9c, 0x44, 0xda, 0x11,
		    0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 },
};

struct sn_pcidev_match {
	u8 bus;
	unsigned int devfn;
	acpi_handle handle;
};

/*
 * Perform the early IO init in PROM.
 */
static long
sal_ioif_init(u64 *result)
{
	struct ia64_sal_retval isrv = {0,0,0,0};

	SAL_CALL_NOLOCK(isrv,
			SN_SAL_IOIF_INIT, 0, 0, 0, 0, 0, 0, 0);
	*result = isrv.v0;
	return isrv.status;
}

/*
 * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
 *			   for all SGIHUB and SGITIO acpi devices defined in the
 *			   DSDT. It obtains the hubdev_info pointer from the
 *			   ACPI vendor resource, which the PROM setup, and sets up the
 *			   hubdev_info in the pda.
 */

static acpi_status __init
sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	u64 addr;
	struct hubdev_info *hubdev;
	struct hubdev_info *hubdev_ptr;
	int i;
	u64 nasid;
	struct acpi_resource *resource;
	acpi_status status;
	struct acpi_resource_vendor_typed *vendor;
	extern void sn_common_hubdev_init(struct hubdev_info *);

	status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
					  &sn_uuid, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR
		       "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
		       "(0x%x) failed for: %s\n", status,
			(char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		return AE_OK;		/* Continue walking namespace */
	}

	resource = buffer.pointer;
	vendor = &resource->data.vendor_typed;
	if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
	    sizeof(struct hubdev_info *)) {
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR
		       "sn_acpi_hubdev_init: Invalid vendor data length: "
		       "%d for: %s\n",
			vendor->byte_length, (char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		goto exit;
	}

	memcpy(&addr, vendor->byte_data, sizeof(struct hubdev_info *));
	hubdev_ptr = __va((struct hubdev_info *) addr);

	nasid = hubdev_ptr->hdi_nasid;
	i = nasid_to_cnodeid(nasid);
	hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
	*hubdev = *hubdev_ptr;
	sn_common_hubdev_init(hubdev);

exit:
	kfree(buffer.pointer);
	return AE_OK;		/* Continue walking namespace */
}

/*
 * sn_get_bussoft_ptr() - The pcibus_bussoft pointer is found in
 *			  the ACPI Vendor resource for this bus.
 */
static struct pcibus_bussoft *
sn_get_bussoft_ptr(struct pci_bus *bus)
{
	u64 addr;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	acpi_handle handle;
	struct pcibus_bussoft *prom_bussoft_ptr;
	struct acpi_resource *resource;
	acpi_status status;
	struct acpi_resource_vendor_typed *vendor;


	handle = acpi_device_handle(PCI_CONTROLLER(bus)->companion);
	status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
					  &sn_uuid, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR "%s: "
		       "acpi_get_vendor_resource() failed (0x%x) for: %s\n",
		       __func__, status, (char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		return NULL;
	}
	resource = buffer.pointer;
	vendor = &resource->data.vendor_typed;

	if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
	     sizeof(struct pcibus_bussoft *)) {
		printk(KERN_ERR
		       "%s: Invalid vendor data length %d\n",
			__func__, vendor->byte_length);
		kfree(buffer.pointer);
		return NULL;
	}
	memcpy(&addr, vendor->byte_data, sizeof(struct pcibus_bussoft *));
	prom_bussoft_ptr = __va((struct pcibus_bussoft *) addr);
	kfree(buffer.pointer);

	return prom_bussoft_ptr;
}

/*
 * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info
 *			    pointers from the vendor resource using the
 *			    provided acpi handle, and copy the structures
 *			    into the argument buffers.
 */
static int
sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
		    struct sn_irq_info **sn_irq_info)
{
	u64 addr;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct sn_irq_info *irq_info, *irq_info_prom;
	struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr;
	struct acpi_resource *resource;
	int ret = 0;
	acpi_status status;
	struct acpi_resource_vendor_typed *vendor;

	/*
	 * The pointer to this device's pcidev_info structure in
	 * the PROM, is in the vendor resource.
	 */
	status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
					  &sn_uuid, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR
		       "%s: acpi_get_vendor_resource() failed (0x%x) for: %s\n",
			__func__, status, (char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		return 1;
	}

	resource = buffer.pointer;
	vendor = &resource->data.vendor_typed;
	if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
	    sizeof(struct pci_devdev_info *)) {
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR
		       "%s: Invalid vendor data length: %d for: %s\n",
			 __func__, vendor->byte_length,
			(char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		ret = 1;
		goto exit;
	}

	pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
	if (!pcidev_ptr)
		panic("%s: Unable to alloc memory for pcidev_info", __func__);

	memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *));
	pcidev_prom_ptr = __va(addr);
	memcpy(pcidev_ptr, pcidev_prom_ptr, sizeof(struct pcidev_info));

	/* Get the IRQ info */
	irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
	if (!irq_info)
		 panic("%s: Unable to alloc memory for sn_irq_info", __func__);

	if (pcidev_ptr->pdi_sn_irq_info) {
		irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info);
		memcpy(irq_info, irq_info_prom, sizeof(struct sn_irq_info));
	}

	*pcidev_info = pcidev_ptr;
	*sn_irq_info = irq_info;

exit:
	kfree(buffer.pointer);
	return ret;
}

static unsigned int
get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
{
	unsigned long long adr;
	acpi_handle child;
	unsigned int devfn;
	int function;
	acpi_handle parent;
	int slot;
	acpi_status status;
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	acpi_get_name(device_handle, ACPI_FULL_PATHNAME, &name_buffer);

	/*
	 * Do an upward search to find the root bus device, and
	 * obtain the host devfn from the previous child device.
	 */
	child = device_handle;
	while (child) {
		status = acpi_get_parent(child, &parent);
		if (ACPI_FAILURE(status)) {
			printk(KERN_ERR "%s: acpi_get_parent() failed "
			       "(0x%x) for: %s\n", __func__, status,
				(char *)name_buffer.pointer);
			panic("%s: Unable to find host devfn\n", __func__);
		}
		if (parent == rootbus_handle)
			break;
		child = parent;
	}
	if (!child) {
		printk(KERN_ERR "%s: Unable to find root bus for: %s\n",
		       __func__, (char *)name_buffer.pointer);
		BUG();
	}

	status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr);
	if (ACPI_FAILURE(status)) {
		printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: %s\n",
		       __func__, status, (char *)name_buffer.pointer);
		panic("%s: Unable to find host devfn\n", __func__);
	}

	kfree(name_buffer.pointer);

	slot = (adr >> 16) & 0xffff;
	function = adr & 0xffff;
	devfn = PCI_DEVFN(slot, function);
	return devfn;
}

/*
 * find_matching_device - Callback routine to find the ACPI device
 *			  that matches up with our pci_dev device.
 *			  Matching is done on bus number and devfn.
 *			  To find the bus number for a particular
 *			  ACPI device, we must look at the _BBN method
 *			  of its parent.
 */
static acpi_status
find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
{
	unsigned long long bbn = -1;
	unsigned long long adr;
	acpi_handle parent = NULL;
	acpi_status status;
	unsigned int devfn;
	int function;
	int slot;
	struct sn_pcidev_match *info = context;
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };

        status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
                                       &adr);
        if (ACPI_SUCCESS(status)) {
		status = acpi_get_parent(handle, &parent);
		if (ACPI_FAILURE(status)) {
			acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
			printk(KERN_ERR
			       "%s: acpi_get_parent() failed (0x%x) for: %s\n",
				__func__, status, (char *)name_buffer.pointer);
			kfree(name_buffer.pointer);
			return AE_OK;
		}
		status = acpi_evaluate_integer(parent, METHOD_NAME__BBN,
					       NULL, &bbn);
		if (ACPI_FAILURE(status)) {
			acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
			printk(KERN_ERR
			  "%s: Failed to find _BBN in parent of: %s\n",
					__func__, (char *)name_buffer.pointer);
			kfree(name_buffer.pointer);
			return AE_OK;
		}

                slot = (adr >> 16) & 0xffff;
                function = adr & 0xffff;
                devfn = PCI_DEVFN(slot, function);
                if ((info->devfn == devfn) && (info->bus == bbn)) {
			/* We have a match! */
			info->handle = handle;
			return 1;
		}
	}
	return AE_OK;
}

/*
 * sn_acpi_get_pcidev_info - Search ACPI namespace for the acpi
 *			     device matching the specified pci_dev,
 *			     and return the pcidev info and irq info.
 */
int
sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
			struct sn_irq_info **sn_irq_info)
{
	unsigned int host_devfn;
	struct sn_pcidev_match pcidev_match;
	acpi_handle rootbus_handle;
	unsigned long long segment;
	acpi_status status;
	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	rootbus_handle = acpi_device_handle(PCI_CONTROLLER(dev)->companion);
        status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL,
                                       &segment);
        if (ACPI_SUCCESS(status)) {
		if (segment != pci_domain_nr(dev)) {
			acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME,
				&name_buffer);
			printk(KERN_ERR
			       "%s: Segment number mismatch, 0x%llx vs 0x%x for: %s\n",
			       __func__, segment, pci_domain_nr(dev),
			       (char *)name_buffer.pointer);
			kfree(name_buffer.pointer);
			return 1;
		}
	} else {
		acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME, &name_buffer);
		printk(KERN_ERR "%s: Unable to get __SEG from: %s\n",
		       __func__, (char *)name_buffer.pointer);
		kfree(name_buffer.pointer);
		return 1;
	}

	/*
	 * We want to search all devices in this segment/domain
	 * of the ACPI namespace for the matching ACPI device,
	 * which holds the pcidev_info pointer in its vendor resource.
	 */
	pcidev_match.bus = dev->bus->number;
	pcidev_match.devfn = dev->devfn;
	pcidev_match.handle = NULL;

	acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
			    find_matching_device, NULL, &pcidev_match, NULL);

	if (!pcidev_match.handle) {
		printk(KERN_ERR
		       "%s: Could not find matching ACPI device for %s.\n",
		       __func__, pci_name(dev));
		return 1;
	}

	if (sn_extract_device_info(pcidev_match.handle, pcidev_info, sn_irq_info))
		return 1;

	/* Build up the pcidev_info.pdi_slot_host_handle */
	host_devfn = get_host_devfn(pcidev_match.handle, rootbus_handle);
	(*pcidev_info)->pdi_slot_host_handle =
			((unsigned long) pci_domain_nr(dev) << 40) |
					/* bus == 0 */
					host_devfn;
	return 0;
}

/*
 * sn_acpi_slot_fixup - Obtain the pcidev_info and sn_irq_info.
 *			Perform any SN specific slot fixup.
 *			At present there does not appear to be
 *			any generic way to handle a ROM image
 *			that has been shadowed by the PROM, so
 *			we pass a pointer to it	within the
 *			pcidev_info structure.
 */

void
sn_acpi_slot_fixup(struct pci_dev *dev)
{
	struct pcidev_info *pcidev_info = NULL;
	struct sn_irq_info *sn_irq_info = NULL;
	struct resource *res;
	size_t size;

	if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
		panic("%s:  Failure obtaining pcidev_info for %s\n",
		      __func__, pci_name(dev));
	}

	if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
		/*
		 * A valid ROM image exists and has been shadowed by the
		 * PROM. Setup the pci_dev ROM resource with the address
		 * of the shadowed copy, and the actual length of the ROM image.
		 */
		size = pci_resource_len(dev, PCI_ROM_RESOURCE);

		res = &dev->resource[PCI_ROM_RESOURCE];

		pci_disable_rom(dev);
		if (res->parent)
			release_resource(res);

		res->start = pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE];
		res->end = res->start + size - 1;
		res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
			     IORESOURCE_PCI_FIXED;
	}
	sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
}
EXPORT_SYMBOL(sn_acpi_slot_fixup);


/*
 * sn_acpi_bus_fixup -  Perform SN specific setup of software structs
 *			(pcibus_bussoft, pcidev_info) and hardware
 *			registers, for the specified bus and devices under it.
 */
void
sn_acpi_bus_fixup(struct pci_bus *bus)
{
	struct pci_dev *pci_dev = NULL;
	struct pcibus_bussoft *prom_bussoft_ptr;

	if (!bus->parent) {	/* If root bus */
		prom_bussoft_ptr = sn_get_bussoft_ptr(bus);
		if (prom_bussoft_ptr == NULL) {
			printk(KERN_ERR
			       "%s: 0x%04x:0x%02x Unable to "
			       "obtain prom_bussoft_ptr\n",
			       __func__, pci_domain_nr(bus), bus->number);
			return;
		}
		sn_common_bus_fixup(bus, prom_bussoft_ptr);
	}
	list_for_each_entry(pci_dev, &bus->devices, bus_list) {
		sn_acpi_slot_fixup(pci_dev);
	}
}

/*
 * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the
 *		     nodes and root buses in the DSDT. As a result, bus scanning
 *		     will be initiated by the Linux ACPI code.
 */

void __init
sn_io_acpi_init(void)
{
	u64 result;
	long status;

	/* SN Altix does not follow the IOSAPIC IRQ routing model */
	acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;

	/* Setup hubdev_info for all SGIHUB/SGITIO devices */
	acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
	acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);

	status = sal_ioif_init(&result);
	if (status || result)
		panic("sal_ioif_init failed: [%lx] %s\n",
		      status, ia64_sal_strerror(status));
}
