// SPDX-License-Identifier: GPL-2.0
/* Code to support devices on the DIO and DIO-II bus
 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
 * Copyright (C) 2004 Jochen Friedrich <jochen@scram.de>
 *
 * This code has basically these routines at the moment:
 * int dio_find(u_int deviceid)
 *    Search the list of DIO devices and return the select code
 *    of the next unconfigured device found that matches the given device ID.
 *    Note that the deviceid parameter should be the encoded ID.
 *    This means that framebuffers should pass it as
 *    DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOPCAT)
 *    (or whatever); everybody else just uses DIO_ID_FOOBAR.
 * unsigned long dio_scodetophysaddr(int scode)
 *    Return the physical address corresponding to the given select code.
 * int dio_scodetoipl(int scode)
 *    Every DIO card has a fixed interrupt priority level. This function
 *    returns it, whatever it is.
 * const char *dio_scodetoname(int scode)
 *    Return a character string describing this board [might be "" if
 *    not CONFIG_DIO_CONSTANTS]
 * void dio_config_board(int scode)     mark board as configured in the list
 * void dio_unconfig_board(int scode)   mark board as no longer configured
 *
 * This file is based on the way the Amiga port handles Zorro II cards,
 * although we aren't so complicated...
 */
#include <linux/module.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dio.h>
#include <linux/slab.h>                         /* kmalloc() */
#include <linux/uaccess.h>
#include <linux/io.h>                           /* readb() */

struct dio_bus dio_bus = {
	.resources = {
		/* DIO range */
		{ .name = "DIO mem", .start = 0x00600000, .end = 0x007fffff },
		/* DIO-II range */
		{ .name = "DIO-II mem", .start = 0x01000000, .end = 0x1fffffff }
	},
	.name = "DIO bus"
};

/* not a real config option yet! */
#define CONFIG_DIO_CONSTANTS

#ifdef CONFIG_DIO_CONSTANTS
/* We associate each numeric ID with an appropriate descriptive string
 * using a constant array of these structs.
 * FIXME: we should be able to arrange to throw away most of the strings
 * using the initdata stuff. Then we wouldn't need to worry about
 * carrying them around...
 * I think we do this by copying them into newly kmalloc()ed memory and
 * marking the names[] array as .initdata ?
 */
struct dioname {
	int id;
	const char *name;
};

/* useful macro */
#define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
#define DIOFBNAME(x) { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }

static struct dioname names[] = {
	DIONAME(DCA0), DIONAME(DCA0REM), DIONAME(DCA1), DIONAME(DCA1REM),
	DIONAME(DCM), DIONAME(DCMREM),
	DIONAME(LAN),
	DIONAME(FHPIB), DIONAME(NHPIB),
	DIONAME(SCSI0), DIONAME(SCSI1), DIONAME(SCSI2), DIONAME(SCSI3),
	DIONAME(FBUFFER),
	DIONAME(PARALLEL), DIONAME(VME), DIONAME(DCL), DIONAME(DCLREM),
	DIONAME(MISC0), DIONAME(MISC1), DIONAME(MISC2), DIONAME(MISC3),
	DIONAME(MISC4), DIONAME(MISC5), DIONAME(MISC6), DIONAME(MISC7),
	DIONAME(MISC8), DIONAME(MISC9), DIONAME(MISC10), DIONAME(MISC11),
	DIONAME(MISC12), DIONAME(MISC13),
	DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT), DIOFBNAME(RENAISSANCE),
	DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCATSEYE), DIOFBNAME(HRMCATSEYE),
	DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSEYE), DIOFBNAME(HYPERION),
	DIOFBNAME(XGENESIS), DIOFBNAME(TIGER), DIOFBNAME(YGENESIS)
};

#undef DIONAME
#undef DIOFBNAME

static const char unknowndioname[]
	= "unknown DIO board, please email linux-m68k@lists.linux-m68k.org";

static const char *dio_getname(int id)
{
	/* return pointer to a constant string describing the board with given ID */
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(names); i++)
		if (names[i].id == id)
			return names[i].name;

	return unknowndioname;
}

#else

static char dio_no_name[] = { 0 };
#define dio_getname(_id)	(dio_no_name)

#endif /* CONFIG_DIO_CONSTANTS */

static void dio_dev_release(struct device *dev)
{
	struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev);
	kfree(ddev);
}

