// SPDX-License-Identifier: GPL-2.0-only
/*
 *  PS3 system bus driver.
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/dma-map-ops.h>
#include <linux/err.h>
#include <linux/slab.h>

#include <asm/udbg.h>
#include <asm/lv1call.h>
#include <asm/firmware.h>
#include <asm/cell-regs.h>

#include "platform.h"

static struct device ps3_system_bus = {
	.init_name = "ps3_system",
};

/* FIXME: need device usage counters! */
static struct {
	struct mutex mutex;
	int sb_11; /* usb 0 */
	int sb_12; /* usb 0 */
	int gpu;
} usage_hack;

static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
			 u64 dev_id)
{
	return dev->bus_id == bus_id && dev->dev_id == dev_id;
}

static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
{
	int result;

	BUG_ON(!dev->bus_id);
	mutex_lock(&usage_hack.mutex);

	if (ps3_is_device(dev, 1, 1)) {
		usage_hack.sb_11++;
		if (usage_hack.sb_11 > 1) {
			result = 0;
			goto done;
		}
	}

	if (ps3_is_device(dev, 1, 2)) {
		usage_hack.sb_12++;
		if (usage_hack.sb_12 > 1) {
			result = 0;
			goto done;
		}
	}

	result = lv1_open_device(dev->bus_id, dev->dev_id, 0);

	if (result) {
		pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
			__LINE__, ps3_result(result));
			result = -EPERM;
	}

done:
	mutex_unlock(&usage_hack.mutex);
	return result;
}

static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
{
	int result;

	BUG_ON(!dev->bus_id);
	mutex_lock(&usage_hack.mutex);

	if (ps3_is_device(dev, 1, 1)) {
		usage_hack.sb_11--;
		if (usage_hack.sb_11) {
			result = 0;
			goto done;
		}
	}

	if (ps3_is_device(dev, 1, 2)) {
		usage_hack.sb_12--;
		if (usage_hack.sb_12) {
			result = 0;
			goto done;
		}
	}

	result = lv1_close_device(dev->bus_id, dev->dev_id);
	BUG_ON(result);

done:
	mutex_unlock(&usage_hack.mutex);
	return result;
}

static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
{
	int result;

	mutex_lock(&usage_hack.mutex);

	usage_hack.gpu++;
	if (usage_hack.gpu > 1) {
		result = 0;
		goto done;
	}

	result = lv1_gpu_open(0);

	if (result) {
		pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
			__LINE__, ps3_result(result));
			result = -EPERM;
	}

done:
	mutex_unlock(&usage_hack.mutex);
	return result;
}

static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
{
	int result;

	mutex_lock(&usage_hack.mutex);

	usage_hack.gpu--;
	if (usage_hack.gpu) {
		result = 0;
		goto done;
	}

	result = lv1_gpu_close();
	BUG_ON(result);

done:
	mutex_unlock(&usage_hack.mutex);
	return result;
}

int ps3_open_hv_device(struct ps3_system_bus_device *dev)
{
	BUG_ON(!dev);
	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);

	switch (dev->match_id) {
	case PS3_MATCH_ID_EHCI:
	case PS3_MATCH_ID_OHCI:
	case PS3_MATCH_ID_GELIC:
	case PS3_MATCH_ID_STOR_DISK:
	case PS3_MATCH_ID_STOR_ROM:
	case PS3_MATCH_ID_STOR_FLASH:
		return ps3_open_hv_device_sb(dev);

	case PS3_MATCH_ID_SOUND:
	case PS3_MATCH_ID_GPU:
		return ps3_open_hv_device_gpu(dev);

	case PS3_MATCH_ID_AV_SETTINGS:
	case PS3_MATCH_ID_SYSTEM_MANAGER:
		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
			__LINE__, dev->match_id);
		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
			dev->bus_id);
		BUG();
		return -EINVAL;

	default:
		break;
	}

	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
		dev->match_id);
	BUG();
	return -ENODEV;
}
EXPORT_SYMBOL_GPL(ps3_open_hv_device);

