diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-01 13:05:40 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-01 13:05:40 -0800 |
commit | 13dda80e48439b446d0bc9bab34b91484bc8f533 (patch) | |
tree | e8037122d65fe2a5dd8f633a7648b2597640a2ce /drivers/net | |
parent | 379e3a820da171cb1d97e8dccd736a69cebfb7c0 (diff) | |
parent | 5f19daa16ffca55db5b0253eba2bd0f71ee7f7f4 (diff) | |
download | linux-13dda80e48439b446d0bc9bab34b91484bc8f533.tar.bz2 |
Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci
* 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci: (40 commits)
DaVinci DM365: Adding support for SPI EEPROM
DaVinci DM365: Adding DM365 SPI support
DaVinci DM355: Modifications to DM355 SPI support
DaVinci: SPI: Adding header file for SPI support.
davinci: dm646x: CDCE clocks: davinci_clk converted to clk_lookup
davinci: clkdev cleanup: remove clk_lookup wrapper, use clkdev_add_table()
DaVinci: DM365: Voice codec support for the DM365 SoC
davinci: clock: let clk->set_rate function sleep
Add SDA and SCL pin numbers to i2c platform data
davinci: da8xx/omap-l1xx: Add EDMA platform data for da850/omap-l138
davinci: build list of unused EDMA events dynamically
davinci: Fix edma_alloc_channel api for EDMA_CHANNEL_ANY case
davinci: Keep count of channel controllers on a platform
davinci: Correct return value of edma_alloc_channel api
davinci: add CDCE949 support on DM6467 EVM
davinci: add support for CDCE949 clock synthesizer
davinci: da850/omap-l138 EVM: register for suspend support
davinci: da850/omap-l138: add support for SoC suspend
davinci: add power management support
DaVinci: DM365: Changing default queue for DM365.
...
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/davinci_emac.c | 55 |
2 files changed, 37 insertions, 20 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dd9a09c72dff..18300625b05b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -920,7 +920,7 @@ config NET_NETX config TI_DAVINCI_EMAC tristate "TI DaVinci EMAC Support" - depends on ARM && ARCH_DAVINCI + depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) select PHYLIB help This driver supports TI's DaVinci Ethernet . diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 33c4fe26178c..1605bc225b0c 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -62,12 +62,11 @@ #include <linux/bitops.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/davinci_emac.h> #include <asm/irq.h> #include <asm/page.h> -#include <mach/emac.h> - static int debug_level; module_param(debug_level, int, 0); MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)"); @@ -465,6 +464,7 @@ struct emac_priv { void __iomem *ctrl_base; void __iomem *emac_ctrl_ram; u32 ctrl_ram_size; + u32 hw_ram_addr; struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; u32 link; /* 1=link on, 0=link off */ @@ -488,6 +488,9 @@ struct emac_priv { struct mii_bus *mii_bus; struct phy_device *phydev; spinlock_t lock; + /*platform specific members*/ + void (*int_enable) (void); + void (*int_disable) (void); }; /* clock frequency for EMAC */ @@ -495,11 +498,9 @@ static struct clk *emac_clk; static unsigned long emac_bus_frequency; static unsigned long mdio_max_freq; -/* EMAC internal utility function */ -static inline u32 emac_virt_to_phys(void __iomem *addr) -{ - return (u32 __force) io_v2p(addr); -} +#define emac_virt_to_phys(addr, priv) \ + (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \ + + priv->hw_ram_addr) /* Cache macros - Packet buffers would be from skb pool which is cached */ #define EMAC_VIRT_NOCACHE(addr) (addr) @@ -1002,6 +1003,8 @@ static void emac_int_disable(struct emac_priv *priv) emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0); emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0); /* NOTE: Rx Threshold and Misc interrupts are not disabled */ + if (priv->int_disable) + priv->int_disable(); local_irq_restore(flags); @@ -1021,6 +1024,9 @@ static void emac_int_disable(struct emac_priv *priv) static void emac_int_enable(struct emac_priv *priv) { if (priv->version == EMAC_VERSION_2) { + if (priv->int_enable) + priv->int_enable(); + emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff); emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff); @@ -1302,7 +1308,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) curr_bd = txch->active_queue_head; if (NULL == curr_bd) { emac_write(EMAC_TXCP(ch), - emac_virt_to_phys(txch->last_hw_bdprocessed)); + emac_virt_to_phys(txch->last_hw_bdprocessed, priv)); txch->no_active_pkts++; spin_unlock_irqrestore(&priv->tx_lock, flags); return 0; @@ -1312,7 +1318,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) while ((curr_bd) && ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && (pkts_processed < budget)) { - emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv)); txch->active_queue_head = curr_bd->next; if (frame_status & EMAC_CPPI_EOQ_BIT) { if (curr_bd->next) { /* misqueued packet */ @@ -1399,7 +1405,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) txch->active_queue_tail = curr_bd; if (1 != txch->queue_active) { emac_write(EMAC_TXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); txch->queue_active = 1; } ++txch->queue_reinit; @@ -1411,10 +1417,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) tail_bd->next = curr_bd; txch->active_queue_tail = curr_bd; tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = (int)emac_virt_to_phys(curr_bd); + tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv); frame_status = tail_bd->mode; if (frame_status & EMAC_CPPI_EOQ_BIT) { - emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_TXHDP(ch), + emac_virt_to_phys(curr_bd, priv)); frame_status &= ~(EMAC_CPPI_EOQ_BIT); tail_bd->mode = frame_status; ++txch->end_of_queue_add; @@ -1604,7 +1611,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) } /* populate the hardware descriptor */ - curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head); + curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, + priv); /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); curr_bd->off_b_len = rxch->buf_size; @@ -1879,7 +1887,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, rxch->active_queue_tail = curr_bd; if (0 != rxch->queue_active) { emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head)); + emac_virt_to_phys(rxch->active_queue_head, priv)); rxch->queue_active = 1; } } else { @@ -1890,11 +1898,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, rxch->active_queue_tail = curr_bd; tail_bd->next = curr_bd; tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = emac_virt_to_phys(curr_bd); + tail_bd->h_next = emac_virt_to_phys(curr_bd, priv); frame_status = tail_bd->mode; if (frame_status & EMAC_CPPI_EOQ_BIT) { emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); frame_status &= ~(EMAC_CPPI_EOQ_BIT); tail_bd->mode = frame_status; ++rxch->end_of_queue_add; @@ -1987,7 +1995,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) curr_pkt->num_bufs = 1; curr_pkt->pkt_length = (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK); - emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd)); + emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv)); ++rxch->processed_bd; last_bd = curr_bd; curr_bd = last_bd->next; @@ -1998,7 +2006,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) if (curr_bd) { ++rxch->mis_queued_packets; emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd)); + emac_virt_to_phys(curr_bd, priv)); } else { ++rxch->end_of_queue; rxch->queue_active = 0; @@ -2099,7 +2107,7 @@ static int emac_hw_enable(struct emac_priv *priv) emac_write(EMAC_RXINTMASKSET, BIT(ch)); rxch->queue_active = 1; emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head)); + emac_virt_to_phys(rxch->active_queue_head, priv)); } /* Enable MII */ @@ -2660,6 +2668,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->phy_mask = pdata->phy_mask; priv->rmii_en = pdata->rmii_en; priv->version = pdata->version; + priv->int_enable = pdata->interrupt_enable; + priv->int_disable = pdata->interrupt_disable; + emac_dev = &ndev->dev; /* Get EMAC platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2692,6 +2703,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->ctrl_ram_size = pdata->ctrl_ram_size; priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; + if (pdata->hw_ram_addr) + priv->hw_ram_addr = pdata->hw_ram_addr; + else + priv->hw_ram_addr = (u32 __force)res->start + + pdata->ctrl_ram_offset; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n"); |