/* SPDX-License-Identifier: GPL-2.0 */
/* parport.h: sparc64 specific parport initialization and dma.
 *
 * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
 */

#ifndef _ASM_SPARC64_PARPORT_H
#define _ASM_SPARC64_PARPORT_H 1

#include <linux/of_device.h>

#include <asm/ebus_dma.h>
#include <asm/ns87303.h>
#include <asm/prom.h>

#define PARPORT_PC_MAX_PORTS	PARPORT_MAX

/*
 * While sparc64 doesn't have an ISA DMA API, we provide something that looks
 * close enough to make parport_pc happy
 */
#define HAS_DMA

#ifdef CONFIG_PARPORT_PC_FIFO
static DEFINE_SPINLOCK(dma_spin_lock);

#define claim_dma_lock() \
({	unsigned long flags; \
	spin_lock_irqsave(&dma_spin_lock, flags); \
	flags; \
})

#define release_dma_lock(__flags) \
	spin_unlock_irqrestore(&dma_spin_lock, __flags);
#endif

static struct sparc_ebus_info {
	struct ebus_dma_info info;
	unsigned int addr;
	unsigned int count;
	int lock;

	struct parport *port;
} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];

static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);

static inline int request_dma(unsigned int dmanr, const char *device_id)
{
	if (dmanr >= PARPORT_PC_MAX_PORTS)
		return -EINVAL;
	if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
		return -EBUSY;
	return 0;
}

static inline void free_dma(unsigned int dmanr)
{
	if (dmanr >= PARPORT_PC_MAX_PORTS) {
		printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
		return;
	}
	if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
		printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
		return;
	}
}

static inline void enable_dma(unsigned int dmanr)
{
	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);

	if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
			     sparc_ebus_dmas[dmanr].addr,
			     sparc_ebus_dmas[dmanr].count))
		BUG();
}

static inline void disable_dma(unsigned int dmanr)
{
	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
}

static inline void clear_dma_ff(unsigned int dmanr)
{
	/* nothing */
}

static inline void set_dma_mode(unsigned int dmanr, char mode)
{
	ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
}

static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
{
	sparc_ebus_dmas[dmanr].addr = addr;
}

static inline void set_dma_count(unsigned int dmanr, unsigned int count)
{
	sparc_ebus_dmas[dmanr].count = count;
}

static inline unsigned int get_dma_residue(unsigned int dmanr)
{
	return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
}

static int ecpp_probe(struct platform_device *op)
{
	unsigned long base = op->resource[0].start;
	unsigned long config = op->resource[1].start;
	unsigned long d_base = op->resource[2].start;
	unsigned long d_len;
	struct device_node *parent;
	struct parport *p;
	int slot, err;

	parent = op->dev.of_node->parent;
	if (!strcmp(parent->name, "dma")) {
		p = parport_pc_probe_port(base, base + 0x400,
					  op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
					  op->dev.parent->parent, 0);
		if (!p)
			return -ENOMEM;
		dev_set_drvdata(&op->dev, p);
		return 0;
	}

	for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
		if (!test_and_set_bit(slot, dma_slot_map))
			break;
	}
	err = -ENODEV;
	if (slot >= PARPORT_PC_MAX_PORTS)
		goto out_err;

	spin_lock_init(&sparc_ebus_dmas[slot].info.lock);

	d_len = (op->resource[2].end - d_base) + 1UL;
	sparc_ebus_dmas[slot].info.regs =
		of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");

	if (!sparc_ebus_dmas[slot].info.regs)
		goto out_clear_map;

	sparc_ebus_dmas[slot].info.flags = 0;
	sparc_ebus_dmas[slot].info.callback = NULL;
	sparc_ebus_dmas[slot].info.client_cookie = NULL;
	sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
	strcpy(sparc_ebus_dmas[slot].info.name, "parport");
	if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
		goto out_unmap_regs;

	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);

	/* Configure IRQ to Push Pull, Level Low */
	/* Enable ECP, set bit 2 of the CTR first */
	outb(0x04, base + 0x02);
	ns87303_modify(config, PCR,
		       PCR_EPP_ENABLE |
		       PCR_IRQ_ODRAIN,
		       PCR_ECP_ENABLE |
		       PCR_ECP_CLK_ENA |
		       PCR_IRQ_POLAR);

	/* CTR bit 5 controls direction of port */
	ns87303_modify(config, PTR,
		       0, PTR_LPT_REG_DIR);

	p = parport_pc_probe_port(base, base + 0x400,
				  op->archdata.irqs[0],
				  slot,
				  op->dev.parent,
				  0);
	err = -ENOMEM;
	if (!p)
		goto out_disable_irq;

	dev_set_drvdata(&op->dev, p);

	return 0;

out_disable_irq:
	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
	ebus_dma_unregister(&sparc_ebus_dmas[slot].info);

out_unmap_regs:
	of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);

out_clear_map:
	clear_bit(slot, dma_slot_map);

out_err:
	return err;
}

static int ecpp_remove(struct platform_device *op)
{
	struct parport *p = dev_get_drvdata(&op->dev);
	int slot = p->dma;

	parport_pc_unregister_port(p);

	if (slot != PARPORT_DMA_NOFIFO) {
		unsigned long d_base = op->resource[2].start;
		unsigned long d_len;

		d_len = (op->resource[2].end - d_base) + 1UL;

		ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
		ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
		of_iounmap(&op->resource[2],
			   sparc_ebus_dmas[slot].info.regs,
			   d_len);
		clear_bit(slot, dma_slot_map);
	}

	return 0;
}

static const struct of_device_id ecpp_match[] = {
	{
		.name = "ecpp",
	},
	{
		.name = "parallel",
		.compatible = "ecpp",
	},
	{
		.name = "parallel",
		.compatible = "ns87317-ecpp",
	},
	{
		.name = "parallel",
		.compatible = "pnpALI,1533,3",
	},
	{},
};

static struct platform_driver ecpp_driver = {
	.driver = {
		.name = "ecpp",
		.of_match_table = ecpp_match,
	},
	.probe			= ecpp_probe,
	.remove			= ecpp_remove,
};

static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
{
	return platform_driver_register(&ecpp_driver);
}

#endif /* !(_ASM_SPARC64_PARPORT_H */
