提交 89fa5724 编写于 作者: R Robert Jarzmik 提交者: David S. Miller

net: irda: pxaficp_ir: convert to readl and writel

Convert the pxa IRDA driver to readl and writel primitives, and remove
another set of direct registers access. This leaves only the DMA
registers access, which will be dealt with dmaengine conversion.
Signed-off-by: NRobert Jarzmik <robert.jarzmik@free.fr>
Tested-by: NPetr Cvek <petr.cvek@tul.cz>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 be01891e
...@@ -29,15 +29,16 @@ ...@@ -29,15 +29,16 @@
#include <mach/dma.h> #include <mach/dma.h>
#include <linux/platform_data/irda-pxaficp.h> #include <linux/platform_data/irda-pxaficp.h>
#undef __REG
#define __REG(x) ((x) & 0xffff)
#include <mach/regs-uart.h> #include <mach/regs-uart.h>
#define FICP __REG(0x40800000) /* Start of FICP area */ #define ICCR0 0x0000 /* ICP Control Register 0 */
#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ #define ICCR1 0x0004 /* ICP Control Register 1 */
#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ #define ICCR2 0x0008 /* ICP Control Register 2 */
#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ #define ICDR 0x000c /* ICP Data Register */
#define ICDR __REG(0x4080000c) /* ICP Data Register */ #define ICSR0 0x0014 /* ICP Status Register 0 */
#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ #define ICSR1 0x0018 /* ICP Status Register 1 */
#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */
#define ICCR0_AME (1 << 7) /* Address match enable */ #define ICCR0_AME (1 << 7) /* Address match enable */
#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ #define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */
...@@ -55,9 +56,7 @@ ...@@ -55,9 +56,7 @@
#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ #define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */
#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ #define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */
#ifdef CONFIG_PXA27x
#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ #define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */
#endif
#define ICSR0_FRE (1 << 5) /* Framing error */ #define ICSR0_FRE (1 << 5) /* Framing error */
#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ #define ICSR0_RFS (1 << 4) /* Receive FIFO service request */
#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ #define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */
...@@ -98,11 +97,50 @@ ...@@ -98,11 +97,50 @@
IrSR_RCVEIR_UART_MODE | \ IrSR_RCVEIR_UART_MODE | \
IrSR_XMITIR_IR_MODE) IrSR_XMITIR_IR_MODE)
/* macros for registers read/write */
#define ficp_writel(irda, val, off) \
do { \
dev_vdbg(irda->dev, \
"%s():%d ficp_writel(0x%x, %s)\n", \
__func__, __LINE__, (val), #off); \
writel_relaxed((val), (irda)->irda_base + (off)); \
} while (0)
#define ficp_readl(irda, off) \
({ \
unsigned int _v; \
_v = readl_relaxed((irda)->irda_base + (off)); \
dev_vdbg(irda->dev, \
"%s():%d ficp_readl(%s): 0x%x\n", \
__func__, __LINE__, #off, _v); \
_v; \
})
#define stuart_writel(irda, val, off) \
do { \
dev_vdbg(irda->dev, \
"%s():%d stuart_writel(0x%x, %s)\n", \
__func__, __LINE__, (val), #off); \
writel_relaxed((val), (irda)->stuart_base + (off)); \
} while (0)
#define stuart_readl(irda, off) \
({ \
unsigned int _v; \
_v = readl_relaxed((irda)->stuart_base + (off)); \
dev_vdbg(irda->dev, \
"%s():%d stuart_readl(%s): 0x%x\n", \
__func__, __LINE__, #off, _v); \
_v; \
})
struct pxa_irda { struct pxa_irda {
int speed; int speed;
int newspeed; int newspeed;
unsigned long long last_clk; unsigned long long last_clk;
void __iomem *stuart_base;
void __iomem *irda_base;
unsigned char *dma_rx_buff; unsigned char *dma_rx_buff;
unsigned char *dma_tx_buff; unsigned char *dma_tx_buff;
dma_addr_t dma_rx_buff_phy; dma_addr_t dma_rx_buff_phy;
...@@ -153,7 +191,7 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si) ...@@ -153,7 +191,7 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si) inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
{ {
DCSR(si->rxdma) = DCSR_NODESC; DCSR(si->rxdma) = DCSR_NODESC;
DSADR(si->rxdma) = __PREG(ICDR); DSADR(si->rxdma) = (unsigned long)si->irda_base + ICDR;
DTADR(si->rxdma) = si->dma_rx_buff_phy; DTADR(si->rxdma) = si->dma_rx_buff_phy;
DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT; DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
DCSR(si->rxdma) |= DCSR_RUN; DCSR(si->rxdma) |= DCSR_RUN;
...@@ -163,7 +201,7 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si) ...@@ -163,7 +201,7 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
{ {
DCSR(si->txdma) = DCSR_NODESC; DCSR(si->txdma) = DCSR_NODESC;
DSADR(si->txdma) = si->dma_tx_buff_phy; DSADR(si->txdma) = si->dma_tx_buff_phy;
DTADR(si->txdma) = __PREG(ICDR); DTADR(si->txdma) = (unsigned long)si->irda_base + ICDR;
DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len; DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
DCSR(si->txdma) |= DCSR_RUN; DCSR(si->txdma) |= DCSR_RUN;
} }
...@@ -206,7 +244,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) ...@@ -206,7 +244,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
/* stop RX DMA */ /* stop RX DMA */
DCSR(si->rxdma) &= ~DCSR_RUN; DCSR(si->rxdma) &= ~DCSR_RUN;
/* disable FICP */ /* disable FICP */
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
pxa_irda_disable_clk(si); pxa_irda_disable_clk(si);
/* set board transceiver to SIR mode */ /* set board transceiver to SIR mode */
...@@ -217,17 +255,19 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) ...@@ -217,17 +255,19 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
} }
/* disable STUART first */ /* disable STUART first */
STIER = 0; stuart_writel(si, 0, STIER);
/* access DLL & DLH */ /* access DLL & DLH */
STLCR |= LCR_DLAB; stuart_writel(si, stuart_readl(si, STLCR) | LCR_DLAB, STLCR);
STDLL = divisor & 0xff; stuart_writel(si, divisor & 0xff, STDLL);
STDLH = divisor >> 8; stuart_writel(si, divisor >> 8, STDLH);
STLCR &= ~LCR_DLAB; stuart_writel(si, stuart_readl(si, STLCR) & ~LCR_DLAB, STLCR);
si->speed = speed; si->speed = speed;
STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; stuart_writel(si, IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6,
STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; STISR);
stuart_writel(si, IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE,
STIER);
local_irq_restore(flags); local_irq_restore(flags);
break; break;
...@@ -236,12 +276,12 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) ...@@ -236,12 +276,12 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
local_irq_save(flags); local_irq_save(flags);
/* disable STUART */ /* disable STUART */
STIER = 0; stuart_writel(si, 0, STIER);
STISR = 0; stuart_writel(si, 0, STISR);
pxa_irda_disable_clk(si); pxa_irda_disable_clk(si);
/* disable FICP first */ /* disable FICP first */
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
/* set board transceiver to FIR mode */ /* set board transceiver to FIR mode */
pxa_irda_set_mode(si, IR_FIRMODE); pxa_irda_set_mode(si, IR_FIRMODE);
...@@ -251,7 +291,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) ...@@ -251,7 +291,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
si->speed = speed; si->speed = speed;
pxa_irda_fir_dma_rx_start(si); pxa_irda_fir_dma_rx_start(si);
ICCR0 = ICCR0_ITR | ICCR0_RXE; ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
local_irq_restore(flags); local_irq_restore(flags);
break; break;
...@@ -270,13 +310,13 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) ...@@ -270,13 +310,13 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
struct pxa_irda *si = netdev_priv(dev); struct pxa_irda *si = netdev_priv(dev);
int iir, lsr, data; int iir, lsr, data;
iir = STIIR; iir = stuart_readl(si, STIIR);
switch (iir & 0x0F) { switch (iir & 0x0F) {
case 0x06: /* Receiver Line Status */ case 0x06: /* Receiver Line Status */
lsr = STLSR; lsr = stuart_readl(si, STLSR);
while (lsr & LSR_FIFOE) { while (lsr & LSR_FIFOE) {
data = STRBR; data = stuart_readl(si, STRBR);
if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
dev->stats.rx_errors++; dev->stats.rx_errors++;
...@@ -289,7 +329,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) ...@@ -289,7 +329,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
async_unwrap_char(dev, &dev->stats, async_unwrap_char(dev, &dev->stats,
&si->rx_buff, data); &si->rx_buff, data);
} }
lsr = STLSR; lsr = stuart_readl(si, STLSR);
} }
si->last_clk = sched_clock(); si->last_clk = sched_clock();
break; break;
...@@ -300,14 +340,16 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) ...@@ -300,14 +340,16 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
case 0x0C: /* Character Timeout Indication */ case 0x0C: /* Character Timeout Indication */
do { do {
dev->stats.rx_bytes++; dev->stats.rx_bytes++;
async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR); async_unwrap_char(dev, &dev->stats, &si->rx_buff,
} while (STLSR & LSR_DR); stuart_readl(si, STRBR));
} while (stuart_readl(si, STLSR) & LSR_DR);
si->last_clk = sched_clock(); si->last_clk = sched_clock();
break; break;
case 0x02: /* Transmit FIFO Data Request */ case 0x02: /* Transmit FIFO Data Request */
while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) { while ((si->tx_buff.len) &&
STTHR = *si->tx_buff.data++; (stuart_readl(si, STLSR) & LSR_TDRQ)) {
stuart_writel(si, *si->tx_buff.data++, STTHR);
si->tx_buff.len -= 1; si->tx_buff.len -= 1;
} }
...@@ -316,7 +358,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) ...@@ -316,7 +358,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head;
/* We need to ensure that the transmitter has finished. */ /* We need to ensure that the transmitter has finished. */
while ((STLSR & LSR_TEMT) == 0) while ((stuart_readl(si, STLSR) & LSR_TEMT) == 0)
cpu_relax(); cpu_relax();
si->last_clk = sched_clock(); si->last_clk = sched_clock();
...@@ -330,9 +372,11 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) ...@@ -330,9 +372,11 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
si->newspeed = 0; si->newspeed = 0;
} else { } else {
/* enable IR Receiver, disable IR Transmitter */ /* enable IR Receiver, disable IR Transmitter */
STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; stuart_writel(si, IrSR_IR_RECEIVE_ON |
IrSR_XMODE_PULSE_1_6, STISR);
/* enable STUART and receive interrupts */ /* enable STUART and receive interrupts */
STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; stuart_writel(si, IER_UUE | IER_RLSE |
IER_RAVIE | IER_RTIOE, STIER);
} }
/* I'm hungry! */ /* I'm hungry! */
netif_wake_queue(dev); netif_wake_queue(dev);
...@@ -370,7 +414,7 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data) ...@@ -370,7 +414,7 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
dev->stats.tx_errors++; dev->stats.tx_errors++;
} }
while (ICSR1 & ICSR1_TBY) while (ficp_readl(si, ICSR1) & ICSR1_TBY)
cpu_relax(); cpu_relax();
si->last_clk = sched_clock(); si->last_clk = sched_clock();
...@@ -386,11 +430,11 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data) ...@@ -386,11 +430,11 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
} else { } else {
int i = 64; int i = 64;
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
pxa_irda_fir_dma_rx_start(si); pxa_irda_fir_dma_rx_start(si);
while ((ICSR1 & ICSR1_RNE) && i--) while ((ficp_readl(si, ICSR1) & ICSR1_RNE) && i--)
(void)ICDR; ficp_readl(si, ICDR);
ICCR0 = ICCR0_ITR | ICCR0_RXE; ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
if (i < 0) if (i < 0)
printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n"); printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
...@@ -408,9 +452,9 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in ...@@ -408,9 +452,9 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in
do { do {
/* Read Status, and then Data. */ /* Read Status, and then Data. */
stat = ICSR1; stat = ficp_readl(si, ICSR1);
rmb(); rmb();
data = ICDR; data = ficp_readl(si, ICDR);
if (stat & (ICSR1_CRE | ICSR1_ROR)) { if (stat & (ICSR1_CRE | ICSR1_ROR)) {
dev->stats.rx_errors++; dev->stats.rx_errors++;
...@@ -428,7 +472,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in ...@@ -428,7 +472,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in
/* If we hit the end of frame, there's no point in continuing. */ /* If we hit the end of frame, there's no point in continuing. */
if (stat & ICSR1_EOF) if (stat & ICSR1_EOF)
break; break;
} while (ICSR0 & ICSR0_EIF); } while (ficp_readl(si, ICSR0) & ICSR0_EIF);
if (stat & ICSR1_EOF) { if (stat & ICSR1_EOF) {
/* end of frame. */ /* end of frame. */
...@@ -472,8 +516,8 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) ...@@ -472,8 +516,8 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
/* stop RX DMA */ /* stop RX DMA */
DCSR(si->rxdma) &= ~DCSR_RUN; DCSR(si->rxdma) &= ~DCSR_RUN;
icsr0 = ICSR0;
si->last_clk = sched_clock(); si->last_clk = sched_clock();
icsr0 = ficp_readl(si, ICSR0);
if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) { if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
if (icsr0 & ICSR0_FRE) { if (icsr0 & ICSR0_FRE) {
...@@ -483,7 +527,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) ...@@ -483,7 +527,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
printk(KERN_DEBUG "pxa_ir: fir receive abort\n"); printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
dev->stats.rx_errors++; dev->stats.rx_errors++;
} }
ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB); ficp_writel(si, icsr0 & (ICSR0_FRE | ICSR0_RAB), ICSR0);
} }
if (icsr0 & ICSR0_EIF) { if (icsr0 & ICSR0_EIF) {
...@@ -491,11 +535,11 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) ...@@ -491,11 +535,11 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
pxa_irda_fir_irq_eif(si, dev, icsr0); pxa_irda_fir_irq_eif(si, dev, icsr0);
} }
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
pxa_irda_fir_dma_rx_start(si); pxa_irda_fir_dma_rx_start(si);
while ((ICSR1 & ICSR1_RNE) && i--) while ((ficp_readl(si, ICSR1) & ICSR1_RNE) && i--)
(void)ICDR; ficp_readl(si, ICDR);
ICCR0 = ICCR0_ITR | ICCR0_RXE; ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
if (i < 0) if (i < 0)
printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n"); printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
...@@ -536,11 +580,12 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -536,11 +580,12 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
/* Disable STUART interrupts and switch to transmit mode. */ /* Disable STUART interrupts and switch to transmit mode. */
STIER = 0; stuart_writel(si, 0, STIER);
STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6; stuart_writel(si, IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6,
STISR);
/* enable STUART and transmit interrupts */ /* enable STUART and transmit interrupts */
STIER = IER_UUE | IER_TIE; stuart_writel(si, IER_UUE | IER_TIE, STIER);
} else { } else {
unsigned long mtt = irda_get_mtt(skb); unsigned long mtt = irda_get_mtt(skb);
...@@ -553,10 +598,10 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -553,10 +598,10 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* stop RX DMA, disable FICP */ /* stop RX DMA, disable FICP */
DCSR(si->rxdma) &= ~DCSR_RUN; DCSR(si->rxdma) &= ~DCSR_RUN;
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
pxa_irda_fir_dma_tx_start(si); pxa_irda_fir_dma_tx_start(si);
ICCR0 = ICCR0_ITR | ICCR0_TXE; ficp_writel(si, ICCR0_ITR | ICCR0_TXE, ICCR0);
} }
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -612,18 +657,18 @@ static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) ...@@ -612,18 +657,18 @@ static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
static void pxa_irda_startup(struct pxa_irda *si) static void pxa_irda_startup(struct pxa_irda *si)
{ {
/* Disable STUART interrupts */ /* Disable STUART interrupts */
STIER = 0; stuart_writel(si, 0, STIER);
/* enable STUART interrupt to the processor */ /* enable STUART interrupt to the processor */
STMCR = MCR_OUT2; stuart_writel(si, MCR_OUT2, STMCR);
/* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */ /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
STLCR = LCR_WLS0 | LCR_WLS1; stuart_writel(si, LCR_WLS0 | LCR_WLS1, STLCR);
/* enable FIFO, we use FIFO to improve performance */ /* enable FIFO, we use FIFO to improve performance */
STFCR = FCR_TRFIFOE | FCR_ITL_32; stuart_writel(si, FCR_TRFIFOE | FCR_ITL_32, STFCR);
/* disable FICP */ /* disable FICP */
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
/* configure FICP ICCR2 */ /* configure FICP ICCR2 */
ICCR2 = ICCR2_TXP | ICCR2_TRIG_32; ficp_writel(si, ICCR2_TXP | ICCR2_TRIG_32, ICCR2);
/* configure DMAC */ /* configure DMAC */
DRCMR(17) = si->rxdma | DRCMR_MAPVLD; DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
...@@ -643,15 +688,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si) ...@@ -643,15 +688,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
local_irq_save(flags); local_irq_save(flags);
/* disable STUART and interrupt */ /* disable STUART and interrupt */
STIER = 0; stuart_writel(si, 0, STIER);
/* disable STUART SIR mode */ /* disable STUART SIR mode */
STISR = 0; stuart_writel(si, 0, STISR);
/* disable DMA */ /* disable DMA */
DCSR(si->txdma) &= ~DCSR_RUN; DCSR(si->txdma) &= ~DCSR_RUN;
DCSR(si->rxdma) &= ~DCSR_RUN; DCSR(si->rxdma) &= ~DCSR_RUN;
/* disable FICP */ /* disable FICP */
ICCR0 = 0; ficp_writel(si, 0, ICCR0);
/* disable the STUART or FICP clocks */ /* disable the STUART or FICP clocks */
pxa_irda_disable_clk(si); pxa_irda_disable_clk(si);
...@@ -829,25 +874,33 @@ static const struct net_device_ops pxa_irda_netdev_ops = { ...@@ -829,25 +874,33 @@ static const struct net_device_ops pxa_irda_netdev_ops = {
static int pxa_irda_probe(struct platform_device *pdev) static int pxa_irda_probe(struct platform_device *pdev)
{ {
struct net_device *dev; struct net_device *dev;
struct resource *res;
struct pxa_irda *si; struct pxa_irda *si;
void __iomem *ficp, *stuart;
unsigned int baudrate_mask; unsigned int baudrate_mask;
int err; int err;
if (!pdev->dev.platform_data) if (!pdev->dev.platform_data)
return -ENODEV; return -ENODEV;
err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (err) ficp = devm_ioremap_resource(&pdev->dev, res);
goto err_mem_1; if (IS_ERR(ficp)) {
dev_err(&pdev->dev, "resource ficp not defined\n");
return PTR_ERR(ficp);
}
err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (err) stuart = devm_ioremap_resource(&pdev->dev, res);
goto err_mem_2; if (IS_ERR(stuart)) {
dev_err(&pdev->dev, "resource stuart not defined\n");
return PTR_ERR(stuart);
}
dev = alloc_irdadev(sizeof(struct pxa_irda)); dev = alloc_irdadev(sizeof(struct pxa_irda));
if (!dev) { if (!dev) {
err = -ENOMEM; err = -ENOMEM;
goto err_mem_3; goto err_mem_1;
} }
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
...@@ -855,11 +908,13 @@ static int pxa_irda_probe(struct platform_device *pdev) ...@@ -855,11 +908,13 @@ static int pxa_irda_probe(struct platform_device *pdev)
si->dev = &pdev->dev; si->dev = &pdev->dev;
si->pdata = pdev->dev.platform_data; si->pdata = pdev->dev.platform_data;
si->irda_base = ficp;
si->stuart_base = stuart;
si->uart_irq = platform_get_irq(pdev, 0); si->uart_irq = platform_get_irq(pdev, 0);
si->icp_irq = platform_get_irq(pdev, 1); si->icp_irq = platform_get_irq(pdev, 1);
si->sir_clk = clk_get(&pdev->dev, "UARTCLK"); si->sir_clk = devm_clk_get(&pdev->dev, "UARTCLK");
si->fir_clk = clk_get(&pdev->dev, "FICPCLK"); si->fir_clk = devm_clk_get(&pdev->dev, "FICPCLK");
if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) { if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk); err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
goto err_mem_4; goto err_mem_4;
...@@ -924,15 +979,7 @@ static int pxa_irda_probe(struct platform_device *pdev) ...@@ -924,15 +979,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
err_mem_5: err_mem_5:
kfree(si->rx_buff.head); kfree(si->rx_buff.head);
err_mem_4: err_mem_4:
if (si->sir_clk && !IS_ERR(si->sir_clk))
clk_put(si->sir_clk);
if (si->fir_clk && !IS_ERR(si->fir_clk))
clk_put(si->fir_clk);
free_netdev(dev); free_netdev(dev);
err_mem_3:
release_mem_region(__PREG(FICP), 0x1c);
err_mem_2:
release_mem_region(__PREG(STUART), 0x24);
} }
err_mem_1: err_mem_1:
return err; return err;
...@@ -951,14 +998,9 @@ static int pxa_irda_remove(struct platform_device *_dev) ...@@ -951,14 +998,9 @@ static int pxa_irda_remove(struct platform_device *_dev)
si->pdata->shutdown(si->dev); si->pdata->shutdown(si->dev);
kfree(si->tx_buff.head); kfree(si->tx_buff.head);
kfree(si->rx_buff.head); kfree(si->rx_buff.head);
clk_put(si->fir_clk);
clk_put(si->sir_clk);
free_netdev(dev); free_netdev(dev);
} }
release_mem_region(__PREG(STUART), 0x24);
release_mem_region(__PREG(FICP), 0x1c);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册