/*
 * 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) 2005-2006 Silicon Graphics, Inc. All rights reserved.
 *
 * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
 * Work to add BIOS PROM support was completed by Mike Habeck.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/proc_fs.h>
#include <linux/types.h>
#include <linux/mutex.h>

#include <asm/sn/addrs.h>
#include <asm/sn/geo.h>
#include <asm/sn/l1.h>
#include <asm/sn/module.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/sn_feature_sets.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/types.h>
#include <linux/acpi.h>
#include <asm/sn/acpi.h>

#include "../pci.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");


/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */
#define PCI_SLOT_ALREADY_UP		2	/* slot already up */
#define PCI_SLOT_ALREADY_DOWN		3	/* slot already down */
#define PCI_L1_ERR			7	/* L1 console command error */
#define PCI_EMPTY_33MHZ			15	/* empty 33 MHz bus */


#define PCIIO_ASIC_TYPE_TIOCA		4
#define PCI_L1_QSIZE			128	/* our L1 message buffer size */
#define SN_MAX_HP_SLOTS			32	/* max hotplug slots */
#define SN_SLOT_NAME_SIZE		33	/* size of name string */

/* internal list head */
static struct list_head sn_hp_list;

/* hotplug_slot struct's private pointer */
struct slot {
	int device_num;
	struct pci_bus *pci_bus;
	/* this struct for glue internal only */
	struct hotplug_slot *hotplug_slot;
	struct list_head hp_list;
	char physical_path[SN_SLOT_NAME_SIZE];
};

struct pcibr_slot_enable_resp {
	int resp_sub_errno;
	char resp_l1_msg[PCI_L1_QSIZE + 1];
};

struct pcibr_slot_disable_resp {
	int resp_sub_errno;
	char resp_l1_msg[PCI_L1_QSIZE + 1];
};

enum sn_pci_req_e {
	PCI_REQ_SLOT_ELIGIBLE,
	PCI_REQ_SLOT_DISABLE
};

static int enable_slot(struct hotplug_slot *slot);
static int disable_slot(struct hotplug_slot *slot);
static inline int get_power_status(struct hotplug_slot *slot, u8 *value);

static struct hotplug_slot_ops sn_hotplug_slot_ops = {
	.owner                  = THIS_MODULE,
	.enable_slot            = enable_slot,
	.disable_slot           = disable_slot,
	.get_power_status       = get_power_status,
};

static DEFINE_MUTEX(sn_hotplug_mutex);

static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot,
	       		  char *buf)
{
	int retval = -ENOENT;
	struct slot *slot = bss_hotplug_slot->private;

	if (!slot)
		return retval;

	retval = sprintf (buf, "%s\n", slot->physical_path);
	return retval;
}

static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);

static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
{
	struct pcibus_info *pcibus_info;
	u16 busnum, segment, ioboard_type;

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);

	/* Check to see if this is a valid slot on 'pci_bus' */
	if (!(pcibus_info->pbi_valid_devices & (1 << device)))
		return -EPERM;

	ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
	busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
	segment = pci_domain_nr(pci_bus) & 0xf;

	/* Do not allow hotplug operations on base I/O cards */
	if ((ioboard_type == L1_BRICKTYPE_IX ||
	     ioboard_type == L1_BRICKTYPE_IA) &&
	    (segment == 1 && busnum == 0 && device != 1))
		return -EPERM;

	return 1;
}

static int sn_pci_bus_valid(struct pci_bus *pci_bus)
{
	struct pcibus_info *pcibus_info;
	u32 asic_type;
	u16 ioboard_type;

	/* Don't register slots hanging off the TIOCA bus */
	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
	asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
	if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
		return -EPERM;

	/* Only register slots in I/O Bricks that support hotplug */
	ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
	switch (ioboard_type) {
		case L1_BRICKTYPE_IX:
		case L1_BRICKTYPE_PX:
		case L1_BRICKTYPE_IA:
		case L1_BRICKTYPE_PA:
		case L1_BOARDTYPE_PCIX3SLOT:
			return 1;
			break;
		default:
			return -EPERM;
			break;
	}

	return -EIO;
}

static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
				    struct pci_bus *pci_bus, int device)
{
	struct pcibus_info *pcibus_info;
	struct slot *slot;

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);

	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
	if (!slot)
		return -ENOMEM;
	bss_hotplug_slot->private = slot;

	bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
	if (!bss_hotplug_slot->name) {
		kfree(bss_hotplug_slot->private);
		return -ENOMEM;
	}

	slot->device_num = device;
	slot->pci_bus = pci_bus;
	sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
		pci_domain_nr(pci_bus),
		((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
		device + 1);

	sn_generate_path(pci_bus, slot->physical_path);

	slot->hotplug_slot = bss_hotplug_slot;
	list_add(&slot->hp_list, &sn_hp_list);

	return 0;
}

