[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: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
97d97224ff
commit
073ac8fd4a
|
@ -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,16 +2172,18 @@ static int smc_drv_probe(struct platform_device *pdev)
|
||||||
goto out_release_attrib;
|
goto out_release_attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SMC_USE_PXA_DMA
|
||||||
|
{
|
||||||
|
struct smc_local *lp = netdev_priv(ndev);
|
||||||
|
lp->device = &pdev->dev;
|
||||||
|
lp->physaddr = res->start;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ndev);
|
platform_set_drvdata(pdev, ndev);
|
||||||
ret = smc_probe(ndev, addr);
|
ret = smc_probe(ndev, addr);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out_iounmap;
|
goto out_iounmap;
|
||||||
#ifdef SMC_USE_PXA_DMA
|
|
||||||
else {
|
|
||||||
struct smc_local *lp = netdev_priv(ndev);
|
|
||||||
lp->physaddr = res->start;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
smc_request_datacs(pdev, ndev);
|
smc_request_datacs(pdev, ndev);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
#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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue