/*
 * drivers/net/ethernet/ibm/emac/mal.c
 *
 * Memory Access Layer (MAL) support
 *
 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
 *                <benh@kernel.crashing.org>
 *
 * Based on the arch/ppc version of the driver:
 *
 * Copyright (c) 2004, 2005 Zultys Technologies.
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *
 * Based on original work by
 *      Benjamin Herrenschmidt <benh@kernel.crashing.org>,
 *      David Gibson <hermes@gibson.dropbear.id.au>,
 *
 *      Armin Kuster <akuster@mvista.com>
 *      Copyright 2002 MontaVista Softare Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 */

#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of_irq.h>

#include "core.h"
#include <asm/dcr-regs.h>

static int mal_count;

int mal_register_commac(struct mal_instance *mal, struct mal_commac *commac)
{
	unsigned long flags;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "reg(%08x, %08x)" NL,
		commac->tx_chan_mask, commac->rx_chan_mask);

	/* Don't let multiple commacs claim the same channel(s) */
	if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
	    (mal->rx_chan_mask & commac->rx_chan_mask)) {
		spin_unlock_irqrestore(&mal->lock, flags);
		printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
		       mal->index);
		return -EBUSY;
	}

	if (list_empty(&mal->list))
		napi_enable(&mal->napi);
	mal->tx_chan_mask |= commac->tx_chan_mask;
	mal->rx_chan_mask |= commac->rx_chan_mask;
	list_add(&commac->list, &mal->list);

	spin_unlock_irqrestore(&mal->lock, flags);

	return 0;
}

void mal_unregister_commac(struct mal_instance	*mal,
		struct mal_commac *commac)
{
	unsigned long flags;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "unreg(%08x, %08x)" NL,
		commac->tx_chan_mask, commac->rx_chan_mask);

	mal->tx_chan_mask &= ~commac->tx_chan_mask;
	mal->rx_chan_mask &= ~commac->rx_chan_mask;
	list_del_init(&commac->list);
	if (list_empty(&mal->list))
		napi_disable(&mal->napi);

	spin_unlock_irqrestore(&mal->lock, flags);
}

int mal_set_rcbs(struct mal_instance *mal, int channel, unsigned long size)
{
	BUG_ON(channel < 0 || channel >= mal->num_rx_chans ||
	       size > MAL_MAX_RX_SIZE);

	MAL_DBG(mal, "set_rbcs(%d, %lu)" NL, channel, size);

	if (size & 0xf) {
		printk(KERN_WARNING
		       "mal%d: incorrect RX size %lu for the channel %d\n",
		       mal->index, size, channel);
		return -EINVAL;
	}

	set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
	return 0;
}

int mal_tx_bd_offset(struct mal_instance *mal, int channel)
{
	BUG_ON(channel < 0 || channel >= mal->num_tx_chans);

	return channel * NUM_TX_BUFF;
}

int mal_rx_bd_offset(struct mal_instance *mal, int channel)
{
	BUG_ON(channel < 0 || channel >= mal->num_rx_chans);
	return mal->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
}

void mal_enable_tx_channel(struct mal_instance *mal, int channel)
{
	unsigned long flags;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "enable_tx(%d)" NL, channel);

	set_mal_dcrn(mal, MAL_TXCASR,
		     get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));

	spin_unlock_irqrestore(&mal->lock, flags);
}

void mal_disable_tx_channel(struct mal_instance *mal, int channel)
{
	set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));

	MAL_DBG(mal, "disable_tx(%d)" NL, channel);
}

void mal_enable_rx_channel(struct mal_instance *mal, int channel)
{
	unsigned long flags;

	/*
	 * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple
	 * of 8, but enabling in MAL_RXCASR needs the divided by 8 value
	 * for the bitmask
	 */
	if (!(channel % 8))
		channel >>= 3;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "enable_rx(%d)" NL, channel);

	set_mal_dcrn(mal, MAL_RXCASR,
		     get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));

	spin_unlock_irqrestore(&mal->lock, flags);
}

void mal_disable_rx_channel(struct mal_instance *mal, int channel)
{
	/*
	 * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple
	 * of 8, but enabling in MAL_RXCASR needs the divided by 8 value
	 * for the bitmask
	 */
	if (!(channel % 8))
		channel >>= 3;

	set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));

	MAL_DBG(mal, "disable_rx(%d)" NL, channel);
}