static struct hotplug_slot * sn_hp_destroy(void)
{
	struct slot *slot;
	struct hotplug_slot *bss_hotplug_slot = NULL;

	list_for_each_entry(slot, &sn_hp_list, hp_list) {
		bss_hotplug_slot = slot->hotplug_slot;
		list_del(&((struct slot *)bss_hotplug_slot->private)->
			 hp_list);
		sysfs_remove_file(&bss_hotplug_slot->kobj,
				  &sn_slot_path_attr.attr);
		break;
	}
	return bss_hotplug_slot;
}

static void sn_bus_free_data(struct pci_dev *dev)
{
	struct pci_bus *subordinate_bus;
	struct pci_dev *child;

	/* Recursively clean up sn_irq_info structs */
	if (dev->subordinate) {
		subordinate_bus = dev->subordinate;
		list_for_each_entry(child, &subordinate_bus->devices, bus_list)
			sn_bus_free_data(child);
	}
	/*
	 * Some drivers may use dma accesses during the
	 * driver remove function. We release the sysdata
	 * areas after the driver remove functions have
	 * been called.
	 */
	sn_bus_store_sysdata(dev);
	sn_pci_unfixup_slot(dev);
}

static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
			  int device_num, char **ssdt)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pcibus_info *pcibus_info;
	struct pcibr_slot_enable_resp resp;
	int rc;

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);

	/*
	 * Power-on and initialize the slot in the SN
	 * PCI infrastructure.
	 */
	rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt);


	if (rc == PCI_SLOT_ALREADY_UP) {
		dev_dbg(&slot->pci_bus->self->dev, "is already active\n");
		return 1; /* return 1 to user */
	}

	if (rc == PCI_L1_ERR) {
		dev_dbg(&slot->pci_bus->self->dev,
			"L1 failure %d with message: %s",
			resp.resp_sub_errno, resp.resp_l1_msg);
		return -EPERM;
	}

	if (rc) {
		dev_dbg(&slot->pci_bus->self->dev,
			"insert failed with error %d sub-error %d\n",
			rc, resp.resp_sub_errno);
		return -EIO;
	}

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
	pcibus_info->pbi_enabled_devices |= (1 << device_num);

	return 0;
}

static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
			   int device_num, int action)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pcibus_info *pcibus_info;
	struct pcibr_slot_disable_resp resp;
	int rc;

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);

	rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);

	if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
	    (rc == PCI_SLOT_ALREADY_DOWN)) {
		dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path);
		return 1; /* return 1 to user */
	}

	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
		dev_dbg(&slot->pci_bus->self->dev,
			"Cannot remove last 33MHz card\n");
		return -EPERM;
	}

	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
		dev_dbg(&slot->pci_bus->self->dev,
			"L1 failure %d with message \n%s\n",
			resp.resp_sub_errno, resp.resp_l1_msg);
		return -EPERM;
	}

	if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
		dev_dbg(&slot->pci_bus->self->dev,
			"remove failed with error %d sub-error %d\n",
			rc, resp.resp_sub_errno);
		return -EIO;
	}

	if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
		return 0;

	if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
		pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
		pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
		dev_dbg(&slot->pci_bus->self->dev, "remove successful\n");
		return 0;
	}

	if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
		dev_dbg(&slot->pci_bus->self->dev,"remove failed rc = %d\n", rc);
	}

	return rc;
}

/*
 * Power up and configure the slot via a SAL call to PROM.
 * Scan slot (and any children), do any platform specific fixup,
 * and find device driver.
 */