int __init dio_find(int deviceid)
{
	/* Called to find a DIO device before the full bus scan has run.
	 * Only used by the console driver.
	 */
	int scode, id;
	u_char prid, secid, i;

	for (scode = 0; scode < DIO_SCMAX; scode++) {
		void *va;
		unsigned long pa;

		if (DIO_SCINHOLE(scode))
			continue;

		pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		if (copy_from_kernel_nofault(&i,
				(unsigned char *)va + DIO_IDOFF, 1)) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			continue;	     /* no board present at that select code */
		}

		prid = DIO_ID(va);

		if (DIO_NEEDSSECID(prid)) {
			secid = DIO_SECID(va);
			id = DIO_ENCODE_ID(prid, secid);
		} else
			id = prid;

		if (id == deviceid) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			return scode;
		}
	}

	return -1;
}

/* This is the function that scans the DIO space and works out what
 * hardware is actually present.
 */
static int __init dio_init(void)
{
	int scode;
	int i;
	struct dio_dev *dev;
	int error;

	if (!MACH_IS_HP300)
		return 0;

	pr_info("Scanning for DIO devices...\n");

	/* Initialize the DIO bus */
	INIT_LIST_HEAD(&dio_bus.devices);
	dev_set_name(&dio_bus.dev, "dio");
	error = device_register(&dio_bus.dev);
	if (error) {
		pr_err("DIO: Error registering dio_bus\n");
		return error;
	}

	/* Request all resources */
	dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
	for (i = 0; i < dio_bus.num_resources; i++)
		request_resource(&iomem_resource, &dio_bus.resources[i]);

	/* Register all devices */
	for (scode = 0; scode < DIO_SCMAX; ++scode) {
		u_char prid, secid = 0;	/* primary, secondary ID bytes */
		u_char *va;
		unsigned long pa;

		if (DIO_SCINHOLE(scode))
			continue;

		pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		if (copy_from_kernel_nofault(&i,
				(unsigned char *)va + DIO_IDOFF, 1)) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			continue;	      /* no board present at that select code */
		}

		/* Found a board, allocate it an entry in the list */
		dev = kzalloc_obj(struct dio_dev);
		if (!dev) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			return -ENOMEM;
		}

		dev->bus = &dio_bus;
		dev->dev.parent = &dio_bus.dev;
		dev->dev.bus = &dio_bus_type;
		dev->dev.release = dio_dev_release;
		dev->scode = scode;
		dev->resource.start = pa;
		dev->resource.end = pa + DIO_SIZE(scode, va);
		dev_set_name(&dev->dev, "%02x", scode);

		/* read the ID byte(s) and encode if necessary. */
		prid = DIO_ID(va);

		if (DIO_NEEDSSECID(prid)) {
			secid = DIO_SECID(va);
			dev->id = DIO_ENCODE_ID(prid, secid);
		} else
			dev->id = prid;

		dev->ipl = DIO_IPL(va);
		strscpy(dev->name, dio_getname(dev->id));
		if (DIO_NEEDSSECID(prid))
			pr_info("select code %3d: ipl %u: ID %02X:%02X: %s\n",
				dev->scode, dev->ipl, prid, secid, dev->name);
		else
			pr_info("select code %3d: ipl %u: ID %02X: %s\n",
				dev->scode, dev->ipl, prid, dev->name);

		if (scode >= DIOII_SCBASE)
			iounmap(va);
		error = device_register(&dev->dev);
		if (error) {
			pr_err("DIO: Error registering device %s\n", dev->name);
			put_device(&dev->dev);
			continue;
		}
		error = dio_create_sysfs_dev_files(dev);
		if (error)
			dev_err(&dev->dev, "Error creating sysfs files\n");
	}
	return 0;
}

subsys_initcall(dio_init);

/* Bear in mind that this is called in the very early stages of initialisation
 * in order to get the address of the serial port for the console...
 */
unsigned long dio_scodetophysaddr(int scode)
{
	if (scode >= DIOII_SCBASE)
		return (DIOII_BASE + (scode - 132) * DIOII_DEVSIZE);
	else if (scode > DIO_SCMAX || scode < 0)
		return 0;
	else if (DIO_SCINHOLE(scode))
		return 0;

	return (DIO_BASE + scode * DIO_DEVSIZE);
}
