/*
 * Marvell 88e6xxx Ethernet switch PHY and PPU support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
 *
 * 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/mdio.h>
#include <linux/module.h>

#include "chip.h"
#include "phy.h"

int mv88e6165_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
		       int addr, int reg, u16 *val)
{
	return mv88e6xxx_read(chip, addr, reg, val);
}

int mv88e6165_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
			int addr, int reg, u16 val)
{
	return mv88e6xxx_write(chip, addr, reg, val);
}

int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy, int reg, u16 *val)
{
	int addr = phy; /* PHY devices addresses start at 0x0 */
	struct mii_bus *bus;

	bus = mv88e6xxx_default_mdio_bus(chip);
	if (!bus)
		return -EOPNOTSUPP;

	if (!chip->info->ops->phy_read)
		return -EOPNOTSUPP;

	return chip->info->ops->phy_read(chip, bus, addr, reg, val);
}

int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy, int reg, u16 val)
{
	int addr = phy; /* PHY devices addresses start at 0x0 */
	struct mii_bus *bus;

	bus = mv88e6xxx_default_mdio_bus(chip);
	if (!bus)
		return -EOPNOTSUPP;

	if (!chip->info->ops->phy_write)
		return -EOPNOTSUPP;

	return chip->info->ops->phy_write(chip, bus, addr, reg, val);
}

static int mv88e6xxx_phy_page_get(struct mv88e6xxx_chip *chip, int phy, u8 page)
{
	return mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_PAGE, page);
}

static void mv88e6xxx_phy_page_put(struct mv88e6xxx_chip *chip, int phy)
{
	int err;

	/* Restore PHY page Copper 0x0 for access via the registered
	 * MDIO bus
	 */
	err = mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_PAGE,
				  MV88E6XXX_PHY_PAGE_COPPER);
	if (unlikely(err)) {
		dev_err(chip->dev,
			"failed to restore PHY %d page Copper (%d)\n",
			phy, err);
	}
}

int mv88e6xxx_phy_page_read(struct mv88e6xxx_chip *chip, int phy,
			    u8 page, int reg, u16 *val)
{
	int err;

	/* There is no paging for registers 22 */
	if (reg == MV88E6XXX_PHY_PAGE)
		return -EINVAL;

	err = mv88e6xxx_phy_page_get(chip, phy, page);
	if (!err) {
		err = mv88e6xxx_phy_read(chip, phy, reg, val);
		mv88e6xxx_phy_page_put(chip, phy);
	}

	return err;
}

int mv88e6xxx_phy_page_write(struct mv88e6xxx_chip *chip, int phy,
			     u8 page, int reg, u16 val)
{
	int err;

	/* There is no paging for registers 22 */
	if (reg == MV88E6XXX_PHY_PAGE)
		return -EINVAL;

	err = mv88e6xxx_phy_page_get(chip, phy, page);
	if (!err) {
		err = mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_PAGE, page);
		mv88e6xxx_phy_page_put(chip, phy);
	}

	return err;
}

static int mv88e6xxx_phy_ppu_disable(struct mv88e6xxx_chip *chip)
{
	if (!chip->info->ops->ppu_disable)
		return 0;

	return chip->info->ops->ppu_disable(chip);
}

static int mv88e6xxx_phy_ppu_enable(struct mv88e6xxx_chip *chip)
{
	if (!chip->info->ops->ppu_enable)
		return 0;

	return chip->info->ops->ppu_enable(chip);
}

static void mv88e6xxx_phy_ppu_reenable_work(struct work_struct *ugly)
{
	struct mv88e6xxx_chip *chip;

	chip = container_of(ugly, struct mv88e6xxx_chip, ppu_work);

	mutex_lock(&chip->reg_lock);

	if (mutex_trylock(&chip->ppu_mutex)) {
		if (mv88e6xxx_phy_ppu_enable(chip) == 0)
			chip->ppu_disabled = 0;
		mutex_unlock(&chip->ppu_mutex);
	}

	mutex_unlock(&chip->reg_lock);
}

static void mv88e6xxx_phy_ppu_reenable_timer(unsigned long _ps)
{
	struct mv88e6xxx_chip *chip = (void *)_ps;

	schedule_work(&chip->ppu_work);
}

static int mv88e6xxx_phy_ppu_access_get(struct mv88e6xxx_chip *chip)
{
	int ret;

	mutex_lock(&chip->ppu_mutex);

	/* If the PHY polling unit is enabled, disable it so that
	 * we can access the PHY registers.  If it was already
	 * disabled, cancel the timer that is going to re-enable
	 * it.
	 */
	if (!chip->ppu_disabled) {
		ret = mv88e6xxx_phy_ppu_disable(chip);
		if (ret < 0) {
			mutex_unlock(&chip->ppu_mutex);
			return ret;
		}
		chip->ppu_disabled = 1;
	} else {
		del_timer(&chip->ppu_timer);
		ret = 0;
	}

	return ret;
}

static void mv88e6xxx_phy_ppu_access_put(struct mv88e6xxx_chip *chip)
{
	/* Schedule a timer to re-enable the PHY polling unit. */
	mod_timer(&chip->ppu_timer, jiffies + msecs_to_jiffies(10));
	mutex_unlock(&chip->ppu_mutex);
}

static void mv88e6xxx_phy_ppu_state_init(struct mv88e6xxx_chip *chip)
{
	mutex_init(&chip->ppu_mutex);
	INIT_WORK(&chip->ppu_work, mv88e6xxx_phy_ppu_reenable_work);
	setup_timer(&chip->ppu_timer, mv88e6xxx_phy_ppu_reenable_timer,
		    (unsigned long)chip);
}

static void mv88e6xxx_phy_ppu_state_destroy(struct mv88e6xxx_chip *chip)
{
	del_timer_sync(&chip->ppu_timer);
}

int mv88e6185_phy_ppu_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
			   int addr, int reg, u16 *val)
{
	int err;

	err = mv88e6xxx_phy_ppu_access_get(chip);
	if (!err) {
		err = mv88e6xxx_read(chip, addr, reg, val);
		mv88e6xxx_phy_ppu_access_put(chip);
	}

	return err;
}

int mv88e6185_phy_ppu_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
			    int addr, int reg, u16 val)
{
	int err;

	err = mv88e6xxx_phy_ppu_access_get(chip);
	if (!err) {
		err = mv88e6xxx_write(chip, addr, reg, val);
		mv88e6xxx_phy_ppu_access_put(chip);
	}

	return err;
}

void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip)
{
	if (chip->info->ops->ppu_enable && chip->info->ops->ppu_disable)
		mv88e6xxx_phy_ppu_state_init(chip);
}

void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip)
{
	if (chip->info->ops->ppu_enable && chip->info->ops->ppu_disable)
		mv88e6xxx_phy_ppu_state_destroy(chip);
}

int mv88e6xxx_phy_setup(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_phy_ppu_enable(chip);
}
