Skip to content

Commit

Permalink
NET: sa11x0-ir: move SIR and FIR interrupt support
Browse files Browse the repository at this point in the history
Move the interrupt handlers to the SIR and FIR sections of the file.
This improves the localization of the protocol handlers.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Feb 9, 2012
1 parent 374f773 commit a6b2ea6
Showing 1 changed file with 141 additions and 149 deletions.
290 changes: 141 additions & 149 deletions drivers/net/irda/sa1100_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a6b2ea6

Please sign in to comment.