diff options
Diffstat (limited to 'target/linux/mcs814x/files-3.3/drivers')
9 files changed, 0 insertions, 2120 deletions
diff --git a/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c b/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c deleted file mode 100644 index 5e3d8f2479..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * RNG driver for Moschip MCS814x SoC - * - * Copyright 2012 (C), Florian Fainelli <florian@openwrt.org> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/platform_device.h> -#include <linux/hw_random.h> -#include <linux/io.h> -#include <linux/of.h> - -#define STAT 0x00 -#define RND 0x04 - -struct mcs814x_rng_priv { - void __iomem *regs; -}; - -static int mcs814x_rng_data_read(struct hwrng *rng, u32 *buffer) -{ - struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv; - - *buffer = readl_relaxed(priv->regs + RND); - - return 4; -} - -static int mcs814x_rng_probe(struct platform_device *pdev) -{ - struct resource *res; - struct mcs814x_rng_priv *priv; - struct hwrng *rng; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto out; - } - - rng = kzalloc(sizeof(*rng), GFP_KERNEL); - if (!rng) { - ret = -ENOMEM; - goto out_priv; - } - - platform_set_drvdata(pdev, rng); - rng->priv = (unsigned long)priv; - rng->name = pdev->name; - rng->data_read = mcs814x_rng_data_read; - - priv->regs = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->regs) { - ret = -ENOMEM; - goto out_rng; - } - - ret = hwrng_register(rng); - if (ret) { - dev_err(&pdev->dev, "failed to register hwrng driver\n"); - goto out; - } - - dev_info(&pdev->dev, "registered\n"); - - return ret; - -out_rng: - platform_set_drvdata(pdev, NULL); - kfree(rng); -out_priv: - kfree(priv); -out: - return ret; -} - -static int mcs814x_rng_remove(struct platform_device *pdev) -{ - struct hwrng *rng = platform_get_drvdata(pdev); - struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv; - - hwrng_unregister(rng); - kfree(priv); - kfree(rng); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id mcs814x_rng_ids[] = { - { .compatible = "moschip,mcs814x-rng", }, - { /* sentinel */ }, -}; - -static struct platform_driver mcs814x_rng_driver = { - .driver = { - .name = "mcs814x-rng", - .owner = THIS_MODULE, - .of_match_table = mcs814x_rng_ids, - }, - .probe = mcs814x_rng_probe, - .remove = __devexit_p(mcs814x_rng_remove), -}; - -module_platform_driver(mcs814x_rng_driver); - -MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); -MODULE_DESCRIPTION("H/W Random Number Generator (RNG) for Moschip MCS814x"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/mcs814x/files-3.3/drivers/gpio/gpio-mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/gpio/gpio-mcs814x.c deleted file mode 100644 index f1382290fb..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/gpio/gpio-mcs814x.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Moschip MCS814x GPIO support - * - * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> - * - * Licensed under the GPLv2 - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> - -struct mcs814x_gpio_chip { - void __iomem *regs; - struct gpio_chip chip; -}; - -#define GPIO_PIN 0x00 -#define GPIO_DIR 0x04 - -#define to_mcs814x_gpio_chip(x) container_of(x, struct mcs814x_gpio_chip, chip) - -static int mcs814x_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip); - - return readl_relaxed(mcs814x->regs + GPIO_PIN) & (1 << offset); -} - -static void mcs814x_gpio_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip); - u32 mask; - - mask = readl_relaxed(mcs814x->regs + GPIO_PIN); - if (value) - mask |= (1 << offset); - else - mask &= ~(1 << offset); - writel_relaxed(mask, mcs814x->regs + GPIO_PIN); -} - -static int mcs814x_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip); - u32 mask; - - mask = readl_relaxed(mcs814x->regs + GPIO_DIR); - mask &= ~(1 << offset); - writel_relaxed(mask, mcs814x->regs + GPIO_DIR); - - return 0; -} - -static int mcs814x_gpio_direction_input(struct gpio_chip *chip, - unsigned offset) -{ - struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip); - u32 mask; - - mask = readl_relaxed(mcs814x->regs + GPIO_DIR); - mask |= (1 << offset); - writel_relaxed(mask, mcs814x->regs + GPIO_DIR); - - return 0; -} - -static int __devinit mcs814x_gpio_probe(struct platform_device *pdev) -{ - struct resource *res; - struct mcs814x_gpio_chip *mcs814x_chip; - int ret; - const unsigned int *num_gpios; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - num_gpios = of_get_property(pdev->dev.of_node, "num-gpios", NULL); - if (!num_gpios) - dev_err(&pdev->dev, "FIXME: no num-gpios property\n"); - - mcs814x_chip = kzalloc(sizeof(*mcs814x_chip), GFP_KERNEL); - if (!mcs814x_chip) - return -ENOMEM; - - mcs814x_chip->regs = devm_request_and_ioremap(&pdev->dev, res); - if (!mcs814x_chip->regs) { - ret = -ENOMEM; - goto out; - } - - platform_set_drvdata(pdev, mcs814x_chip); - -#ifdef CONFIG_OF_GPIO - mcs814x_chip->chip.of_node = pdev->dev.of_node; -#endif - - mcs814x_chip->chip.label = pdev->name; - mcs814x_chip->chip.get = mcs814x_gpio_get; - mcs814x_chip->chip.set = mcs814x_gpio_set; - mcs814x_chip->chip.direction_input = mcs814x_gpio_direction_input; - mcs814x_chip->chip.direction_output = mcs814x_gpio_direction_output; - mcs814x_chip->chip.ngpio = be32_to_cpup(num_gpios); - /* we want dynamic base allocation */ - mcs814x_chip->chip.base = -1; - - ret = gpiochip_add(&mcs814x_chip->chip); - if (ret) { - dev_err(&pdev->dev, "failed to register gpiochip\n"); - goto out; - } - - return 0; - -out: - platform_set_drvdata(pdev, NULL); - kfree(mcs814x_chip); - return ret; -} - -static struct of_device_id mcs814x_gpio_ids[] __devinitdata = { - { .compatible = "moschip,mcs814x-gpio" }, - { /* sentinel */ }, -}; - -static struct platform_driver mcs814x_gpio_driver = { - .driver = { - .name = "mcs814x-gpio", - .owner = THIS_MODULE, - .of_match_table = mcs814x_gpio_ids, - }, - .probe = mcs814x_gpio_probe, -}; - -int __init mcs814x_gpio_init(void) -{ - return platform_driver_register(&mcs814x_gpio_driver); -} -postcore_initcall(mcs814x_gpio_init); diff --git a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Kconfig b/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Kconfig deleted file mode 100644 index 8fa38a4091..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Kconfig +++ /dev/null @@ -1,4 +0,0 @@ -config NUPORT_ETHERNET_DRIVER - tristate "MCS8140 Ethernet driver" - depends on ETHERNET && ARCH_MCS814X - help diff --git a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Makefile b/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Makefile deleted file mode 100644 index 9719c51b7f..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_NUPORT_ETHERNET_DRIVER) += mcs8140.o - -mcs8140-objs := nuport_mac.o diff --git a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c b/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c deleted file mode 100644 index f11f425a00..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c +++ /dev/null @@ -1,1206 +0,0 @@ -/* - * Moschip MCS8140 Ethernet MAC driver - * - * Copyright (C) 2003, Moschip Semiconductors - * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> - * - * Licensed under GPLv2 - */ -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/delay.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_mdio.h> -#include <linux/of_net.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/phy.h> -#include <linux/clk.h> -#include <linux/dma-mapping.h> - -#include <asm/unaligned.h> -#include <asm/sizes.h> - -/* Hardware registers */ -#define MAC_BASE_ADDR ((priv->mac_base)) - -#define CTRL_REG (MAC_BASE_ADDR) -#define MII_BUSY (1 << 0) -#define MII_WRITE (1 << 1) -#define RX_ENABLE (1 << 2) -#define TX_ENABLE (1 << 3) -#define DEFER_CHECK (1 << 5) -#define STRIP_PAD (1 << 8) -#define DRTRY_DISABLE (1 << 10) -#define FULL_DUPLEX (1 << 20) -#define HBD_DISABLE (1 << 28) -#define MAC_ADDR_HIGH_REG (MAC_BASE_ADDR + 0x04) -#define MAC_ADDR_LOW_REG (MAC_BASE_ADDR + 0x08) -#define MII_ADDR_REG (MAC_BASE_ADDR + 0x14) -#define MII_ADDR_SHIFT (11) -#define MII_REG_SHIFT (6) -#define MII_DATA_REG (MAC_BASE_ADDR + 0x18) -/* Link interrupt registers */ -#define LINK_INT_CSR (MAC_BASE_ADDR + 0xD0) -#define LINK_INT_EN (1 << 0) -#define LINK_PHY_ADDR_SHIFT (1) -#define LINK_PHY_REG_SHIFT (6) -#define LINK_BIT_UP_SHIFT (11) -#define LINK_UP (1 << 16) -#define LINK_INT_POLL_TIME (MAC_BASE_ADDR + 0xD4) -#define LINK_POLL_MASK ((1 << 20) - 1) - -#define DMA_CHAN_WIDTH 32 -#define DMA_RX_CHAN 0 -#define DMA_TX_CHAN 2 - -/* Receive DMA registers */ -#define RX_DMA_BASE ((priv->dma_base) + \ - (DMA_CHAN_WIDTH * DMA_RX_CHAN)) -#define RX_BUFFER_ADDR (RX_DMA_BASE + 0x00) -#define RX_MAX_BYTES (RX_DMA_BASE + 0x04) -#define RX_ACT_BYTES (RX_DMA_BASE + 0x08) -#define RX_START_DMA (RX_DMA_BASE + 0x0C) -#define RX_DMA_ENABLE (1 << 0) -#define RX_DMA_RESET (1 << 1) -#define RX_DMA_STATUS_FIFO (1 << 12) -#define RX_DMA_ENH (RX_DMA_BASE + 0x14) -#define RX_DMA_INT_ENABLE (1 << 1) - -/* Transmit DMA registers */ -#define TX_DMA_BASE ((priv->dma_base) + \ - (DMA_CHAN_WIDTH * DMA_TX_CHAN)) -#define TX_BUFFER_ADDR (TX_DMA_BASE + 0x00) -#define TX_PKT_BYTES (TX_DMA_BASE + 0x04) -#define TX_BYTES_SENT (TX_DMA_BASE + 0x08) -#define TX_START_DMA (TX_DMA_BASE + 0x0C) -#define TX_DMA_ENABLE (1 << 0) -#define TX_DMA_START_FRAME (1 << 2) -#define TX_DMA_END_FRAME (1 << 3) -#define TX_DMA_PAD_DISABLE (1 << 8) -#define TX_DMA_CRC_DISABLE (1 << 9) -#define TX_DMA_FIFO_FULL (1 << 16) -#define TX_DMA_FIFO_EMPTY (1 << 17) -#define TX_DMA_STATUS_AVAIL (1 << 18) -#define TX_DMA_RESET (1 << 24) -#define TX_DMA_STATUS (TX_DMA_BASE + 0x10) -#define TX_DMA_ENH (TX_DMA_BASE + 0x14) -#define TX_DMA_ENH_ENABLE (1 << 0) -#define TX_DMA_INT_FIFO (1 << 1) - -#define RX_ALLOC_SIZE SZ_2K -#define MAX_ETH_FRAME_SIZE 1536 -#define RX_SKB_TAILROOM 128 -#define RX_SKB_HEADROOM (RX_ALLOC_SIZE - \ - (MAX_ETH_FRAME_SIZE + RX_SKB_TAILROOM) + 0) - - /* WDT Late COL Lenght COL Type */ -#define ERROR_FILTER_MASK ((1<<14) | (1<<15) | (1<<16) | (1<<17) | (0<<18) | \ - /* MII Dribbling CRC Len/type Control */\ - (1<<19) | (1<<20) | (1<<21) | (0<<24) | (1<<25) | \ - /* Unsup Missed */\ - (1<<26) | (0<<31)) -#define TX_RING_SIZE 30 -#define RX_RING_SIZE 30 - -static inline u32 nuport_mac_readl(void __iomem *reg) -{ - return readl_relaxed(reg); -} - -static inline u8 nuport_mac_readb(void __iomem *reg) -{ - return readb_relaxed(reg); -} - -static inline void nuport_mac_writel(u32 value, void __iomem *reg) -{ - writel_relaxed(value, reg); -} - -static inline void nuport_mac_writeb(u8 value, void __iomem *reg) -{ - writel_relaxed(value, reg); -} - -/* MAC private data */ -struct nuport_mac_priv { - spinlock_t lock; - - void __iomem *mac_base; - void __iomem *dma_base; - - int rx_irq; - int tx_irq; - int link_irq; - struct clk *emac_clk; - struct clk *ephy_clk; - - /* Transmit buffers */ - struct sk_buff *tx_skb[TX_RING_SIZE]; - dma_addr_t tx_addr; - unsigned int valid_txskb[TX_RING_SIZE]; - unsigned int cur_tx; - unsigned int dma_tx; - unsigned int tx_full; - - /* Receive buffers */ - struct sk_buff *rx_skb[RX_RING_SIZE]; - dma_addr_t rx_addr; - unsigned int irq_rxskb[RX_RING_SIZE]; - int pkt_len[RX_RING_SIZE]; - unsigned int cur_rx; - unsigned int dma_rx; - unsigned int rx_full; - - unsigned int first_pkt; - - /* Private data */ - struct napi_struct napi; - struct net_device *dev; - struct platform_device *pdev; - struct mii_bus *mii_bus; - struct phy_device *phydev; - struct device_node *phy_node; - phy_interface_t phy_interface; - int old_link; - int old_duplex; - u32 msg_level; - unsigned int buffer_shifting_len; -}; - -static inline int nuport_mac_mii_busy_wait(struct nuport_mac_priv *priv) -{ - unsigned long curr; - unsigned long finish = jiffies + 3 * HZ; - - do { - curr = jiffies; - if (!(nuport_mac_readl(MII_ADDR_REG) & MII_BUSY)) - return 0; - cpu_relax(); - } while (!time_after_eq(curr, finish)); - - return -EBUSY; -} - -/* Read from PHY registers */ -static int nuport_mac_mii_read(struct mii_bus *bus, - int mii_id, int regnum) -{ - struct net_device *dev = bus->priv; - struct nuport_mac_priv *priv = netdev_priv(dev); - int ret; - u32 val = 0; - - ret = nuport_mac_mii_busy_wait(priv); - if (ret) - return ret; - - val |= (mii_id << MII_ADDR_SHIFT) | (regnum << MII_REG_SHIFT) | MII_BUSY; - nuport_mac_writel(val, MII_ADDR_REG); - ret = nuport_mac_mii_busy_wait(priv); - if (ret) - return ret; - - return nuport_mac_readl(MII_DATA_REG); -} - -static int nuport_mac_mii_write(struct mii_bus *bus, int mii_id, - int regnum, u16 value) -{ - struct net_device *dev = bus->priv; - struct nuport_mac_priv *priv = netdev_priv(dev); - int ret; - u32 val = 0; - - ret = nuport_mac_mii_busy_wait(priv); - if (ret) - return ret; - - val |= (mii_id << MII_ADDR_SHIFT) | (regnum << MII_REG_SHIFT); - val |= MII_BUSY | MII_WRITE; - nuport_mac_writel(value, MII_DATA_REG); - nuport_mac_writel(val, MII_ADDR_REG); - - return nuport_mac_mii_busy_wait(priv); -} - -static int nuport_mac_mii_reset(struct mii_bus *bus) -{ - return 0; -} - -static int nuport_mac_start_tx_dma(struct nuport_mac_priv *priv, - struct sk_buff *skb) -{ - u32 reg; - unsigned int timeout = 2048; - - while (timeout--) { - reg = nuport_mac_readl(TX_START_DMA); - if (!(reg & TX_DMA_ENABLE)) { - netdev_dbg(priv->dev, "dma ready\n"); - break; - } - cpu_relax(); - } - - if (!timeout) - return -EBUSY; - - priv->tx_addr = dma_map_single(&priv->pdev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, priv->tx_addr)) - return -ENOMEM; - - /* enable enhanced mode */ - nuport_mac_writel(TX_DMA_ENH_ENABLE, TX_DMA_ENH); - nuport_mac_writel(priv->tx_addr, TX_BUFFER_ADDR); - nuport_mac_writel((skb->len) - 1, TX_PKT_BYTES); - wmb(); - reg = TX_DMA_ENABLE | TX_DMA_START_FRAME | TX_DMA_END_FRAME; - nuport_mac_writel(reg, TX_START_DMA); - - return 0; -} - -static void nuport_mac_reset_tx_dma(struct nuport_mac_priv *priv) -{ - u32 reg; - - reg = nuport_mac_readl(TX_START_DMA); - reg |= TX_DMA_RESET; - nuport_mac_writel(reg, TX_START_DMA); -} - -static int nuport_mac_start_rx_dma(struct nuport_mac_priv *priv, - struct sk_buff *skb) -{ - u32 reg; - unsigned int timeout = 2048; - - while (timeout--) { - reg = nuport_mac_readl(RX_START_DMA); - if (!(reg & RX_DMA_ENABLE)) { - netdev_dbg(priv->dev, "dma ready\n"); - break; - } - cpu_relax(); - } - - if (!timeout) - return -EBUSY; - - priv->rx_addr = dma_map_single(&priv->pdev->dev, skb->data, - RX_ALLOC_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, priv->rx_addr)) - return -ENOMEM; - - nuport_mac_writel(priv->rx_addr, RX_BUFFER_ADDR); - wmb(); - nuport_mac_writel(RX_DMA_ENABLE, RX_START_DMA); - - return 0; -} - -static void nuport_mac_reset_rx_dma(struct nuport_mac_priv *priv) -{ - u32 reg; - - reg = nuport_mac_readl(RX_START_DMA); - reg |= RX_DMA_RESET; - nuport_mac_writel(reg, RX_START_DMA); -} - -/* I suppose this might do something, but I am not sure actually */ -static void nuport_mac_disable_rx_dma(struct nuport_mac_priv *priv) -{ - u32 reg; - - reg = nuport_mac_readl(RX_DMA_ENH); - reg &= ~RX_DMA_INT_ENABLE; - nuport_mac_writel(reg, RX_DMA_ENH); -} - -static void nuport_mac_enable_rx_dma(struct nuport_mac_priv *priv) -{ - u32 reg; - - reg = nuport_mac_readl(RX_DMA_ENH); - reg |= RX_DMA_INT_ENABLE; - nuport_mac_writel(reg, RX_DMA_ENH); -} - -/* Add packets to the transmit queue */ -static int nuport_mac_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - unsigned long flags; - struct nuport_mac_priv *priv = netdev_priv(dev); - int ret; - - if (netif_queue_stopped(dev)) { - netdev_warn(dev, "netif queue was stopped, restarting\n"); - netif_start_queue(dev); - } - - spin_lock_irqsave(&priv->lock, flags); - if (priv->first_pkt) { - ret = nuport_mac_start_tx_dma(priv, skb); - if (ret) { - netif_stop_queue(dev); - spin_unlock_irqrestore(&priv->lock, flags); - netdev_err(dev, "transmit path busy\n"); - return NETDEV_TX_BUSY; - } - priv->first_pkt = 0; - } - - priv->tx_skb[priv->cur_tx] = skb; - dev->stats.tx_bytes += skb->len; - dev->stats.tx_packets++; - priv->valid_txskb[priv->cur_tx] = 1; - priv->cur_tx++; - dev->trans_start = jiffies; - - if (priv->cur_tx >= TX_RING_SIZE) - priv->cur_tx = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->valid_txskb[priv->cur_tx]) { - priv->tx_full = 1; - netdev_err(dev, "stopping queue\n"); - netif_stop_queue(dev); - } - - return NETDEV_TX_OK; -} - -static void nuport_mac_adjust_link(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - struct phy_device *phydev = priv->phydev; - unsigned int status_changed = 0; - u32 reg; - - BUG_ON(!phydev); - - if (priv->old_link != phydev->link) { - status_changed = 1; - priv->old_link = phydev->link; - } - - if (phydev->link && (priv->old_duplex != phydev->duplex)) { - reg = nuport_mac_readl(CTRL_REG); - if (phydev->duplex == DUPLEX_FULL) - reg |= DUPLEX_FULL; - else - reg &= ~DUPLEX_FULL; - nuport_mac_writel(reg, CTRL_REG); - - status_changed = 1; - priv->old_duplex = phydev->duplex; - } - - if (!status_changed) - return; - - pr_info("%s: link %s", dev->name, phydev->link ? - "UP" : "DOWN"); - if (phydev->link) { - pr_cont(" - %d/%s", phydev->speed, - phydev->duplex == DUPLEX_FULL ? "full" : "half"); - } - pr_cont("\n"); -} - -static irqreturn_t nuport_mac_link_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct nuport_mac_priv *priv = netdev_priv(dev); - u32 reg; - u8 phy_addr; - unsigned long flags; - irqreturn_t ret = IRQ_HANDLED; - - spin_lock_irqsave(&priv->lock, flags); - reg = nuport_mac_readl(LINK_INT_CSR); - phy_addr = (reg >> LINK_PHY_ADDR_SHIFT) & (PHY_MAX_ADDR - 1); - - if (phy_addr != priv->phydev->addr) { - netdev_err(dev, "spurious PHY irq (phy: %d)\n", phy_addr); - ret = IRQ_NONE; - goto out; - } - - priv->phydev->link = (reg & LINK_UP); - nuport_mac_adjust_link(dev); - -out: - spin_unlock_irqrestore(&priv->lock, flags); - return ret; -} - -static irqreturn_t nuport_mac_tx_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *)dev_id; - struct nuport_mac_priv *priv = netdev_priv(dev); - struct sk_buff *skb; - unsigned long flags; - int ret; - u32 reg; - - spin_lock_irqsave(&priv->lock, flags); - /* clear status word available if ready */ - reg = nuport_mac_readl(TX_START_DMA); - if (reg & TX_DMA_STATUS_AVAIL) { - nuport_mac_writel(reg, TX_START_DMA); - reg = nuport_mac_readl(TX_DMA_STATUS); - - if (reg & 1) - dev->stats.tx_errors++; - } else - netdev_dbg(dev, "no status word: %08x\n", reg); - - skb = priv->tx_skb[priv->dma_tx]; - priv->tx_skb[priv->dma_tx] = NULL; - priv->valid_txskb[priv->dma_tx] = 0; - dma_unmap_single(&priv->pdev->dev, priv->rx_addr, skb->len, - DMA_TO_DEVICE); - dev_kfree_skb_irq(skb); - - priv->dma_tx++; - if (priv->dma_tx >= TX_RING_SIZE) - priv->dma_tx = 0; - - if (!priv->valid_txskb[priv->dma_tx]) - priv->first_pkt = 1; - else { - ret = nuport_mac_start_tx_dma(priv, priv->tx_skb[priv->dma_tx]); - if (ret) - netdev_err(dev, "failed to restart TX dma\n"); - } - - if (priv->tx_full) { - netdev_dbg(dev, "restarting transmit queue\n"); - netif_wake_queue(dev); - priv->tx_full = 0; - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return IRQ_HANDLED; -} - -static unsigned int nuport_mac_has_work(struct nuport_mac_priv *priv) -{ - unsigned int i; - - for (i = 0; i < RX_RING_SIZE; i++) - if (priv->rx_skb[i]) - return 1; - - return 0; -} - -static irqreturn_t nuport_mac_rx_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *)dev_id; - struct nuport_mac_priv *priv = netdev_priv(dev); - unsigned long flags; - int ret; - - spin_lock_irqsave(&priv->lock, flags); - if (!priv->rx_full) { - priv->pkt_len[priv->dma_rx] = nuport_mac_readl(RX_ACT_BYTES) - 4; - priv->irq_rxskb[priv->dma_rx] = 0; - priv->dma_rx++; - - if (priv->dma_rx >= RX_RING_SIZE) - priv->dma_rx = 0; - } else - priv->rx_full = 0; - - if (priv->irq_rxskb[priv->dma_rx] == 1) { - ret = nuport_mac_start_rx_dma(priv, priv->rx_skb[priv->dma_rx]); - if (ret) - netdev_err(dev, "failed to start rx dma\n"); - } else { - priv->rx_full = 1; - netdev_dbg(dev, "RX ring full\n"); - } - - if (likely(nuport_mac_has_work(priv))) { - /* find a way to disable DMA rx irq */ - nuport_mac_disable_rx_dma(priv); - napi_schedule(&priv->napi); - } - spin_unlock_irqrestore(&priv->lock, flags); - - return IRQ_HANDLED; -} - -/* Process received packets in tasklet */ -static int nuport_mac_rx(struct net_device *dev, int limit) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - struct sk_buff *skb; - int len, status; - int count = 0; - - while (count < limit && !priv->irq_rxskb[priv->cur_rx]) { - skb = priv->rx_skb[priv->cur_rx]; - len = priv->pkt_len[priv->cur_rx]; - - /* Remove 2 bytes added by RX buffer shifting */ - len = len - priv->buffer_shifting_len; - skb->data = skb->data + priv->buffer_shifting_len; - - /* Get packet status */ - status = get_unaligned((u32 *) (skb->data + len)); - - dma_unmap_single(&priv->pdev->dev, priv->rx_addr, skb->len, - DMA_FROM_DEVICE); - - /* packet filter failed */ - if (!(status & (1 << 30))) { - dev_kfree_skb_irq(skb); - goto exit; - } - - /* missed frame */ - if (status & (1 << 31)) { - dev->stats.rx_missed_errors++; - dev_kfree_skb_irq(skb); - goto exit; - } - - /* Not ethernet type */ - if ((!(status & (1 << 18))) || (status & ERROR_FILTER_MASK)) - dev->stats.rx_errors++; - - if (len > MAX_ETH_FRAME_SIZE) { - dev_kfree_skb_irq(skb); - goto exit; - } else - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, dev); - dev->stats.rx_packets++; - - if (status & (1 << 29)) - skb->pkt_type = PACKET_OTHERHOST; - if (status & (1 << 27)) - skb->pkt_type = PACKET_MULTICAST; - if (status & (1 << 28)) - skb->pkt_type = PACKET_BROADCAST; - - skb->ip_summed = CHECKSUM_UNNECESSARY; - - /* Pass the received packet to network layer */ - status = netif_receive_skb(skb); - if (status != NET_RX_DROP) - dev->stats.rx_bytes += len - 4; /* Without CRC */ - else - dev->stats.rx_dropped++; - - dev->last_rx = jiffies; - -exit: - skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE); - if (!skb) - goto out; - - skb_reserve(skb, RX_SKB_HEADROOM); - priv->rx_skb[priv->cur_rx] = skb; - priv->irq_rxskb[priv->cur_rx] = 1; - priv->cur_rx++; - - if (priv->cur_rx >= RX_RING_SIZE) - priv->cur_rx = 0; - count++; - } -out: - return count; -} - -static int nuport_mac_poll(struct napi_struct *napi, int budget) -{ - struct nuport_mac_priv *priv = - container_of(napi, struct nuport_mac_priv, napi); - struct net_device *dev = priv->dev; - int work_done; - - work_done = nuport_mac_rx(dev, budget); - - if (work_done < budget) { - napi_complete(napi); - nuport_mac_enable_rx_dma(priv); - } - - return work_done; -} - -static void nuport_mac_init_tx_ring(struct nuport_mac_priv *priv) -{ - int i; - - priv->cur_tx = priv->dma_tx = priv->tx_full = 0; - for (i = 0; i < TX_RING_SIZE; i++) { - priv->tx_skb[i] = NULL; - priv->valid_txskb[i] = 0; - } - priv->first_pkt = 1; -} - -static int nuport_mac_init_rx_ring(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - struct sk_buff *skb; - int i; - - priv->cur_rx = priv->dma_rx = priv->rx_full = 0; - - for (i = 0; i < RX_RING_SIZE; i++) { - skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE); - if (!skb) - return -ENOMEM; - skb_reserve(skb, RX_SKB_HEADROOM); - priv->rx_skb[i] = skb; - priv->irq_rxskb[i] = 1; - } - - return 0; -} - -static void nuport_mac_free_rx_ring(struct nuport_mac_priv *priv) -{ - int i; - - for (i = 0; i < RX_RING_SIZE; i++) { - if (!priv->rx_skb[i]) - continue; - - dev_kfree_skb(priv->rx_skb[i]); - priv->rx_skb[i] = NULL; - } - - if (priv->rx_addr) - dma_unmap_single(&priv->pdev->dev, priv->rx_addr, RX_ALLOC_SIZE, - DMA_TO_DEVICE); -} - -static void nuport_mac_read_mac_address(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - int i; - - for (i = 0; i < 4; i++) - dev->dev_addr[i] = nuport_mac_readb(MAC_ADDR_LOW_REG + i); - dev->dev_addr[4] = nuport_mac_readb(MAC_ADDR_HIGH_REG); - dev->dev_addr[5] = nuport_mac_readb(MAC_ADDR_HIGH_REG + 1); - - if (!is_valid_ether_addr(dev->dev_addr)) { - dev_info(&priv->pdev->dev, "using random address\n"); - random_ether_addr(dev->dev_addr); - } -} - -static int nuport_mac_change_mac_address(struct net_device *dev, void *mac_addr) -{ - struct sockaddr *addr = mac_addr; - struct nuport_mac_priv *priv = netdev_priv(dev); - unsigned long *temp = (unsigned long *)dev->dev_addr; - u32 high, low; - - if (netif_running(dev)) - return -EBUSY; - - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - - spin_lock_irq(&priv->lock); - - nuport_mac_writel(*temp, MAC_ADDR_LOW_REG); - temp = (unsigned long *)(dev->dev_addr + 4); - nuport_mac_writel(*temp, MAC_ADDR_HIGH_REG); - - low = nuport_mac_readl(MAC_ADDR_LOW_REG); - high = nuport_mac_readl(MAC_ADDR_HIGH_REG); - - spin_unlock_irq(&priv->lock); - - return 0; -} - -static int nuport_mac_open(struct net_device *dev) -{ - int ret; - struct nuport_mac_priv *priv = netdev_priv(dev); - unsigned long flags; - u32 reg = 0; - - ret = clk_enable(priv->emac_clk); - if (ret) { - netdev_err(dev, "failed to enable EMAC clock\n"); - return ret; - } - - /* Set MAC into full duplex mode by default */ - reg |= RX_ENABLE | TX_ENABLE; - reg |= DEFER_CHECK | STRIP_PAD | DRTRY_DISABLE; - reg |= FULL_DUPLEX | HBD_DISABLE; - nuport_mac_writel(reg, CTRL_REG); - - /* set mac address in hardware in case it was not already */ - nuport_mac_change_mac_address(dev, dev->dev_addr); - - ret = request_irq(priv->link_irq, &nuport_mac_link_interrupt, - 0, dev->name, dev); - if (ret) { - netdev_err(dev, "unable to request link interrupt\n"); - goto out_emac_clk; - } - - ret = request_irq(priv->tx_irq, &nuport_mac_tx_interrupt, - 0, dev->name, dev); - if (ret) { - netdev_err(dev, "unable to request rx interrupt\n"); - goto out_link_irq; - } - - /* Enable link interrupt monitoring for our PHY address */ - reg = LINK_INT_EN | (priv->phydev->addr << LINK_PHY_ADDR_SHIFT); - /* MII_BMSR register to be watched */ - reg |= (1 << LINK_PHY_REG_SHIFT); - /* BMSR_STATUS to be watched in particular */ - reg |= (2 << LINK_BIT_UP_SHIFT); - - spin_lock_irqsave(&priv->lock, flags); - nuport_mac_writel(reg, LINK_INT_CSR); - nuport_mac_writel(LINK_POLL_MASK, LINK_INT_POLL_TIME); - spin_unlock_irqrestore(&priv->lock, flags); - - phy_start(priv->phydev); - - ret = request_irq(priv->rx_irq, &nuport_mac_rx_interrupt, - 0, dev->name, dev); - if (ret) { - netdev_err(dev, "unable to request tx interrupt\n"); - goto out_tx_irq; - } - - netif_start_queue(dev); - - nuport_mac_init_tx_ring(priv); - - ret = nuport_mac_init_rx_ring(dev); - if (ret) { - netdev_err(dev, "rx ring init failed\n"); - goto out_rx_skb; - } - - nuport_mac_reset_tx_dma(priv); - nuport_mac_reset_rx_dma(priv); - - /* Start RX DMA */ - spin_lock_irqsave(&priv->lock, flags); - ret = nuport_mac_start_rx_dma(priv, priv->rx_skb[0]); - spin_unlock_irqrestore(&priv->lock, flags); - - napi_enable(&priv->napi); - - return ret; - -out_rx_skb: - nuport_mac_free_rx_ring(priv); - free_irq(priv->rx_irq, dev); -out_tx_irq: - free_irq(priv->tx_irq, dev); -out_link_irq: - free_irq(priv->link_irq, dev); -out_emac_clk: - clk_disable(priv->emac_clk); - return ret; -} - -static int nuport_mac_close(struct net_device *dev) -{ - u32 reg; - struct nuport_mac_priv *priv = netdev_priv(dev); - - spin_lock_irq(&priv->lock); - reg = nuport_mac_readl(CTRL_REG); - reg &= ~(RX_ENABLE | TX_ENABLE); - nuport_mac_writel(reg, CTRL_REG); - - napi_disable(&priv->napi); - netif_stop_queue(dev); - - free_irq(priv->link_irq, dev); - /* disable PHY polling */ - nuport_mac_writel(0, LINK_INT_CSR); - nuport_mac_writel(0, LINK_INT_POLL_TIME); - phy_stop(priv->phydev); - - free_irq(priv->tx_irq, dev); - free_irq(priv->rx_irq, dev); - spin_unlock_irq(&priv->lock); - - nuport_mac_free_rx_ring(priv); - - clk_disable(priv->emac_clk); - - return 0; -} - -static void nuport_mac_tx_timeout(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - unsigned int i; - - netdev_warn(dev, "transmit timeout, attempting recovery\n"); - - netdev_info(dev, "TX DMA regs\n"); - for (i = 0; i < DMA_CHAN_WIDTH; i += 4) - netdev_info(dev, "[%02x]: 0x%08x\n", i, nuport_mac_readl(TX_DMA_BASE + i)); - netdev_info(dev, "RX DMA regs\n"); - for (i = 0; i < DMA_CHAN_WIDTH; i += 4) - netdev_info(dev, "[%02x]: 0x%08x\n", i, nuport_mac_readl(RX_DMA_BASE + i)); - - nuport_mac_init_tx_ring(priv); - nuport_mac_reset_tx_dma(priv); - - netif_wake_queue(dev); -} - -static int nuport_mac_mii_probe(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - struct phy_device *phydev = NULL; - int ret; - - ret = clk_enable(priv->ephy_clk); - if (ret) { - netdev_err(dev, "unable to enable ePHY clk\n"); - return ret; - } - - phydev = phy_find_first(priv->mii_bus); - if (!phydev) { - netdev_err(dev, "no PHYs found\n"); - ret = -ENODEV; - goto out; - } - - phydev = of_phy_connect(dev, priv->phy_node, - nuport_mac_adjust_link, 0, - priv->phy_interface); - if (IS_ERR(phydev)) { - netdev_err(dev, "could not attach PHY\n"); - ret = PTR_ERR(phydev); - goto out; - } - - phydev->supported &= PHY_BASIC_FEATURES; - phydev->advertising = phydev->supported; - priv->phydev = phydev; - priv->old_link = 1; - priv->old_duplex = DUPLEX_FULL; - - dev_info(&priv->pdev->dev, "attached PHY driver [%s] " - "(mii_bus:phy_addr=%d)\n", - phydev->drv->name, phydev->addr); - - return 0; - -out: - /* disable the Ethernet PHY clock for the moment */ - clk_disable(priv->ephy_clk); - - return ret; -} - -static void nuport_mac_ethtool_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strncpy(info->driver, "nuport-mac", sizeof(info->driver)); - strncpy(info->version, "0.1", sizeof(info->version)); - strncpy(info->fw_version, "N/A", sizeof(info->fw_version)); - strncpy(info->bus_info, "internal", sizeof(info->bus_info)); - info->n_stats = 0; - info->testinfo_len = 0; - info->regdump_len = 0; - info->eedump_len = 0; -} - -static int nuport_mac_ethtool_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - - if (priv->phydev) - return phy_ethtool_gset(priv->phydev, cmd); - - return -EINVAL; -} - -static int nuport_mac_ethtool_set_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - - if (priv->phydev) - return phy_ethtool_sset(priv->phydev, cmd); - - return -EINVAL; -} - -static void nuport_mac_set_msglevel(struct net_device *dev, u32 msg_level) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - - priv->msg_level = msg_level; -} - -static u32 nuport_mac_get_msglevel(struct net_device *dev) -{ - struct nuport_mac_priv *priv = netdev_priv(dev); - - return priv->msg_level; -} - -static const struct ethtool_ops nuport_mac_ethtool_ops = { - .get_drvinfo = nuport_mac_ethtool_drvinfo, - .get_link = ethtool_op_get_link, - .get_settings = nuport_mac_ethtool_get_settings, - .set_settings = nuport_mac_ethtool_set_settings, - .set_msglevel = nuport_mac_set_msglevel, - .get_msglevel = nuport_mac_get_msglevel, -}; - -static const struct net_device_ops nuport_mac_ops = { - .ndo_open = nuport_mac_open, - .ndo_stop = nuport_mac_close, - .ndo_start_xmit = nuport_mac_start_xmit, - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = nuport_mac_change_mac_address, - .ndo_tx_timeout = nuport_mac_tx_timeout, -}; - -static int __init nuport_mac_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct nuport_mac_priv *priv = NULL; - struct resource *regs, *dma; - int ret = 0; - int rx_irq, tx_irq, link_irq; - int i; - const unsigned int *intspec; - - dev = alloc_etherdev(sizeof(struct nuport_mac_priv)); - if (!dev) { - dev_err(&pdev->dev, "no memory for net_device\n"); - return -ENOMEM; - } - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dma = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!regs || !dma) { - dev_err(&pdev->dev, "failed to get regs resources\n"); - ret = -ENODEV; - goto out; - } - - rx_irq = platform_get_irq(pdev, 0); - tx_irq = platform_get_irq(pdev, 1); - link_irq = platform_get_irq(pdev, 2); - if (rx_irq < 0 || tx_irq < 0 || link_irq < 0) { - ret = -ENODEV; - goto out; - } - - platform_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - priv = netdev_priv(dev); - priv->pdev = pdev; - priv->dev = dev; - spin_lock_init(&priv->lock); - - intspec = of_get_property(pdev->dev.of_node, - "nuport-mac,buffer-shifting", NULL); - if (!intspec) - priv->buffer_shifting_len = 0; - else - priv->buffer_shifting_len = 2; - - priv->mac_base = devm_request_and_ioremap(&pdev->dev, regs); - if (!priv->mac_base) { - dev_err(&pdev->dev, "failed to remap regs\n"); - ret = -ENOMEM; - goto out_platform; - } - - priv->dma_base = devm_request_and_ioremap(&pdev->dev, dma); - if (!priv->dma_base) { - dev_err(&pdev->dev, "failed to remap dma-regs\n"); - ret = -ENOMEM; - goto out_platform; - } - - priv->emac_clk = clk_get(&pdev->dev, "emac"); - if (IS_ERR_OR_NULL(priv->emac_clk)) { - dev_err(&pdev->dev, "failed to get emac clk\n"); - ret = PTR_ERR(priv->emac_clk); - goto out_platform; - } - - priv->ephy_clk = clk_get(&pdev->dev, "ephy"); - if (IS_ERR_OR_NULL(priv->ephy_clk)) { - dev_err(&pdev->dev, "failed to get ephy clk\n"); - ret = PTR_ERR(priv->ephy_clk); - goto out_platform; - } - - priv->link_irq = link_irq; - priv->rx_irq = rx_irq; - priv->tx_irq = tx_irq; - priv->msg_level = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK; - dev->netdev_ops = &nuport_mac_ops; - dev->ethtool_ops = &nuport_mac_ethtool_ops; - dev->watchdog_timeo = HZ; - dev->flags = IFF_BROADCAST; /* Supports Broadcast */ - dev->tx_queue_len = TX_RING_SIZE / 2; - - netif_napi_add(dev, &priv->napi, nuport_mac_poll, 64); - - priv->phy_node = of_parse_phandle(pdev->dev.of_node, "phy", 0); - if (!priv->phy_node) { - dev_err(&pdev->dev, "no associated PHY\n"); - ret = -ENODEV; - goto out; - } - - priv->phy_interface = of_get_phy_mode(pdev->dev.of_node); - if (priv->phy_interface < 0) { - dev_err(&pdev->dev, "invalid PHY mode\n"); - ret = -EINVAL; - goto out; - } - - priv->mii_bus = mdiobus_alloc(); - if (!priv->mii_bus) { - dev_err(&pdev->dev, "mii bus allocation failed\n"); - goto out; - } - - priv->mii_bus->priv = dev; - priv->mii_bus->read = nuport_mac_mii_read; - priv->mii_bus->write = nuport_mac_mii_write; - priv->mii_bus->reset = nuport_mac_mii_reset; - priv->mii_bus->name = "nuport-mac-mii"; - priv->mii_bus->phy_mask = (1 << 0); - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); - priv->mii_bus->irq = kzalloc(PHY_MAX_ADDR * sizeof(int), GFP_KERNEL); - if (!priv->mii_bus->irq) { - dev_err(&pdev->dev, "failed to allocate mii_bus irqs\n"); - ret = -ENOMEM; - goto out_mdio; - } - - /* We support PHY interrupts routed back to the MAC */ - for (i = 0; i < PHY_MAX_ADDR; i++) - priv->mii_bus->irq[i] = PHY_IGNORE_INTERRUPT; - - ret = of_mdiobus_register(priv->mii_bus, pdev->dev.of_node); - if (ret) { - dev_err(&pdev->dev, "failed to register mii_bus\n"); - goto out_mdio_irq; - } - - ret = nuport_mac_mii_probe(dev); - if (ret) { - dev_err(&pdev->dev, "failed to probe MII bus\n"); - goto out_mdio_unregister; - } - - ret = register_netdev(dev); - if (ret) { - dev_err(&pdev->dev, "failed to register net_device\n"); - goto out_mdio_probe; - } - - /* read existing mac address */ - nuport_mac_read_mac_address(dev); - - dev_info(&pdev->dev, "registered (MAC: %pM)\n", dev->dev_addr); - - return ret; - -out_mdio_probe: - phy_disconnect(priv->phydev); -out_mdio_unregister: - mdiobus_unregister(priv->mii_bus); -out_mdio_irq: - kfree(priv->mii_bus->irq); -out_mdio: - mdiobus_free(priv->mii_bus); -out_platform: - platform_set_drvdata(pdev, NULL); -out: - clk_put(priv->ephy_clk); - clk_put(priv->emac_clk); - free_netdev(dev); - platform_set_drvdata(pdev, NULL); - return ret; -} - -static int nuport_mac_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct nuport_mac_priv *priv = netdev_priv(dev); - - unregister_netdev(dev); - phy_disconnect(priv->phydev); - mdiobus_unregister(priv->mii_bus); - kfree(priv->mii_bus->irq); - mdiobus_free(priv->mii_bus); - clk_put(priv->ephy_clk); - clk_put(priv->emac_clk); - free_netdev(dev); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct of_device_id nuport_eth_ids[] __initdata = { - {.compatible = "moschip,nuport-mac",}, - { /* sentinel */ }, -}; - -static struct platform_driver nuport_eth_driver = { - .driver = { - .name = "nuport-mac", - .owner = THIS_MODULE, - .of_match_table = nuport_eth_ids, - }, - .probe = nuport_mac_probe, - .remove = __devexit_p(nuport_mac_remove), -}; - -module_platform_driver(nuport_eth_driver); - -MODULE_AUTHOR("Moschip Semiconductors Ltd."); -MODULE_DESCRIPTION("Moschip MCS8140 Ethernet MAC driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/mcs814x/files-3.3/drivers/net/phy/mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/net/phy/mcs814x.c deleted file mode 100644 index e92176e3be..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/net/phy/mcs814x.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Driver for Moschip MCS814x internal PHY - * - * Copyright (c) 2012 Florian Fainelli <florian@openwrt.org> - * - * 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -MODULE_DESCRIPTION("Moschip MCS814x PHY driver"); -MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); -MODULE_LICENSE("GPL"); - -/* Nothing special about this PHY but its OUI (O) */ -static struct phy_driver mcs8140_driver = { - .phy_id = 0, - .name = "Moschip MCS8140", - .phy_id_mask = 0x02, - .features = PHY_BASIC_FEATURES, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init mcs814x_phy_init(void) -{ - return phy_driver_register(&mcs8140_driver); -} - -static void __exit mcs814x_phy_exit(void) -{ - phy_driver_unregister(&mcs8140_driver); -} - -module_init(mcs814x_phy_init); -module_exit(mcs814x_phy_exit); - -static struct mdio_device_id __maybe_unused mcs814x_phy_tbl[] = { - { 0x0, 0x0ffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, mcs814x_phy_tbl); diff --git a/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c deleted file mode 100644 index 183155e372..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * MCS814X EHCI Host Controller Driver - * - * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#include <linux/platform_device.h> -#include <linux/of.h> - -#define MCS814X_EHCI_CAPS_OFFSET 0x68 - -static int mcs814x_ehci_init(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval = 0; - - ehci->caps = hcd->regs + MCS814X_EHCI_CAPS_OFFSET; - ehci->regs = hcd->regs - + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - ehci_reset(ehci); - - retval = ehci_init(hcd); - if (retval) { - pr_err("ehci_init failed\n"); - return retval; - } - - ehci_port_power(ehci, 0); - - return retval; -} - -static const struct hc_driver mcs814x_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "MCS814X EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = mcs814x_ehci_init, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .get_frame_number = ehci_get_frame, - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#if defined(CONFIG_PM) - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int mcs814x_ehci_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - const struct hc_driver *driver = &mcs814x_ehci_hc_driver; - struct resource *res; - int irq; - int retval; - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no IRQ. Check %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - irq = res->start; - - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) { - retval = -ENOMEM; - goto fail_create_hcd; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto fail_request_resource; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - driver->description)) { - dev_dbg(&pdev->dev, "controller already in use\n"); - retval = -EBUSY; - goto fail_request_resource; - } - - hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); - if (hcd->regs == NULL) { - dev_dbg(&pdev->dev, "error mapping memory\n"); - retval = -EFAULT; - goto fail_ioremap; - } - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval) - goto fail_add_hcd; - - dev_info(&pdev->dev, "added MCS814X EHCI driver\n"); - - return retval; - -fail_add_hcd: - iounmap(hcd->regs); -fail_ioremap: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -fail_request_resource: - usb_put_hcd(hcd); -fail_create_hcd: - dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); - return retval; -} - -static int mcs814x_ehci_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - - return 0; -} - -MODULE_ALIAS("platform:mcs814x-ehci"); - -static const struct of_device_id mcs814x_ehci_id[] = { - { .compatible = "moschip,mcs814x-ehci" }, - { .compatible = "usb-ehci" }, - { /* sentinel */ }, -}; - -static struct platform_driver mcs814x_ehci_driver = { - .probe = mcs814x_ehci_probe, - .remove = mcs814x_ehci_remove, - .driver = { - .name = "mcs814x-ehci", - .of_match_table = mcs814x_ehci_id, - }, -}; diff --git a/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c deleted file mode 100644 index ef4cb5143e..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> - * (C) Copyright 2002 Hewlett-Packard Company - * - * Bus Glue for Moschip MCS814x. - * - * Written by Christopher Hoover <ch@hpl.hp.com> - * Based on fragments of previous driver by Russell King et al. - * - * Modified for LH7A404 from ohci-sa1111.c - * by Durgesh Pattamatta <pattamattad@sharpsec.com> - * - * Modified for pxa27x from ohci-lh7a404.c - * by Nick Bane <nick@cecomputing.co.uk> 26-8-2004 - * - * Modified for mcs814x from ohci-mcs814x.c - * by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006 - * Based on an earlier driver by Ray Lehtiniemi - * - * This file is licenced under the GPL. - */ - -#include <linux/device.h> -#include <linux/signal.h> -#include <linux/platform_device.h> -#include <linux/of.h> - -static int usb_hcd_mcs814x_probe(const struct hc_driver *driver, - struct platform_device *pdev) -{ - int retval; - struct usb_hcd *hcd; - - if (pdev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - return -ENOMEM; - } - - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - - hcd = usb_create_hcd(driver, &pdev->dev, "mcs814x"); - if (hcd == NULL) - return -ENOMEM; - - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - usb_put_hcd(hcd); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (hcd->regs == NULL) { - pr_debug("ioremap failed"); - retval = -ENOMEM; - goto err2; - } - - ohci_hcd_init(hcd_to_ohci(hcd)); - - retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED); - if (retval == 0) - return retval; - - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - - return retval; -} - -static void usb_hcd_mcs814x_remove(struct usb_hcd *hcd, - struct platform_device *pdev) -{ - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -static int __devinit ohci_mcs814x_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ret = ohci_init(ohci); - if (ret < 0) - return ret; - - ret = ohci_run(ohci); - if (ret < 0) { - ohci_err(ohci, "can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static struct hc_driver ohci_mcs814x_hc_driver = { - .description = hcd_name, - .product_desc = "MCS814X OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - .start = ohci_mcs814x_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - .get_frame_number = ohci_get_frame, - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -extern int usb_disabled(void); - -static int ohci_hcd_mcs814x_drv_probe(struct platform_device *pdev) -{ - int ret; - - ret = -ENODEV; - if (!usb_disabled()) - ret = usb_hcd_mcs814x_probe(&ohci_mcs814x_hc_driver, pdev); - - return ret; -} - -static int ohci_hcd_mcs814x_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_hcd_mcs814x_remove(hcd, pdev); - - return 0; -} - -#ifdef CONFIG_PM -static int ohci_hcd_mcs814x_drv_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - - hcd->state = HC_STATE_SUSPENDED; - - return 0; -} - -static int ohci_hcd_mcs814x_drv_resume(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int status; - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - - ohci_finish_controller_resume(hcd); - return 0; -} -#endif - -static const struct of_device_id mcs814x_ohci_id[] = { - { .compatible = "moschip,mcs814x-ohci" }, - { .compatible = "ohci-le" }, - { /* sentinel */ }, -}; - -static struct platform_driver ohci_hcd_mcs814x_driver = { - .probe = ohci_hcd_mcs814x_drv_probe, - .remove = ohci_hcd_mcs814x_drv_remove, - .shutdown = usb_hcd_platform_shutdown, -#ifdef CONFIG_PM - .suspend = ohci_hcd_mcs814x_drv_suspend, - .resume = ohci_hcd_mcs814x_drv_resume, -#endif - .driver = { - .name = "mcs814x-ohci", - .owner = THIS_MODULE, - .of_match_table = mcs814x_ohci_id, - }, -}; - -MODULE_ALIAS("platform:mcs814x-ohci"); diff --git a/target/linux/mcs814x/files-3.3/drivers/watchdog/mcs814x_wdt.c b/target/linux/mcs814x/files-3.3/drivers/watchdog/mcs814x_wdt.c deleted file mode 100644 index ca69e8f955..0000000000 --- a/target/linux/mcs814x/files-3.3/drivers/watchdog/mcs814x_wdt.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Moschip MCS814x Watchdog driver - * - * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/miscdevice.h> -#include <linux/watchdog.h> -#include <linux/io.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/of.h> - -#define WDT_COUNT 0x00 -#define WDT_CTRL 0x04 -#define WDT_CTRL_EN 0x1 - -/* watchdog frequency */ -#define WDT_MAX_VALUE (0xffffffff) - -struct mcs814x_wdt { - void __iomem *regs; - spinlock_t lock; - struct watchdog_device wdt_dev; - struct clk *clk; -}; - -static int mcs814x_wdt_start(struct watchdog_device *dev) -{ - struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev); - u32 reg; - - spin_lock(&wdt->lock); - reg = readl_relaxed(wdt->regs + WDT_CTRL); - reg |= WDT_CTRL_EN; - writel_relaxed(reg, wdt->regs + WDT_CTRL); - spin_unlock(&wdt->lock); - - return 0; -} - -static int mcs814x_wdt_stop(struct watchdog_device *dev) -{ - struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev); - u32 reg; - - spin_lock(&wdt->lock); - reg = readl_relaxed(wdt->regs + WDT_CTRL); - reg &= ~WDT_CTRL_EN; - writel_relaxed(reg, wdt->regs + WDT_CTRL); - spin_unlock(&wdt->lock); - - return 0; -} - -static int mcs814x_wdt_set_timeout(struct watchdog_device *dev, - unsigned int new_timeout) -{ - struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev); - - spin_lock(&wdt->lock); - /* watchdog counts upward and rollover (0xfffffff -> 0) - * triggers the reboot - */ - writel_relaxed(WDT_MAX_VALUE - (new_timeout * clk_get_rate(wdt->clk)), - wdt->regs + WDT_COUNT); - spin_unlock(&wdt->lock); - - return 0; -} - -static int mcs814x_wdt_ping(struct watchdog_device *dev) -{ - /* restart the watchdog */ - mcs814x_wdt_stop(dev); - mcs814x_wdt_set_timeout(dev, dev->timeout); - mcs814x_wdt_start(dev); - - return 0; -} - -static const struct watchdog_info mcs814x_wdt_ident = { - .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | - WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, - .identity = "MCS814x Watchdog", -}; - -static struct watchdog_ops mcs814x_wdt_ops = { - .owner = THIS_MODULE, - .start = mcs814x_wdt_start, - .stop = mcs814x_wdt_stop, - .set_timeout = mcs814x_wdt_set_timeout, - .ping = mcs814x_wdt_ping, -}; - -static int __devinit mcs814x_wdt_probe(struct platform_device *pdev) -{ - struct resource *res; - struct mcs814x_wdt *wdt; - int ret; - struct clk *clk; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - clk = clk_get(NULL, "wdt"); - if (IS_ERR_OR_NULL(clk)) { - dev_err(&pdev->dev, "failed to get watchdog clock\n"); - return PTR_ERR(clk); - } - - wdt = kzalloc(sizeof(*wdt), GFP_KERNEL); - if (!wdt) { - ret = -ENOMEM; - goto out_clk; - } - - spin_lock_init(&wdt->lock); - wdt->clk = clk; - wdt->wdt_dev.info = &mcs814x_wdt_ident; - wdt->wdt_dev.ops = &mcs814x_wdt_ops; - wdt->wdt_dev.min_timeout = 1; - /* approximately 10995 secs */ - wdt->wdt_dev.max_timeout = (WDT_MAX_VALUE / clk_get_rate(clk)); - - platform_set_drvdata(pdev, wdt); - - /* only ioremap registers, because the register is shared */ - wdt->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!wdt->regs) { - ret = -ENOMEM; - goto out; - } - - watchdog_set_drvdata(&wdt->wdt_dev, wdt); - - ret = watchdog_register_device(&wdt->wdt_dev); - if (ret) { - dev_err(&pdev->dev, "cannot register watchdog: %d\n", ret); - goto out; - } - - dev_info(&pdev->dev, "registered\n"); - return 0; - -out: - platform_set_drvdata(pdev, NULL); - kfree(wdt); -out_clk: - clk_put(clk); - return ret; -} - -static int __devexit mcs814x_wdt_remove(struct platform_device *pdev) -{ - struct mcs814x_wdt *wdt = platform_get_drvdata(pdev); - - clk_put(wdt->clk); - watchdog_unregister_device(&wdt->wdt_dev); - watchdog_set_drvdata(&wdt->wdt_dev, NULL); - kfree(wdt); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id mcs814x_wdt_ids[] = { - { .compatible = "moschip,mcs814x-wdt", }, - { /* sentinel */ }, -}; - -static struct platform_driver mcs814x_wdt_driver = { - .driver = { - .name = "mcs814x-wdt", - .owner = THIS_MODULE, - .of_match_table = mcs814x_wdt_ids, - }, - .probe = mcs814x_wdt_probe, - .remove = __devexit_p(mcs814x_wdt_remove), -}; - -module_platform_driver(mcs814x_wdt_driver); - -MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); -MODULE_DESCRIPTION("Moschip MCS814x Watchdog driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -MODULE_ALIAS("platform:mcs814x-wdt"); |