static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pci_bus *new_bus = NULL;
	struct pci_dev *dev;
	int func, num_funcs;
	int new_ppb = 0;
	int rc;
	char *ssdt = NULL;
	void pcibios_fixup_device_resources(struct pci_dev *);

	/* Serialize the Linux PCI infrastructure */
	mutex_lock(&sn_hotplug_mutex);

	/*
	 * Power-on and initialize the slot in the SN
	 * PCI infrastructure. Also, retrieve the ACPI SSDT
	 * table for the slot (if ACPI capable PROM).
	 */
	rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt);
	if (rc) {
		mutex_unlock(&sn_hotplug_mutex);
		return rc;
	}

	if (ssdt)
		ssdt = __va(ssdt);
	/* Add the new SSDT for the slot to the ACPI namespace */
	if (SN_ACPI_BASE_SUPPORT() && ssdt) {
		acpi_status ret;

		ret = acpi_load_table((struct acpi_table_header *)ssdt);
		if (ACPI_FAILURE(ret)) {
			printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n",
			       __func__, ret);
			/* try to continue on */
		}
	}

	num_funcs = pci_scan_slot(slot->pci_bus,
				  PCI_DEVFN(slot->device_num + 1, 0));
	if (!num_funcs) {
		dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n");
		mutex_unlock(&sn_hotplug_mutex);
		return -ENODEV;
	}

	/*
	 * Map SN resources for all functions on the card
	 * to the Linux PCI interface and tell the drivers
	 * about them.
	 */
	for (func = 0; func < num_funcs;  func++) {
		dev = pci_get_slot(slot->pci_bus,
				   PCI_DEVFN(slot->device_num + 1,
					     PCI_FUNC(func)));
		if (dev) {
			/* Need to do slot fixup on PPB before fixup of children
			 * (PPB's pcidev_info needs to be in pcidev_info list
			 * before child's SN_PCIDEV_INFO() call to setup
			 * pdi_host_pcidev_info).
			 */
			pcibios_fixup_device_resources(dev);
			if (SN_ACPI_BASE_SUPPORT())
				sn_acpi_slot_fixup(dev);
			else
				sn_io_slot_fixup(dev);
			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
				unsigned char sec_bus;
				pci_read_config_byte(dev, PCI_SECONDARY_BUS,
						     &sec_bus);
				new_bus = pci_add_new_bus(dev->bus, dev,
							  sec_bus);
				pci_scan_child_bus(new_bus);
				new_ppb = 1;
			}
			pci_dev_put(dev);
		}
	}

	/*
	 * Add the slot's devices to the ACPI infrastructure */
	if (SN_ACPI_BASE_SUPPORT() && ssdt) {
		unsigned long adr;
		struct acpi_device *pdevice;
		struct acpi_device *device;
		acpi_handle phandle;
		acpi_handle chandle = NULL;
		acpi_handle rethandle;
		acpi_status ret;

		phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;

		if (acpi_bus_get_device(phandle, &pdevice)) {
			dev_dbg(&slot->pci_bus->self->dev,
				"no parent device, assuming NULL\n");
			pdevice = NULL;
		}

		/*
		 * Walk the rootbus node's immediate children looking for
		 * the slot's device node(s). There can be more than
		 * one for multifunction devices.
		 */
		for (;;) {
			rethandle = NULL;
			ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
						   phandle, chandle,
						   &rethandle);

			if (ret == AE_NOT_FOUND || rethandle == NULL)
				break;

			chandle = rethandle;

			ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR,
						    NULL, &adr);

			if (ACPI_SUCCESS(ret) &&
			    (adr>>16) == (slot->device_num + 1)) {

				ret = acpi_bus_add(&device, pdevice, chandle,
						   ACPI_BUS_TYPE_DEVICE);
				if (ACPI_FAILURE(ret)) {
					printk(KERN_ERR "%s: acpi_bus_add "
					       "failed (0x%x) for slot %d "
					       "func %d\n", __func__,
					       ret, (int)(adr>>16),
					       (int)(adr&0xffff));
					/* try to continue on */
				} else {
					acpi_bus_start(device);
				}
			}
		}
	}

	/* Call the driver for the new device */
	pci_bus_add_devices(slot->pci_bus);
	/* Call the drivers for the new devices subordinate to PPB */
	if (new_ppb)
		pci_bus_add_devices(new_bus);

	mutex_unlock(&sn_hotplug_mutex);

	if (rc == 0)
		dev_dbg(&slot->pci_bus->self->dev,
			"insert operation successful\n");
	else
		dev_dbg(&slot->pci_bus->self->dev,
			"insert operation failed rc = %d\n", rc);

	return rc;
}

static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pci_dev *dev;
	int func;
	int rc;
	acpi_owner_id ssdt_id = 0;

	/* Acquire update access to the bus */
	mutex_lock(&sn_hotplug_mutex);

	/* is it okay to bring this slot down? */
	rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
			     PCI_REQ_SLOT_ELIGIBLE);
	if (rc)
		goto leaving;

	/* free the ACPI resources for the slot */
	if (SN_ACPI_BASE_SUPPORT() &&
            PCI_CONTROLLER(slot->pci_bus)->acpi_handle) {
		unsigned long adr;
		struct acpi_device *device;
		acpi_handle phandle;
		acpi_handle chandle = NULL;
		acpi_handle rethandle;
		acpi_status ret;

		/* Get the rootbus node pointer */
		phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;

		/*
		 * Walk the rootbus node's immediate children looking for
		 * the slot's device node(s). There can be more than
		 * one for multifunction devices.
		 */
		for (;;) {
			rethandle = NULL;
			ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
						   phandle, chandle,
						   &rethandle);

			if (ret == AE_NOT_FOUND || rethandle == NULL)
				break;

			chandle = rethandle;

			ret = acpi_evaluate_integer(chandle,
						    METHOD_NAME__ADR,
						    NULL, &adr);
			if (ACPI_SUCCESS(ret) &&
			    (adr>>16) == (slot->device_num + 1)) {
				/* retain the owner id */
				acpi_get_id(chandle, &ssdt_id);

				ret = acpi_bus_get_device(chandle,
							  &device);
				if (ACPI_SUCCESS(ret))
					acpi_bus_trim(device, 1);
			}
		}

	}

	/* Free the SN resources assigned to the Linux device.*/
	for (func = 0; func < 8;  func++) {
		dev = pci_get_slot(slot->pci_bus,
				   PCI_DEVFN(slot->device_num + 1,
				   	     PCI_FUNC(func)));
		if (dev) {
			sn_bus_free_data(dev);
			pci_remove_bus_device(dev);
			pci_dev_put(dev);
		}
	}

	/* Remove the SSDT for the slot from the ACPI namespace */
	if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {
		acpi_status ret;
		ret = acpi_unload_table_id(ssdt_id);
		if (ACPI_FAILURE(ret)) {
			printk(KERN_ERR "%s: acpi_unload_table_id "
			       "failed (0x%x) for id %d\n",
			       __func__, ret, ssdt_id);
			/* try to continue on */
		}
	}

	/* free the collected sysdata pointers */
	sn_bus_free_sysdata();

	/* Deactivate slot */
	rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
			     PCI_REQ_SLOT_DISABLE);
 leaving:
	/* Release the bus lock */
	mutex_unlock(&sn_hotplug_mutex);

	return rc;
}

static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
				   u8 *value)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pcibus_info *pcibus_info;
	u32 power;

	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
	mutex_lock(&sn_hotplug_mutex);
	power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
	*value = power ? 1 : 0;
	mutex_unlock(&sn_hotplug_mutex);
	return 0;
}

static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
{
	kfree(bss_hotplug_slot->info);
	kfree(bss_hotplug_slot->name);
	kfree(bss_hotplug_slot->private);
	kfree(bss_hotplug_slot);
}

static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
{
	int device;
	struct hotplug_slot *bss_hotplug_slot;
	int rc = 0;

	/*
	 * Currently only four devices are supported,
	 * in the future there maybe more -- up to 32.
	 */

	for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
		if (sn_pci_slot_valid(pci_bus, device) != 1)
			continue;

		bss_hotplug_slot = kzalloc(sizeof(*bss_hotplug_slot),
					   GFP_KERNEL);
		if (!bss_hotplug_slot) {
			rc = -ENOMEM;
			goto alloc_err;
		}

		bss_hotplug_slot->info =
			kzalloc(sizeof(struct hotplug_slot_info),
				GFP_KERNEL);
		if (!bss_hotplug_slot->info) {
			rc = -ENOMEM;
			goto alloc_err;
		}

		if (sn_hp_slot_private_alloc(bss_hotplug_slot,
					     pci_bus, device)) {
			rc = -ENOMEM;
			goto alloc_err;
		}

		bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
		bss_hotplug_slot->release = &sn_release_slot;

		rc = pci_hp_register(bss_hotplug_slot);
		if (rc)
			goto register_err;

		rc = sysfs_create_file(&bss_hotplug_slot->kobj,
				       &sn_slot_path_attr.attr);
		if (rc)
			goto register_err;
	}
	dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n");
	return rc;

register_err:
	dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n",
	        rc);

alloc_err:
	if (rc == -ENOMEM)
		dev_dbg(&pci_bus->self->dev, "Memory allocation error\n");

	/* destroy THIS element */
	if (bss_hotplug_slot)
		sn_release_slot(bss_hotplug_slot);

	/* destroy anything else on the list */
	while ((bss_hotplug_slot = sn_hp_destroy()))
		pci_hp_deregister(bss_hotplug_slot);

	return rc;
}

static int sn_pci_hotplug_init(void)
{
	struct pci_bus *pci_bus = NULL;
	int rc;
	int registered = 0;

	if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
		printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
		       __func__);
		return -EPERM;
	}

	INIT_LIST_HEAD(&sn_hp_list);

	while ((pci_bus = pci_find_next_bus(pci_bus))) {
		if (!pci_bus->sysdata)
			continue;

		rc = sn_pci_bus_valid(pci_bus);
		if (rc != 1) {
			dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n");
			continue;
		}
		dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n");

		rc = sn_hotplug_slot_register(pci_bus);
		if (!rc) {
			registered = 1;
		} else {
			registered = 0;
			break;
		}
	}

	return registered == 1 ? 0 : -ENODEV;
}

static void sn_pci_hotplug_exit(void)
{
	struct hotplug_slot *bss_hotplug_slot;

	while ((bss_hotplug_slot = sn_hp_destroy()))
		pci_hp_deregister(bss_hotplug_slot);

	if (!list_empty(&sn_hp_list))
		printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
}

module_init(sn_pci_hotplug_init);
module_exit(sn_pci_hotplug_exit);
