Commit 073ac8fd authored by Russell King's avatar Russell King Committed by Russell King

[NET] smc91x: fix PXA DMA support code

The PXA DMA support code for smc91x doesn't pass a struct device to
the dma_*map_single() functions, which leads to an oops in the dma
bounce code.  We have a struct device which was used to probe the
SMC chip.  Use it.

(This patch is slightly larger because it requires struct smc_local
to move into the header file.)
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 97d97224
...@@ -173,49 +173,6 @@ MODULE_LICENSE("GPL"); ...@@ -173,49 +173,6 @@ MODULE_LICENSE("GPL");
*/ */
#define MII_DELAY 1 #define MII_DELAY 1
/* store this information for the driver.. */
struct smc_local {
/*
* If I have to wait until memory is available to send a
* packet, I will store the skbuff here, until I get the
* desired memory. Then, I'll send it out and free it.
*/
struct sk_buff *pending_tx_skb;
struct tasklet_struct tx_task;
/* version/revision of the SMC91x chip */
int version;
/* Contains the current active transmission mode */
int tcr_cur_mode;
/* Contains the current active receive mode */
int rcr_cur_mode;
/* Contains the current active receive/phy mode */
int rpc_cur_mode;
int ctl_rfduplx;
int ctl_rspeed;
u32 msg_enable;
u32 phy_type;
struct mii_if_info mii;
/* work queue */
struct work_struct phy_configure;
struct net_device *dev;
int work_pending;
spinlock_t lock;
#ifdef SMC_USE_PXA_DMA
/* DMA needs the physical address of the chip */
u_long physaddr;
#endif
void __iomem *base;
void __iomem *datacs;
};
#if SMC_DEBUG > 0 #if SMC_DEBUG > 0
#define DBG(n, args...) \ #define DBG(n, args...) \
do { \ do { \
...@@ -2215,17 +2172,19 @@ static int smc_drv_probe(struct platform_device *pdev) ...@@ -2215,17 +2172,19 @@ static int smc_drv_probe(struct platform_device *pdev)
goto out_release_attrib; goto out_release_attrib;
} }
platform_set_drvdata(pdev, ndev);
ret = smc_probe(ndev, addr);
if (ret != 0)
goto out_iounmap;
#ifdef SMC_USE_PXA_DMA #ifdef SMC_USE_PXA_DMA
else { {
struct smc_local *lp = netdev_priv(ndev); struct smc_local *lp = netdev_priv(ndev);
lp->device = &pdev->dev;
lp->physaddr = res->start; lp->physaddr = res->start;
} }
#endif #endif
platform_set_drvdata(pdev, ndev);
ret = smc_probe(ndev, addr);
if (ret != 0)
goto out_iounmap;
smc_request_datacs(pdev, ndev); smc_request_datacs(pdev, ndev);
return 0; return 0;
......
...@@ -462,6 +462,52 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, ...@@ -462,6 +462,52 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#endif #endif
/* store this information for the driver.. */
struct smc_local {
/*
* If I have to wait until memory is available to send a
* packet, I will store the skbuff here, until I get the
* desired memory. Then, I'll send it out and free it.
*/
struct sk_buff *pending_tx_skb;
struct tasklet_struct tx_task;
/* version/revision of the SMC91x chip */
int version;
/* Contains the current active transmission mode */
int tcr_cur_mode;
/* Contains the current active receive mode */
int rcr_cur_mode;
/* Contains the current active receive/phy mode */
int rpc_cur_mode;
int ctl_rfduplx;
int ctl_rspeed;
u32 msg_enable;
u32 phy_type;
struct mii_if_info mii;
/* work queue */
struct work_struct phy_configure;
struct net_device *dev;
int work_pending;
spinlock_t lock;
#ifdef SMC_USE_PXA_DMA
/* DMA needs the physical address of the chip */
u_long physaddr;
struct device *device;
#endif
void __iomem *base;
void __iomem *datacs;
};
#ifdef SMC_USE_PXA_DMA #ifdef SMC_USE_PXA_DMA
/* /*
* Let's use the DMA engine on the XScale PXA2xx for RX packets. This is * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
...@@ -476,11 +522,12 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, ...@@ -476,11 +522,12 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#ifdef SMC_insl #ifdef SMC_insl
#undef SMC_insl #undef SMC_insl
#define SMC_insl(a, r, p, l) \ #define SMC_insl(a, r, p, l) \
smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l) smc_pxa_dma_insl(a, lp, r, dev->dma, p, l)
static inline void static inline void
smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len) u_char *buf, int len)
{ {
u_long physaddr = lp->physaddr;
dma_addr_t dmabuf; dma_addr_t dmabuf;
/* fallback if no DMA available */ /* fallback if no DMA available */
...@@ -497,7 +544,7 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, ...@@ -497,7 +544,7 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
} }
len *= 4; len *= 4;
dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE); dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC; DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf; DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg; DSADR(dma) = physaddr + reg;
...@@ -507,18 +554,19 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, ...@@ -507,18 +554,19 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
while (!(DCSR(dma) & DCSR_STOPSTATE)) while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax(); cpu_relax();
DCSR(dma) = 0; DCSR(dma) = 0;
dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE); dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
} }
#endif #endif
#ifdef SMC_insw #ifdef SMC_insw
#undef SMC_insw #undef SMC_insw
#define SMC_insw(a, r, p, l) \ #define SMC_insw(a, r, p, l) \
smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l) smc_pxa_dma_insw(a, lp, r, dev->dma, p, l)
static inline void static inline void
smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len) u_char *buf, int len)
{ {
u_long physaddr = lp->physaddr;
dma_addr_t dmabuf; dma_addr_t dmabuf;
/* fallback if no DMA available */ /* fallback if no DMA available */
...@@ -535,7 +583,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, ...@@ -535,7 +583,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
} }
len *= 2; len *= 2;
dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE); dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC; DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf; DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg; DSADR(dma) = physaddr + reg;
...@@ -545,7 +593,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, ...@@ -545,7 +593,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
while (!(DCSR(dma) & DCSR_STOPSTATE)) while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax(); cpu_relax();
DCSR(dma) = 0; DCSR(dma) = 0;
dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE); dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
} }
#endif #endif
......
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