int ps3_close_hv_device(struct ps3_system_bus_device *dev)
{
	BUG_ON(!dev);
	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);

	switch (dev->match_id) {
	case PS3_MATCH_ID_EHCI:
	case PS3_MATCH_ID_OHCI:
	case PS3_MATCH_ID_GELIC:
	case PS3_MATCH_ID_STOR_DISK:
	case PS3_MATCH_ID_STOR_ROM:
	case PS3_MATCH_ID_STOR_FLASH:
		return ps3_close_hv_device_sb(dev);

	case PS3_MATCH_ID_SOUND:
	case PS3_MATCH_ID_GPU:
		return ps3_close_hv_device_gpu(dev);

	case PS3_MATCH_ID_AV_SETTINGS:
	case PS3_MATCH_ID_SYSTEM_MANAGER:
		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
			__LINE__, dev->match_id);
		pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__,
			dev->bus_id);
		BUG();
		return -EINVAL;

	default:
		break;
	}

	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
		dev->match_id);
	BUG();
	return -ENODEV;
}
EXPORT_SYMBOL_GPL(ps3_close_hv_device);

#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
static void _dump_mmio_region(const struct ps3_mmio_region* r,
	const char* func, int line)
{
	pr_debug("%s:%d: dev       %llu:%llu\n", func, line, r->dev->bus_id,
		r->dev->dev_id);
	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
}

static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
{
	int result;
	u64 lpar_addr;

	result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
		r->bus_addr, r->len, r->page_size, &lpar_addr);
	r->lpar_addr = lpar_addr;

	if (result) {
		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		r->lpar_addr = 0;
	}

	dump_mmio_region(r);
	return result;
}

static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
{
	/* device specific; do nothing currently */
	return 0;
}

int ps3_mmio_region_create(struct ps3_mmio_region *r)
{
	return r->mmio_ops->create(r);
}
EXPORT_SYMBOL_GPL(ps3_mmio_region_create);

static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
{
	int result;

	dump_mmio_region(r);
	result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
		r->lpar_addr);

	if (result)
		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	r->lpar_addr = 0;
	return result;
}

static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
{
	/* device specific; do nothing currently */
	return 0;
}


int ps3_free_mmio_region(struct ps3_mmio_region *r)
{
	return r->mmio_ops->free(r);
}

EXPORT_SYMBOL_GPL(ps3_free_mmio_region);

static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
	.create = ps3_sb_mmio_region_create,
	.free = ps3_sb_free_mmio_region
};

static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
	.create = ps3_ioc0_mmio_region_create,
	.free = ps3_ioc0_free_mmio_region
};

int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
	struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
	enum ps3_mmio_page_size page_size)
{
	r->dev = dev;
	r->bus_addr = bus_addr;
	r->len = len;
	r->page_size = page_size;
	switch (dev->dev_type) {
	case PS3_DEVICE_TYPE_SB:
		r->mmio_ops = &ps3_mmio_sb_region_ops;
		break;
	case PS3_DEVICE_TYPE_IOC0:
		r->mmio_ops = &ps3_mmio_ioc0_region_ops;
		break;
	default:
		BUG();
		return -EINVAL;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(ps3_mmio_region_init);

static int ps3_system_bus_match(struct device *_dev,
	struct device_driver *_drv)
{
	int result;
	struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);

	if (!dev->match_sub_id)
		result = dev->match_id == drv->match_id;
	else
		result = dev->match_sub_id == drv->match_sub_id &&
			dev->match_id == drv->match_id;

	if (result)
		pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
			__func__, __LINE__,
			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
			drv->match_id, drv->match_sub_id, drv->core.name);
	else
		pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
			__func__, __LINE__,
			dev->match_id, dev->match_sub_id, dev_name(&dev->core),
			drv->match_id, drv->match_sub_id, drv->core.name);

	return result;
}

static int ps3_system_bus_probe(struct device *_dev)
{
	int result = 0;
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	struct ps3_system_bus_driver *drv;

	BUG_ON(!dev);
	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);

	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
	BUG_ON(!drv);

	if (drv->probe)
		result = drv->probe(dev);
	else
		pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
			dev_name(&dev->core));

	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
	return result;
}

static int ps3_system_bus_remove(struct device *_dev)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	struct ps3_system_bus_driver *drv;

	BUG_ON(!dev);
	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);

	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
	BUG_ON(!drv);

	if (drv->remove)
		drv->remove(dev);
	else
		dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
			__func__, __LINE__, drv->core.name);

	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
	return 0;
}

static void ps3_system_bus_shutdown(struct device *_dev)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	struct ps3_system_bus_driver *drv;

	BUG_ON(!dev);

	dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
		dev->match_id);

	if (!dev->core.driver) {
		dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
			__LINE__);
		return;
	}

	drv = ps3_system_bus_dev_to_system_bus_drv(dev);

	BUG_ON(!drv);

	dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
		dev_name(&dev->core), drv->core.name);

	if (drv->shutdown)
		drv->shutdown(dev);
	else if (drv->remove) {
		dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
			__func__, __LINE__, drv->core.name);
		drv->remove(dev);
	} else {
		dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
			__func__, __LINE__, drv->core.name);
		BUG();
	}

	dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
}

static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);

	if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
			   dev->match_sub_id))
		return -ENOMEM;
	return 0;
}

static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
	char *buf)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
			   dev->match_sub_id);

	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
static DEVICE_ATTR_RO(modalias);

static struct attribute *ps3_system_bus_dev_attrs[] = {
	&dev_attr_modalias.attr,
	NULL,
};
ATTRIBUTE_GROUPS(ps3_system_bus_dev);

struct bus_type ps3_system_bus_type = {
	.name = "ps3_system_bus",
	.match = ps3_system_bus_match,
	.uevent = ps3_system_bus_uevent,
	.probe = ps3_system_bus_probe,
	.remove = ps3_system_bus_remove,
	.shutdown = ps3_system_bus_shutdown,
	.dev_groups = ps3_system_bus_dev_groups,
};

static int __init ps3_system_bus_init(void)
{
	int result;

	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
		return -ENODEV;

	pr_debug(" -> %s:%d\n", __func__, __LINE__);

	mutex_init(&usage_hack.mutex);

	result = device_register(&ps3_system_bus);
	BUG_ON(result);

	result = bus_register(&ps3_system_bus_type);
	BUG_ON(result);

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
	return result;
}

core_initcall(ps3_system_bus_init);

/* Allocates a contiguous real buffer and creates mappings over it.
 * Returns the virtual address of the buffer and sets dma_handle
 * to the dma address (mapping) of the first page.
 */
static void * ps3_alloc_coherent(struct device *_dev, size_t size,
				 dma_addr_t *dma_handle, gfp_t flag,
				 unsigned long attrs)
{
	int result;
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	unsigned long virt_addr;

	flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
	flag |= __GFP_ZERO;

	virt_addr = __get_free_pages(flag, get_order(size));

	if (!virt_addr) {
		pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
		goto clean_none;
	}

	result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
			     CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
			     CBE_IOPTE_SO_RW | CBE_IOPTE_M);

	if (result) {
		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
			__func__, __LINE__, result);
		BUG_ON("check region type");
		goto clean_alloc;
	}

	return (void*)virt_addr;

clean_alloc:
	free_pages(virt_addr, get_order(size));
clean_none:
	dma_handle = NULL;
	return NULL;
}

static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
			      dma_addr_t dma_handle, unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);

	ps3_dma_unmap(dev->d_region, dma_handle, size);
	free_pages((unsigned long)vaddr, get_order(size));
}

/* Creates TCEs for a user provided buffer.  The user buffer must be
 * contiguous real kernel storage (not vmalloc).  The address passed here
 * comprises a page address and offset into that page. The dma_addr_t
 * returned will point to the same byte within the page as was passed in.
 */

static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
	unsigned long offset, size_t size, enum dma_data_direction direction,
	unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	int result;
	dma_addr_t bus_addr;
	void *ptr = page_address(page) + offset;

	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
			     &bus_addr,
			     CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
			     CBE_IOPTE_SO_RW | CBE_IOPTE_M);

	if (result) {
		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
			__func__, __LINE__, result);
	}

	return bus_addr;
}

static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
				    unsigned long offset, size_t size,
				    enum dma_data_direction direction,
				    unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	int result;
	dma_addr_t bus_addr;
	u64 iopte_flag;
	void *ptr = page_address(page) + offset;

	iopte_flag = CBE_IOPTE_M;
	switch (direction) {
	case DMA_BIDIRECTIONAL:
		iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
		break;
	case DMA_TO_DEVICE:
		iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
		break;
	case DMA_FROM_DEVICE:
		iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
		break;
	default:
		/* not happned */
		BUG();
	};
	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
			     &bus_addr, iopte_flag);

	if (result) {
		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
			__func__, __LINE__, result);
	}
	return bus_addr;
}

