Commit a6b2ea66 authored by Russell King's avatar Russell King

NET: sa11x0-ir: move SIR and FIR interrupt support

Move the interrupt handlers to the SIR and FIR sections of the file.
This improves the localization of the protocol handlers.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 374f7739
......@@ -164,151 +164,6 @@ static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev,
return NETDEV_TX_OK;
}
/*
* FIR format support.
*/
static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
struct sa1100_irda *si)
{
int mtt = irda_get_mtt(skb);
si->dma_tx.skb = skb;
si->dma_tx.dma = dma_map_single(si->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
si->dma_tx.skb = NULL;
netif_wake_queue(dev);
dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);
/*
* If we have a mean turn-around time, impose the specified
* specified delay. We could shorten this by timing from
* the point we received the packet.
*/
if (mtt)
udelay(mtt);
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
return NETDEV_TX_OK;
}
static irqreturn_t sa1100_irda_sir_irq(struct net_device *, struct sa1100_irda *);
static irqreturn_t sa1100_irda_fir_irq(struct net_device *, struct sa1100_irda *);
/*
* Set the IrDA communications speed.
*/
static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
{
unsigned long flags;
int brd, ret = -EINVAL;
switch (speed) {
case 9600: case 19200: case 38400:
case 57600: case 115200:
brd = 3686400 / (16 * speed) - 1;
/*
* Stop the receive DMA.
*/
if (IS_FIR(si))
sa1100_stop_dma(si->dma_rx.regs);
local_irq_save(flags);
Ser2UTCR3 = 0;
Ser2HSCR0 = HSCR0_UART;
Ser2UTCR1 = brd >> 8;
Ser2UTCR2 = brd;
/*
* Clear status register
*/
Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
si->speed = speed;
si->tx_start = sa1100_irda_sir_tx_start;
si->irq = sa1100_irda_sir_irq;
local_irq_restore(flags);
ret = 0;
break;
case 4000000:
local_irq_save(flags);
si->hscr0 = 0;
Ser2HSSR0 = 0xff;
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
Ser2UTCR3 = 0;
si->speed = speed;
si->tx_start = sa1100_irda_fir_tx_start;
si->irq = sa1100_irda_fir_irq;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
sa1100_irda_rx_alloc(si);
sa1100_irda_rx_dma_start(si);
local_irq_restore(flags);
break;
default:
break;
}
return ret;
}
/*
* Control the power state of the IrDA transmitter.
* State:
* 0 - off
* 1 - short range, lowest power
* 2 - medium range, medium power
* 3 - maximum range, high power
*
* Currently, only assabet is known to support this.
*/
static int
__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
{
int ret = 0;
if (si->pdata->set_power)
ret = si->pdata->set_power(si->dev, state);
return ret;
}
static inline int
sa1100_set_power(struct sa1100_irda *si, unsigned int state)
{
int ret;
ret = __sa1100_irda_set_power(si, state);
if (ret == 0)
si->power = state;
return ret;
}
/*
* HP-SIR format interrupt service routines.
*/
static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si)
{
int status;
......@@ -403,6 +258,40 @@ static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_ird
return IRQ_HANDLED;
}
/*
* FIR format support.
*/
static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
struct sa1100_irda *si)
{
int mtt = irda_get_mtt(skb);
si->dma_tx.skb = skb;
si->dma_tx.dma = dma_map_single(si->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
si->dma_tx.skb = NULL;
netif_wake_queue(dev);
dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);
/*
* If we have a mean turn-around time, impose the specified
* specified delay. We could shorten this by timing from
* the point we received the packet.
*/
if (mtt)
udelay(mtt);
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
return NETDEV_TX_OK;
}
static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
{
struct sk_buff *skb = si->dma_rx.skb;
......@@ -476,10 +365,8 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
}
/*
* FIR format interrupt service routine. We only have to
* handle RX events; transmit events go via the TX DMA handler.
*
* No matter what, we disable RX, process, and the restart RX.
* We only have to handle RX events here; transmit events go via the TX
* DMA handler. We disable RX, process, and the restart RX.
*/
static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si)
{
......@@ -528,6 +415,111 @@ static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_ird
return IRQ_HANDLED;
}
/*
* Set the IrDA communications speed.
*/
static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
{
unsigned long flags;
int brd, ret = -EINVAL;
switch (speed) {
case 9600: case 19200: case 38400:
case 57600: case 115200:
brd = 3686400 / (16 * speed) - 1;
/*
* Stop the receive DMA.
*/
if (IS_FIR(si))
sa1100_stop_dma(si->dma_rx.regs);
local_irq_save(flags);
Ser2UTCR3 = 0;
Ser2HSCR0 = HSCR0_UART;
Ser2UTCR1 = brd >> 8;
Ser2UTCR2 = brd;
/*
* Clear status register
*/
Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
si->speed = speed;
si->tx_start = sa1100_irda_sir_tx_start;
si->irq = sa1100_irda_sir_irq;
local_irq_restore(flags);
ret = 0;
break;
case 4000000:
local_irq_save(flags);
si->hscr0 = 0;
Ser2HSSR0 = 0xff;
Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
Ser2UTCR3 = 0;
si->speed = speed;
si->tx_start = sa1100_irda_fir_tx_start;
si->irq = sa1100_irda_fir_irq;
if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
sa1100_irda_rx_alloc(si);
sa1100_irda_rx_dma_start(si);
local_irq_restore(flags);
break;
default:
break;
}
return ret;
}
/*
* Control the power state of the IrDA transmitter.
* State:
* 0 - off
* 1 - short range, lowest power
* 2 - medium range, medium power
* 3 - maximum range, high power
*
* Currently, only assabet is known to support this.
*/
static int
__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
{
int ret = 0;
if (si->pdata->set_power)
ret = si->pdata->set_power(si->dev, state);
return ret;
}
static inline int
sa1100_set_power(struct sa1100_irda *si, unsigned int state)
{
int ret;
ret = __sa1100_irda_set_power(si, state);
if (ret == 0)
si->power = state;
return ret;
}
static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment