Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
* 'next-spi' of git://git.secretlab.ca/git/linux-2.6: spi/pl022: move probe call to subsys_initcall() powerpc/5200: mpc52xx_uart.c: Add of_node_put to avoid memory leak spi/pl022: fix APB pclk power regression on U300 spi/spi_s3c64xx: Warn if PIO transfers time out spi/s3c64xx: Fix incorrect reuse of 'val' local variable. spi/s3c64xx: Fix compilation warning spi/dw_spi: clean the cs_control code spi/dw_spi: Allow interrupt sharing spi/spi_s3c64xx: Increase dead reckoning time in wait_for_xfer() spi/spi_s3c64xx: Move to subsys_initcall() spi: free children in spi_unregister_master, not siblings gpiolib: Add 'struct gpio_chip' forward declaration for !GPIOLIB case of: Fix missing includes - ll_temac spi/spi_s3c64xx: Staticise non-exported functions spi/spi_s3c64xx: Make probe more robust against missing board config
This commit is contained in:
commit
6142811a33
|
@ -38,6 +38,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/tcp.h> /* needed for sizeof(tcphdr) */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/phy.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_mdio.h>
|
||||
|
||||
|
|
|
@ -500,6 +500,7 @@ static int __init mpc512x_psc_fifoc_init(void)
|
|||
psc_fifoc = of_iomap(np, 0);
|
||||
if (!psc_fifoc) {
|
||||
pr_err("%s: Can't map FIFOC\n", __func__);
|
||||
of_node_put(np);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -503,8 +503,9 @@ static void giveback(struct pl022 *pl022)
|
|||
msg->state = NULL;
|
||||
if (msg->complete)
|
||||
msg->complete(msg->context);
|
||||
/* This message is completed, so let's turn off the clock! */
|
||||
/* This message is completed, so let's turn off the clocks! */
|
||||
clk_disable(pl022->clk);
|
||||
amba_pclk_disable(pl022->adev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1139,9 +1140,10 @@ static void pump_messages(struct work_struct *work)
|
|||
/* Setup the SPI using the per chip configuration */
|
||||
pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
|
||||
/*
|
||||
* We enable the clock here, then the clock will be disabled when
|
||||
* We enable the clocks here, then the clocks will be disabled when
|
||||
* giveback() is called in each method (poll/interrupt/DMA)
|
||||
*/
|
||||
amba_pclk_enable(pl022->adev);
|
||||
clk_enable(pl022->clk);
|
||||
restore_state(pl022);
|
||||
flush(pl022);
|
||||
|
@ -1786,11 +1788,9 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
|
|||
}
|
||||
|
||||
/* Disable SSP */
|
||||
clk_enable(pl022->clk);
|
||||
writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
|
||||
SSP_CR1(pl022->virtbase));
|
||||
load_ssp_default_config(pl022);
|
||||
clk_disable(pl022->clk);
|
||||
|
||||
status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022",
|
||||
pl022);
|
||||
|
@ -1818,6 +1818,8 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
|
|||
goto err_spi_register;
|
||||
}
|
||||
dev_dbg(dev, "probe succeded\n");
|
||||
/* Disable the silicon block pclk and clock it when needed */
|
||||
amba_pclk_disable(adev);
|
||||
return 0;
|
||||
|
||||
err_spi_register:
|
||||
|
@ -1879,9 +1881,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
|
|||
return status;
|
||||
}
|
||||
|
||||
clk_enable(pl022->clk);
|
||||
amba_pclk_enable(adev);
|
||||
load_ssp_default_config(pl022);
|
||||
clk_disable(pl022->clk);
|
||||
amba_pclk_disable(adev);
|
||||
dev_dbg(&adev->dev, "suspended\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1981,7 +1983,7 @@ static int __init pl022_init(void)
|
|||
return amba_driver_register(&pl022_driver);
|
||||
}
|
||||
|
||||
module_init(pl022_init);
|
||||
subsys_initcall(pl022_init);
|
||||
|
||||
static void __exit pl022_exit(void)
|
||||
{
|
||||
|
|
|
@ -181,10 +181,6 @@ static void flush(struct dw_spi *dws)
|
|||
wait_till_not_busy(dws);
|
||||
}
|
||||
|
||||
static void null_cs_control(u32 command)
|
||||
{
|
||||
}
|
||||
|
||||
static int null_writer(struct dw_spi *dws)
|
||||
{
|
||||
u8 n_bytes = dws->n_bytes;
|
||||
|
@ -322,7 +318,7 @@ static void giveback(struct dw_spi *dws)
|
|||
struct spi_transfer,
|
||||
transfer_list);
|
||||
|
||||
if (!last_transfer->cs_change)
|
||||
if (!last_transfer->cs_change && dws->cs_control)
|
||||
dws->cs_control(MRST_SPI_DEASSERT);
|
||||
|
||||
msg->state = NULL;
|
||||
|
@ -396,6 +392,11 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
|
|||
static irqreturn_t dw_spi_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct dw_spi *dws = dev_id;
|
||||
u16 irq_status, irq_mask = 0x3f;
|
||||
|
||||
irq_status = dw_readw(dws, isr) & irq_mask;
|
||||
if (!irq_status)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (!dws->cur_msg) {
|
||||
spi_mask_intr(dws, SPI_INT_TXEI);
|
||||
|
@ -544,13 +545,13 @@ static void pump_transfers(unsigned long data)
|
|||
*/
|
||||
if (dws->cs_control) {
|
||||
if (dws->rx && dws->tx)
|
||||
chip->tmode = 0x00;
|
||||
chip->tmode = SPI_TMOD_TR;
|
||||
else if (dws->rx)
|
||||
chip->tmode = 0x02;
|
||||
chip->tmode = SPI_TMOD_RO;
|
||||
else
|
||||
chip->tmode = 0x01;
|
||||
chip->tmode = SPI_TMOD_TO;
|
||||
|
||||
cr0 &= ~(0x3 << SPI_MODE_OFFSET);
|
||||
cr0 &= ~SPI_TMOD_MASK;
|
||||
cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
|
||||
}
|
||||
|
||||
|
@ -699,9 +700,6 @@ static int dw_spi_setup(struct spi_device *spi)
|
|||
chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->cs_control = null_cs_control;
|
||||
chip->enable_dma = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -883,7 +881,7 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
|
|||
dws->dma_inited = 0;
|
||||
dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
|
||||
|
||||
ret = request_irq(dws->irq, dw_spi_irq, 0,
|
||||
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
|
||||
"dw_spi", dws);
|
||||
if (ret < 0) {
|
||||
dev_err(&master->dev, "can not get IRQ\n");
|
||||
|
|
|
@ -554,11 +554,9 @@ done:
|
|||
EXPORT_SYMBOL_GPL(spi_register_master);
|
||||
|
||||
|
||||
static int __unregister(struct device *dev, void *master_dev)
|
||||
static int __unregister(struct device *dev, void *null)
|
||||
{
|
||||
/* note: before about 2.6.14-rc1 this would corrupt memory: */
|
||||
if (dev != master_dev)
|
||||
spi_unregister_device(to_spi_device(dev));
|
||||
spi_unregister_device(to_spi_device(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -576,8 +574,7 @@ void spi_unregister_master(struct spi_master *master)
|
|||
{
|
||||
int dummy;
|
||||
|
||||
dummy = device_for_each_child(master->dev.parent, &master->dev,
|
||||
__unregister);
|
||||
dummy = device_for_each_child(&master->dev, NULL, __unregister);
|
||||
device_unregister(&master->dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_unregister_master);
|
||||
|
|
|
@ -200,6 +200,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
|
|||
val = readl(regs + S3C64XX_SPI_STATUS);
|
||||
} while (TX_FIFO_LVL(val, sci) && loops--);
|
||||
|
||||
if (loops == 0)
|
||||
dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
|
||||
|
||||
/* Flush RxFIFO*/
|
||||
loops = msecs_to_loops(1);
|
||||
do {
|
||||
|
@ -210,6 +213,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
|
|||
break;
|
||||
} while (loops--);
|
||||
|
||||
if (loops == 0)
|
||||
dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n");
|
||||
|
||||
val = readl(regs + S3C64XX_SPI_CH_CFG);
|
||||
val &= ~S3C64XX_SPI_CH_SW_RST;
|
||||
writel(val, regs + S3C64XX_SPI_CH_CFG);
|
||||
|
@ -320,16 +326,17 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
|
|||
|
||||
/* millisecs to xfer 'len' bytes @ 'cur_speed' */
|
||||
ms = xfer->len * 8 * 1000 / sdd->cur_speed;
|
||||
ms += 5; /* some tolerance */
|
||||
ms += 10; /* some tolerance */
|
||||
|
||||
if (dma_mode) {
|
||||
val = msecs_to_jiffies(ms) + 10;
|
||||
val = wait_for_completion_timeout(&sdd->xfer_completion, val);
|
||||
} else {
|
||||
u32 status;
|
||||
val = msecs_to_loops(ms);
|
||||
do {
|
||||
val = readl(regs + S3C64XX_SPI_STATUS);
|
||||
} while (RX_FIFO_LVL(val, sci) < xfer->len && --val);
|
||||
status = readl(regs + S3C64XX_SPI_STATUS);
|
||||
} while (RX_FIFO_LVL(status, sci) < xfer->len && --val);
|
||||
}
|
||||
|
||||
if (!val)
|
||||
|
@ -447,8 +454,8 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
|
|||
writel(val, regs + S3C64XX_SPI_CLK_CFG);
|
||||
}
|
||||
|
||||
void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
|
||||
int size, enum s3c2410_dma_buffresult res)
|
||||
static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
|
||||
int size, enum s3c2410_dma_buffresult res)
|
||||
{
|
||||
struct s3c64xx_spi_driver_data *sdd = buf_id;
|
||||
unsigned long flags;
|
||||
|
@ -467,8 +474,8 @@ void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
|
|||
spin_unlock_irqrestore(&sdd->lock, flags);
|
||||
}
|
||||
|
||||
void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
|
||||
int size, enum s3c2410_dma_buffresult res)
|
||||
static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
|
||||
int size, enum s3c2410_dma_buffresult res)
|
||||
{
|
||||
struct s3c64xx_spi_driver_data *sdd = buf_id;
|
||||
unsigned long flags;
|
||||
|
@ -508,8 +515,9 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
|
|||
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
|
||||
|
||||
if (xfer->tx_buf != NULL) {
|
||||
xfer->tx_dma = dma_map_single(dev, xfer->tx_buf,
|
||||
xfer->len, DMA_TO_DEVICE);
|
||||
xfer->tx_dma = dma_map_single(dev,
|
||||
(void *)xfer->tx_buf, xfer->len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, xfer->tx_dma)) {
|
||||
dev_err(dev, "dma_map_single Tx failed\n");
|
||||
xfer->tx_dma = XFER_DMAADDR_INVALID;
|
||||
|
@ -919,6 +927,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
sci = pdev->dev.platform_data;
|
||||
if (!sci->src_clk_name) {
|
||||
dev_err(&pdev->dev,
|
||||
"Board init must call s3c64xx_spi_set_info()\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for availability of necessary resource */
|
||||
|
||||
dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
|
@ -946,8 +961,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sci = pdev->dev.platform_data;
|
||||
|
||||
platform_set_drvdata(pdev, master);
|
||||
|
||||
sdd = spi_master_get_devdata(master);
|
||||
|
@ -1170,7 +1183,7 @@ static int __init s3c64xx_spi_init(void)
|
|||
{
|
||||
return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
|
||||
}
|
||||
module_init(s3c64xx_spi_init);
|
||||
subsys_initcall(s3c64xx_spi_init);
|
||||
|
||||
static void __exit s3c64xx_spi_exit(void)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/errno.h>
|
||||
|
||||
struct device;
|
||||
struct gpio_chip;
|
||||
|
||||
/*
|
||||
* Some platforms don't support the GPIO programming interface.
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
#define SPI_MODE_OFFSET 6
|
||||
#define SPI_SCPH_OFFSET 6
|
||||
#define SPI_SCOL_OFFSET 7
|
||||
|
||||
#define SPI_TMOD_OFFSET 8
|
||||
#define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET)
|
||||
#define SPI_TMOD_TR 0x0 /* xmit & recv */
|
||||
#define SPI_TMOD_TO 0x1 /* xmit only */
|
||||
#define SPI_TMOD_RO 0x2 /* recv only */
|
||||
|
|
Loading…
Reference in New Issue