static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
	size_t size, enum dma_data_direction direction, unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	int result;

	result = ps3_dma_unmap(dev->d_region, dma_addr, size);

	if (result) {
		pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
			__func__, __LINE__, result);
	}
}

static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
	int nents, enum dma_data_direction direction, unsigned long attrs)
{
#if defined(CONFIG_PS3_DYNAMIC_DMA)
	BUG_ON("do");
	return -EPERM;
#else
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	struct scatterlist *sg;
	int i;

	for_each_sg(sgl, sg, nents, i) {
		int result = ps3_dma_map(dev->d_region, sg_phys(sg),
					sg->length, &sg->dma_address, 0);

		if (result) {
			pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
				__func__, __LINE__, result);
			return -EINVAL;
		}

		sg->dma_length = sg->length;
	}

	return nents;
#endif
}

static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
			   int nents,
			   enum dma_data_direction direction,
			   unsigned long attrs)
{
	BUG();
	return 0;
}

static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
	int nents, enum dma_data_direction direction, unsigned long attrs)
{
#if defined(CONFIG_PS3_DYNAMIC_DMA)
	BUG_ON("do");
#endif
}

static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
			    int nents, enum dma_data_direction direction,
			    unsigned long attrs)
{
	BUG();
}

static int ps3_dma_supported(struct device *_dev, u64 mask)
{
	return mask >= DMA_BIT_MASK(32);
}

static const struct dma_map_ops ps3_sb_dma_ops = {
	.alloc = ps3_alloc_coherent,
	.free = ps3_free_coherent,
	.map_sg = ps3_sb_map_sg,
	.unmap_sg = ps3_sb_unmap_sg,
	.dma_supported = ps3_dma_supported,
	.map_page = ps3_sb_map_page,
	.unmap_page = ps3_unmap_page,
	.mmap = dma_common_mmap,
	.get_sgtable = dma_common_get_sgtable,
	.alloc_pages = dma_common_alloc_pages,
	.free_pages = dma_common_free_pages,
};

static const struct dma_map_ops ps3_ioc0_dma_ops = {
	.alloc = ps3_alloc_coherent,
	.free = ps3_free_coherent,
	.map_sg = ps3_ioc0_map_sg,
	.unmap_sg = ps3_ioc0_unmap_sg,
	.dma_supported = ps3_dma_supported,
	.map_page = ps3_ioc0_map_page,
	.unmap_page = ps3_unmap_page,
	.mmap = dma_common_mmap,
	.get_sgtable = dma_common_get_sgtable,
	.alloc_pages = dma_common_alloc_pages,
	.free_pages = dma_common_free_pages,
};

/**
 * ps3_system_bus_release_device - remove a device from the system bus
 */

static void ps3_system_bus_release_device(struct device *_dev)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	kfree(dev);
}

/**
 * ps3_system_bus_device_register - add a device to the system bus
 *
 * ps3_system_bus_device_register() expects the dev object to be allocated
 * dynamically by the caller.  The system bus takes ownership of the dev
 * object and frees the object in ps3_system_bus_release_device().
 */

int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
{
	int result;
	static unsigned int dev_ioc0_count;
	static unsigned int dev_sb_count;
	static unsigned int dev_vuart_count;
	static unsigned int dev_lpm_count;

	if (!dev->core.parent)
		dev->core.parent = &ps3_system_bus;
	dev->core.bus = &ps3_system_bus_type;
	dev->core.release = ps3_system_bus_release_device;

	switch (dev->dev_type) {
	case PS3_DEVICE_TYPE_IOC0:
		dev->core.dma_ops = &ps3_ioc0_dma_ops;
		dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
		break;
	case PS3_DEVICE_TYPE_SB:
		dev->core.dma_ops = &ps3_sb_dma_ops;
		dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);

		break;
	case PS3_DEVICE_TYPE_VUART:
		dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
		break;
	case PS3_DEVICE_TYPE_LPM:
		dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
		break;
	default:
		BUG();
	};

	dev->core.of_node = NULL;
	set_dev_node(&dev->core, 0);

	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));

	result = device_register(&dev->core);
	return result;
}

EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);

int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
{
	int result;

	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);

	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
		return -ENODEV;

	drv->core.bus = &ps3_system_bus_type;

	result = driver_register(&drv->core);
	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
	return result;
}

EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);

void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
{
	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
	driver_unregister(&drv->core);
	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
}

EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