void mal_poll_add(struct mal_instance *mal, struct mal_commac *commac)
{
	unsigned long flags;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "poll_add(%p)" NL, commac);

	/* starts disabled */
	set_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags);

	list_add_tail(&commac->poll_list, &mal->poll_list);

	spin_unlock_irqrestore(&mal->lock, flags);
}

void mal_poll_del(struct mal_instance *mal, struct mal_commac *commac)
{
	unsigned long flags;

	spin_lock_irqsave(&mal->lock, flags);

	MAL_DBG(mal, "poll_del(%p)" NL, commac);

	list_del(&commac->poll_list);

	spin_unlock_irqrestore(&mal->lock, flags);
}

/* synchronized by mal_poll() */
static inline void mal_enable_eob_irq(struct mal_instance *mal)
{
	MAL_DBG2(mal, "enable_irq" NL);

	// XXX might want to cache MAL_CFG as the DCR read can be slooooow
	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
}

/* synchronized by NAPI state */
static inline void mal_disable_eob_irq(struct mal_instance *mal)
{
	// XXX might want to cache MAL_CFG as the DCR read can be slooooow
	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);

	MAL_DBG2(mal, "disable_irq" NL);
}

static irqreturn_t mal_serr(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;

	u32 esr = get_mal_dcrn(mal, MAL_ESR);

	/* Clear the error status register */
	set_mal_dcrn(mal, MAL_ESR, esr);

	MAL_DBG(mal, "SERR %08x" NL, esr);

	if (esr & MAL_ESR_EVB) {
		if (esr & MAL_ESR_DE) {
			/* We ignore Descriptor error,
			 * TXDE or RXDE interrupt will be generated anyway.
			 */
			return IRQ_HANDLED;
		}

		if (esr & MAL_ESR_PEIN) {
			/* PLB error, it's probably buggy hardware or
			 * incorrect physical address in BD (i.e. bug)
			 */
			if (net_ratelimit())
				printk(KERN_ERR
				       "mal%d: system error, "
				       "PLB (ESR = 0x%08x)\n",
				       mal->index, esr);
			return IRQ_HANDLED;
		}

		/* OPB error, it's probably buggy hardware or incorrect
		 * EBC setup
		 */
		if (net_ratelimit())
			printk(KERN_ERR
			       "mal%d: system error, OPB (ESR = 0x%08x)\n",
			       mal->index, esr);
	}
	return IRQ_HANDLED;
}

static inline void mal_schedule_poll(struct mal_instance *mal)
{
	if (likely(napi_schedule_prep(&mal->napi))) {
		MAL_DBG2(mal, "schedule_poll" NL);
		spin_lock(&mal->lock);
		mal_disable_eob_irq(mal);
		spin_unlock(&mal->lock);
		__napi_schedule(&mal->napi);
	} else
		MAL_DBG2(mal, "already in poll" NL);
}

static irqreturn_t mal_txeob(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;

	u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);

	MAL_DBG2(mal, "txeob %08x" NL, r);

	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_TXEOBISR, r);

#ifdef CONFIG_PPC_DCR_NATIVE
	if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
		mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
				(mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX));
#endif

	return IRQ_HANDLED;
}

static irqreturn_t mal_rxeob(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;

	u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);

	MAL_DBG2(mal, "rxeob %08x" NL, r);

	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_RXEOBISR, r);

#ifdef CONFIG_PPC_DCR_NATIVE
	if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
		mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
				(mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX));
#endif

	return IRQ_HANDLED;
}

static irqreturn_t mal_txde(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;

	u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
	set_mal_dcrn(mal, MAL_TXDEIR, deir);

	MAL_DBG(mal, "txde %08x" NL, deir);

	if (net_ratelimit())
		printk(KERN_ERR
		       "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
		       mal->index, deir);

	return IRQ_HANDLED;
}

static irqreturn_t mal_rxde(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;
	struct list_head *l;

	u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);

	MAL_DBG(mal, "rxde %08x" NL, deir);

	list_for_each(l, &mal->list) {
		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
		if (deir & mc->rx_chan_mask) {
			set_bit(MAL_COMMAC_RX_STOPPED, &mc->flags);
			mc->ops->rxde(mc->dev);
		}
	}

	mal_schedule_poll(mal);
	set_mal_dcrn(mal, MAL_RXDEIR, deir);

	return IRQ_HANDLED;
}

