mirror of https://gitee.com/openkylin/linux.git
NET: sa11x0-ir: containerize DMA data
Both the transmit and receive DMA store identical data: the skb, dma address, and the dma registers. Move this data into its own data structure. The following replacements were used: rxskb -> dma_rx.skb rxbuf_dma -> dma_rx.dma rxdma -> dma_rx.regs txskb -> dma_tx.skb txbuf_dma -> dma_tx.dma txdma -> dma_tx.regs Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
e556fdbde3
commit
885767ca4c
|
@ -43,6 +43,12 @@ static int power_level = 3;
|
||||||
static int tx_lpm;
|
static int tx_lpm;
|
||||||
static int max_rate = 4000000;
|
static int max_rate = 4000000;
|
||||||
|
|
||||||
|
struct sa1100_buf {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
dma_addr_t dma;
|
||||||
|
dma_regs_t *regs;
|
||||||
|
};
|
||||||
|
|
||||||
struct sa1100_irda {
|
struct sa1100_irda {
|
||||||
unsigned char hscr0;
|
unsigned char hscr0;
|
||||||
unsigned char utcr4;
|
unsigned char utcr4;
|
||||||
|
@ -52,12 +58,8 @@ struct sa1100_irda {
|
||||||
int speed;
|
int speed;
|
||||||
int newspeed;
|
int newspeed;
|
||||||
|
|
||||||
struct sk_buff *txskb;
|
struct sa1100_buf dma_rx;
|
||||||
struct sk_buff *rxskb;
|
struct sa1100_buf dma_tx;
|
||||||
dma_addr_t txbuf_dma;
|
|
||||||
dma_addr_t rxbuf_dma;
|
|
||||||
dma_regs_t *txdma;
|
|
||||||
dma_regs_t *rxdma;
|
|
||||||
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct irda_platform_data *pdata;
|
struct irda_platform_data *pdata;
|
||||||
|
@ -77,11 +79,11 @@ struct sa1100_irda {
|
||||||
*/
|
*/
|
||||||
static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
|
static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
|
||||||
{
|
{
|
||||||
if (si->rxskb)
|
if (si->dma_rx.skb)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
|
si->dma_rx.skb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
|
||||||
if (!si->rxskb) {
|
if (!si->dma_rx.skb) {
|
||||||
printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n");
|
printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -90,13 +92,13 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
|
||||||
* Align any IP headers that may be contained
|
* Align any IP headers that may be contained
|
||||||
* within the frame.
|
* within the frame.
|
||||||
*/
|
*/
|
||||||
skb_reserve(si->rxskb, 1);
|
skb_reserve(si->dma_rx.skb, 1);
|
||||||
|
|
||||||
si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
|
si->dma_rx.dma = dma_map_single(si->dev, si->dma_rx.skb->data,
|
||||||
HPSIR_MAX_RXLEN,
|
HPSIR_MAX_RXLEN,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
if (dma_mapping_error(si->dev, si->rxbuf_dma)) {
|
if (dma_mapping_error(si->dev, si->dma_rx.dma)) {
|
||||||
dev_kfree_skb_any(si->rxskb);
|
dev_kfree_skb_any(si->dma_rx.skb);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
|
||||||
*/
|
*/
|
||||||
static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
|
static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
|
||||||
{
|
{
|
||||||
if (!si->rxskb) {
|
if (!si->dma_rx.skb) {
|
||||||
printk(KERN_ERR "sa1100_ir: rx buffer went missing\n");
|
printk(KERN_ERR "sa1100_ir: rx buffer went missing\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -122,8 +124,8 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
|
||||||
/*
|
/*
|
||||||
* Enable the DMA, receiver and receive interrupt.
|
* Enable the DMA, receiver and receive interrupt.
|
||||||
*/
|
*/
|
||||||
sa1100_clear_dma(si->rxdma);
|
sa1100_clear_dma(si->dma_rx.regs);
|
||||||
sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN);
|
sa1100_start_dma(si->dma_rx.regs, si->dma_rx.dma, HPSIR_MAX_RXLEN);
|
||||||
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE;
|
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +146,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
|
||||||
* Stop the receive DMA.
|
* Stop the receive DMA.
|
||||||
*/
|
*/
|
||||||
if (IS_FIR(si))
|
if (IS_FIR(si))
|
||||||
sa1100_stop_dma(si->rxdma);
|
sa1100_stop_dma(si->dma_rx.regs);
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
@ -280,8 +282,8 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
|
||||||
/*
|
/*
|
||||||
* Stop all DMA activity.
|
* Stop all DMA activity.
|
||||||
*/
|
*/
|
||||||
sa1100_stop_dma(si->rxdma);
|
sa1100_stop_dma(si->dma_rx.regs);
|
||||||
sa1100_stop_dma(si->txdma);
|
sa1100_stop_dma(si->dma_tx.regs);
|
||||||
|
|
||||||
/* Disable the port. */
|
/* Disable the port. */
|
||||||
Ser2UTCR3 = 0;
|
Ser2UTCR3 = 0;
|
||||||
|
@ -460,7 +462,7 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev)
|
||||||
|
|
||||||
static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
|
static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = si->rxskb;
|
struct sk_buff *skb = si->dma_rx.skb;
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
unsigned int len, stat, data;
|
unsigned int len, stat, data;
|
||||||
|
|
||||||
|
@ -472,11 +474,11 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
|
||||||
/*
|
/*
|
||||||
* Get the current data position.
|
* Get the current data position.
|
||||||
*/
|
*/
|
||||||
dma_addr = sa1100_get_dma_pos(si->rxdma);
|
dma_addr = sa1100_get_dma_pos(si->dma_rx.regs);
|
||||||
len = dma_addr - si->rxbuf_dma;
|
len = dma_addr - si->dma_rx.dma;
|
||||||
if (len > HPSIR_MAX_RXLEN)
|
if (len > HPSIR_MAX_RXLEN)
|
||||||
len = HPSIR_MAX_RXLEN;
|
len = HPSIR_MAX_RXLEN;
|
||||||
dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE);
|
dma_unmap_single(si->dev, si->dma_rx.dma, len, DMA_FROM_DEVICE);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
|
@ -504,7 +506,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
|
||||||
} while (Ser2HSSR0 & HSSR0_EIF);
|
} while (Ser2HSSR0 & HSSR0_EIF);
|
||||||
|
|
||||||
if (stat & HSSR1_EOF) {
|
if (stat & HSSR1_EOF) {
|
||||||
si->rxskb = NULL;
|
si->dma_rx.skb = NULL;
|
||||||
|
|
||||||
skb_put(skb, len);
|
skb_put(skb, len);
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
|
@ -524,7 +526,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
|
||||||
* Remap the buffer - it was previously mapped, and we
|
* Remap the buffer - it was previously mapped, and we
|
||||||
* hope that this succeeds.
|
* hope that this succeeds.
|
||||||
*/
|
*/
|
||||||
si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
|
si->dma_rx.dma = dma_map_single(si->dev, si->dma_rx.skb->data,
|
||||||
HPSIR_MAX_RXLEN,
|
HPSIR_MAX_RXLEN,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
}
|
}
|
||||||
|
@ -543,7 +545,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
|
||||||
/*
|
/*
|
||||||
* Stop RX DMA
|
* Stop RX DMA
|
||||||
*/
|
*/
|
||||||
sa1100_stop_dma(si->rxdma);
|
sa1100_stop_dma(si->dma_rx.regs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Framing error - we throw away the packet completely.
|
* Framing error - we throw away the packet completely.
|
||||||
|
@ -600,9 +602,9 @@ static void sa1100_irda_txdma_irq(void *id)
|
||||||
{
|
{
|
||||||
struct net_device *dev = id;
|
struct net_device *dev = id;
|
||||||
struct sa1100_irda *si = netdev_priv(dev);
|
struct sa1100_irda *si = netdev_priv(dev);
|
||||||
struct sk_buff *skb = si->txskb;
|
struct sk_buff *skb = si->dma_tx.skb;
|
||||||
|
|
||||||
si->txskb = NULL;
|
si->dma_tx.skb = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for the transmission to complete. Unfortunately,
|
* Wait for the transmission to complete. Unfortunately,
|
||||||
|
@ -620,7 +622,7 @@ static void sa1100_irda_txdma_irq(void *id)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do we need to change speed? Note that we're lazy
|
* Do we need to change speed? Note that we're lazy
|
||||||
* here - we don't free the old rxskb. We don't need
|
* here - we don't free the old dma_rx.skb. We don't need
|
||||||
* to allocate a buffer either.
|
* to allocate a buffer either.
|
||||||
*/
|
*/
|
||||||
if (si->newspeed) {
|
if (si->newspeed) {
|
||||||
|
@ -638,7 +640,7 @@ static void sa1100_irda_txdma_irq(void *id)
|
||||||
* Account and free the packet.
|
* Account and free the packet.
|
||||||
*/
|
*/
|
||||||
if (skb) {
|
if (skb) {
|
||||||
dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE);
|
dma_unmap_single(si->dev, si->dma_tx.dma, skb->len, DMA_TO_DEVICE);
|
||||||
dev->stats.tx_packets ++;
|
dev->stats.tx_packets ++;
|
||||||
dev->stats.tx_bytes += skb->len;
|
dev->stats.tx_bytes += skb->len;
|
||||||
dev_kfree_skb_irq(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
|
@ -698,22 +700,22 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
/*
|
/*
|
||||||
* We must not be transmitting...
|
* We must not be transmitting...
|
||||||
*/
|
*/
|
||||||
BUG_ON(si->txskb);
|
BUG_ON(si->dma_tx.skb);
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
si->txskb = skb;
|
si->dma_tx.skb = skb;
|
||||||
si->txbuf_dma = dma_map_single(si->dev, skb->data,
|
si->dma_tx.dma = dma_map_single(si->dev, skb->data,
|
||||||
skb->len, DMA_TO_DEVICE);
|
skb->len, DMA_TO_DEVICE);
|
||||||
if (dma_mapping_error(si->dev, si->txbuf_dma)) {
|
if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
|
||||||
si->txskb = NULL;
|
si->dma_tx.skb = NULL;
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
dev->stats.tx_dropped++;
|
dev->stats.tx_dropped++;
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len);
|
sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have a mean turn-around time, impose the specified
|
* If we have a mean turn-around time, impose the specified
|
||||||
|
@ -785,12 +787,12 @@ static int sa1100_irda_start(struct net_device *dev)
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
|
|
||||||
err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive",
|
err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive",
|
||||||
NULL, NULL, &si->rxdma);
|
NULL, NULL, &si->dma_rx.regs);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_rx_dma;
|
goto err_rx_dma;
|
||||||
|
|
||||||
err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit",
|
err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit",
|
||||||
sa1100_irda_txdma_irq, dev, &si->txdma);
|
sa1100_irda_txdma_irq, dev, &si->dma_tx.regs);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_tx_dma;
|
goto err_tx_dma;
|
||||||
|
|
||||||
|
@ -827,9 +829,9 @@ static int sa1100_irda_start(struct net_device *dev)
|
||||||
si->open = 0;
|
si->open = 0;
|
||||||
sa1100_irda_shutdown(si);
|
sa1100_irda_shutdown(si);
|
||||||
err_startup:
|
err_startup:
|
||||||
sa1100_free_dma(si->txdma);
|
sa1100_free_dma(si->dma_tx.regs);
|
||||||
err_tx_dma:
|
err_tx_dma:
|
||||||
sa1100_free_dma(si->rxdma);
|
sa1100_free_dma(si->dma_rx.regs);
|
||||||
err_rx_dma:
|
err_rx_dma:
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
err_irq:
|
err_irq:
|
||||||
|
@ -847,11 +849,11 @@ static int sa1100_irda_stop(struct net_device *dev)
|
||||||
* If we have been doing DMA receive, make sure we
|
* If we have been doing DMA receive, make sure we
|
||||||
* tidy that up cleanly.
|
* tidy that up cleanly.
|
||||||
*/
|
*/
|
||||||
if (si->rxskb) {
|
if (si->dma_rx.skb) {
|
||||||
dma_unmap_single(si->dev, si->rxbuf_dma, HPSIR_MAX_RXLEN,
|
dma_unmap_single(si->dev, si->dma_rx.dma, HPSIR_MAX_RXLEN,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
dev_kfree_skb(si->rxskb);
|
dev_kfree_skb(si->dma_rx.skb);
|
||||||
si->rxskb = NULL;
|
si->dma_rx.skb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop IrLAP */
|
/* Stop IrLAP */
|
||||||
|
@ -866,8 +868,8 @@ static int sa1100_irda_stop(struct net_device *dev)
|
||||||
/*
|
/*
|
||||||
* Free resources
|
* Free resources
|
||||||
*/
|
*/
|
||||||
sa1100_free_dma(si->txdma);
|
sa1100_free_dma(si->dma_tx.regs);
|
||||||
sa1100_free_dma(si->rxdma);
|
sa1100_free_dma(si->dma_rx.regs);
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
|
|
||||||
sa1100_set_power(si, 0);
|
sa1100_set_power(si, 0);
|
||||||
|
|
Loading…
Reference in New Issue