static irqreturn_t mal_int(int irq, void *dev_instance)
{
	struct mal_instance *mal = dev_instance;
	u32 esr = get_mal_dcrn(mal, MAL_ESR);

	if (esr & MAL_ESR_EVB) {
		/* descriptor error */
		if (esr & MAL_ESR_DE) {
			if (esr & MAL_ESR_CIDT)
				return mal_rxde(irq, dev_instance);
			else
				return mal_txde(irq, dev_instance);
		} else { /* SERR */
			return mal_serr(irq, dev_instance);
		}
	}
	return IRQ_HANDLED;
}

void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
{
	/* Spinlock-type semantics: only one caller disable poll at a time */
	while (test_and_set_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags))
		msleep(1);

	/* Synchronize with the MAL NAPI poller */
	napi_synchronize(&mal->napi);
}

void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
{
	smp_wmb();
	clear_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags);

	/* Feels better to trigger a poll here to catch up with events that
	 * may have happened on this channel while disabled. It will most
	 * probably be delayed until the next interrupt but that's mostly a
	 * non-issue in the context where this is called.
	 */
	napi_schedule(&mal->napi);
}

static int mal_poll(struct napi_struct *napi, int budget)
{
	struct mal_instance *mal = container_of(napi, struct mal_instance, napi);
	struct list_head *l;
	int received = 0;
	unsigned long flags;

	MAL_DBG2(mal, "poll(%d)" NL, budget);

	/* Process TX skbs */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
			list_entry(l, struct mal_commac, poll_list);
		mc->ops->poll_tx(mc->dev);
	}

	/* Process RX skbs.
	 *
	 * We _might_ need something more smart here to enforce polling
	 * fairness.
	 */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
			list_entry(l, struct mal_commac, poll_list);
		int n;
		if (unlikely(test_bit(MAL_COMMAC_POLL_DISABLED, &mc->flags)))
			continue;
		n = mc->ops->poll_rx(mc->dev, budget);
		if (n) {
			received += n;
			budget -= n;
			if (budget <= 0)
				goto more_work; // XXX What if this is the last one ?
		}
	}

	/* We need to disable IRQs to protect from RXDE IRQ here */
	spin_lock_irqsave(&mal->lock, flags);
	__napi_complete(napi);
	mal_enable_eob_irq(mal);
	spin_unlock_irqrestore(&mal->lock, flags);

	/* Check for "rotting" packet(s) */
	list_for_each(l, &mal->poll_list) {
		struct mal_commac *mc =
			list_entry(l, struct mal_commac, poll_list);
		if (unlikely(test_bit(MAL_COMMAC_POLL_DISABLED, &mc->flags)))
			continue;
		if (unlikely(mc->ops->peek_rx(mc->dev) ||
			     test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) {
			MAL_DBG2(mal, "rotting packet" NL);
			if (!napi_reschedule(napi))
				goto more_work;

			spin_lock_irqsave(&mal->lock, flags);
			mal_disable_eob_irq(mal);
			spin_unlock_irqrestore(&mal->lock, flags);
		}
		mc->ops->poll_tx(mc->dev);
	}

 more_work:
	MAL_DBG2(mal, "poll() %d <- %d" NL, budget, received);
	return received;
}

static void mal_reset(struct mal_instance *mal)
{
	int n = 10;

	MAL_DBG(mal, "reset" NL);

	set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);

	/* Wait for reset to complete (1 system clock) */
	while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
		--n;

	if (unlikely(!n))
		printk(KERN_ERR "mal%d: reset timeout\n", mal->index);
}

int mal_get_regs_len(struct mal_instance *mal)
{
	return sizeof(struct emac_ethtool_regs_subhdr) +
	    sizeof(struct mal_regs);
}

void *mal_dump_regs(struct mal_instance *mal, void *buf)
{
	struct emac_ethtool_regs_subhdr *hdr = buf;
	struct mal_regs *regs = (struct mal_regs *)(hdr + 1);
	int i;

	hdr->version = mal->version;
	hdr->index = mal->index;

	regs->tx_count = mal->num_tx_chans;
	regs->rx_count = mal->num_rx_chans;

	regs->cfg = get_mal_dcrn(mal, MAL_CFG);
	regs->esr = get_mal_dcrn(mal, MAL_ESR);
	regs->ier = get_mal_dcrn(mal, MAL_IER);
	regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
	regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
	regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
	regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
	regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
	regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
	regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
	regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);

	for (i = 0; i < regs->tx_count; ++i)
		regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));

	for (i = 0; i < regs->rx_count; ++i) {
		regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
		regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
	}
	return regs + 1;
}

static int mal_probe(struct platform_device *ofdev)
{
	struct mal_instance *mal;
	int err = 0, i, bd_size;
	int index = mal_count++;
	unsigned int dcr_base;
	const u32 *prop;
	u32 cfg;
	unsigned long irqflags;
	irq_handler_t hdlr_serr, hdlr_txde, hdlr_rxde;

	mal = kzalloc(sizeof(struct mal_instance), GFP_KERNEL);
	if (!mal)
		return -ENOMEM;

	mal->index = index;
	mal->ofdev = ofdev;
	mal->version = of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal2") ? 2 : 1;

	MAL_DBG(mal, "probe" NL);

	prop = of_get_property(ofdev->dev.of_node, "num-tx-chans", NULL);
	if (prop == NULL) {
		printk(KERN_ERR
		       "mal%d: can't find MAL num-tx-chans property!\n",
		       index);
		err = -ENODEV;
		goto fail;
	}
	mal->num_tx_chans = prop[0];

	prop = of_get_property(ofdev->dev.of_node, "num-rx-chans", NULL);
	if (prop == NULL) {
		printk(KERN_ERR
		       "mal%d: can't find MAL num-rx-chans property!\n",
		       index);
		err = -ENODEV;
		goto fail;
	}
	mal->num_rx_chans = prop[0];

	dcr_base = dcr_resource_start(ofdev->dev.of_node, 0);
	if (dcr_base == 0) {
		printk(KERN_ERR
		       "mal%d: can't find DCR resource!\n", index);
		err = -ENODEV;
		goto fail;
	}
	mal->dcr_host = dcr_map(ofdev->dev.of_node, dcr_base, 0x100);
	if (!DCR_MAP_OK(mal->dcr_host)) {
		printk(KERN_ERR
		       "mal%d: failed to map DCRs !\n", index);
		err = -ENODEV;
		goto fail;
	}

	if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-405ez")) {
#if defined(CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT) && \
		defined(CONFIG_IBM_EMAC_MAL_COMMON_ERR)
		mal->features |= (MAL_FTR_CLEAR_ICINTSTAT |
				MAL_FTR_COMMON_ERR_INT);
#else
		printk(KERN_ERR "%s: Support for 405EZ not enabled!\n",
				ofdev->dev.of_node->full_name);
		err = -ENODEV;
		goto fail;
#endif
	}

	mal->txeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
	mal->rxeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 1);
	mal->serr_irq = irq_of_parse_and_map(ofdev->dev.of_node, 2);

	if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) {
		mal->txde_irq = mal->rxde_irq = mal->serr_irq;
	} else {
		mal->txde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 3);
		mal->rxde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 4);
	}

	if (!mal->txeob_irq || !mal->rxeob_irq || !mal->serr_irq ||
	    !mal->txde_irq  || !mal->rxde_irq) {
		printk(KERN_ERR
		       "mal%d: failed to map interrupts !\n", index);
		err = -ENODEV;
		goto fail_unmap;
	}

	INIT_LIST_HEAD(&mal->poll_list);
	INIT_LIST_HEAD(&mal->list);
	spin_lock_init(&mal->lock);

	init_dummy_netdev(&mal->dummy_dev);

	netif_napi_add(&mal->dummy_dev, &mal->napi, mal_poll,
		       CONFIG_IBM_EMAC_POLL_WEIGHT);

	/* Load power-on reset defaults */
	mal_reset(mal);

	/* Set the MAL configuration register */
	cfg = (mal->version == 2) ? MAL2_CFG_DEFAULT : MAL1_CFG_DEFAULT;
	cfg |= MAL_CFG_PLBB | MAL_CFG_OPBBL | MAL_CFG_LEA;

	/* Current Axon is not happy with priority being non-0, it can
	 * deadlock, fix it up here
	 */
	if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-axon"))
		cfg &= ~(MAL2_CFG_RPP_10 | MAL2_CFG_WPP_10);

	/* Apply configuration */
	set_mal_dcrn(mal, MAL_CFG, cfg);

	/* Allocate space for BD rings */
	BUG_ON(mal->num_tx_chans <= 0 || mal->num_tx_chans > 32);
	BUG_ON(mal->num_rx_chans <= 0 || mal->num_rx_chans > 32);

	bd_size = sizeof(struct mal_descriptor) *
		(NUM_TX_BUFF * mal->num_tx_chans +
		 NUM_RX_BUFF * mal->num_rx_chans);
	mal->bd_virt = dma_zalloc_coherent(&ofdev->dev, bd_size, &mal->bd_dma,
					   GFP_KERNEL);
	if (mal->bd_virt == NULL) {
		err = -ENOMEM;
		goto fail_unmap;
	}

	for (i = 0; i < mal->num_tx_chans; ++i)
		set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
			     sizeof(struct mal_descriptor) *
			     mal_tx_bd_offset(mal, i));

	for (i = 0; i < mal->num_rx_chans; ++i)
		set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
			     sizeof(struct mal_descriptor) *
			     mal_rx_bd_offset(mal, i));

	if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) {
		irqflags = IRQF_SHARED;
		hdlr_serr = hdlr_txde = hdlr_rxde = mal_int;
	} else {
		irqflags = 0;
		hdlr_serr = mal_serr;
		hdlr_txde = mal_txde;
		hdlr_rxde = mal_rxde;
	}

	err = request_irq(mal->serr_irq, hdlr_serr, irqflags, "MAL SERR", mal);
	if (err)
		goto fail2;
	err = request_irq(mal->txde_irq, hdlr_txde, irqflags, "MAL TX DE", mal);
	if (err)
		goto fail3;
	err = request_irq(mal->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
	if (err)
		goto fail4;
	err = request_irq(mal->rxde_irq, hdlr_rxde, irqflags, "MAL RX DE", mal);
	if (err)
		goto fail5;
	err = request_irq(mal->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
	if (err)
		goto fail6;

	/* Enable all MAL SERR interrupt sources */
	set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);

	/* Enable EOB interrupt */
	mal_enable_eob_irq(mal);

	printk(KERN_INFO
	       "MAL v%d %s, %d TX channels, %d RX channels\n",
	       mal->version, ofdev->dev.of_node->full_name,
	       mal->num_tx_chans, mal->num_rx_chans);

	/* Advertise this instance to the rest of the world */
	wmb();
	platform_set_drvdata(ofdev, mal);

	mal_dbg_register(mal);

	return 0;

 fail6:
	free_irq(mal->rxde_irq, mal);
 fail5:
	free_irq(mal->txeob_irq, mal);
 fail4:
	free_irq(mal->txde_irq, mal);
 fail3:
	free_irq(mal->serr_irq, mal);
 fail2:
	dma_free_coherent(&ofdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
 fail_unmap:
	dcr_unmap(mal->dcr_host, 0x100);
 fail:
	kfree(mal);

	return err;
}

static int mal_remove(struct platform_device *ofdev)
{
	struct mal_instance *mal = platform_get_drvdata(ofdev);

	MAL_DBG(mal, "remove" NL);

	/* Synchronize with scheduled polling */
	napi_disable(&mal->napi);

	if (!list_empty(&mal->list))
		/* This is *very* bad */
		WARN(1, KERN_EMERG
		       "mal%d: commac list is not empty on remove!\n",
		       mal->index);

	free_irq(mal->serr_irq, mal);
	free_irq(mal->txde_irq, mal);
	free_irq(mal->txeob_irq, mal);
	free_irq(mal->rxde_irq, mal);
	free_irq(mal->rxeob_irq, mal);

	mal_reset(mal);

	mal_dbg_unregister(mal);

	dma_free_coherent(&ofdev->dev,
			  sizeof(struct mal_descriptor) *
			  (NUM_TX_BUFF * mal->num_tx_chans +
			   NUM_RX_BUFF * mal->num_rx_chans), mal->bd_virt,
			  mal->bd_dma);
	kfree(mal);

	return 0;
}

static const struct of_device_id mal_platform_match[] =
{
	{
		.compatible	= "ibm,mcmal",
	},
	{
		.compatible	= "ibm,mcmal2",
	},
	/* Backward compat */
	{
		.type		= "mcmal-dma",
		.compatible	= "ibm,mcmal",
	},
	{
		.type		= "mcmal-dma",
		.compatible	= "ibm,mcmal2",
	},
	{},
};

static struct platform_driver mal_of_driver = {
	.driver = {
		.name = "mcmal",
		.of_match_table = mal_platform_match,
	},
	.probe = mal_probe,
	.remove = mal_remove,
};

int __init mal_init(void)
{
	return platform_driver_register(&mal_of_driver);
}

void mal_exit(void)
{
	platform_driver_unregister(&mal_of_driver);
}
