mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge commit 'origin'
Manual fixup of conflicts on: arch/powerpc/include/asm/dcr-regs.h drivers/net/ibm_newemac/core.h
This commit is contained in:
commit
6dc6472581
5097 changed files with 278566 additions and 138302 deletions
|
|
@ -427,7 +427,7 @@ static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m)
|
|||
goto msg_rejected;
|
||||
}
|
||||
|
||||
if (t->speed_hz < orion_spi->min_speed) {
|
||||
if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
|
||||
dev_err(&spi->dev,
|
||||
"message rejected : "
|
||||
"device min speed (%d Hz) exceeds "
|
||||
|
|
|
|||
|
|
@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
|
|||
|
||||
#define MAX_BUSES 3
|
||||
|
||||
#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
|
||||
#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
|
||||
#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
|
||||
#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
|
||||
#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
|
||||
#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
|
||||
#define MAX_DMA_LEN 8191
|
||||
|
||||
/*
|
||||
* for testing SSCR1 changes that require SSP restart, basically
|
||||
|
|
@ -144,7 +145,6 @@ struct driver_data {
|
|||
size_t tx_map_len;
|
||||
u8 n_bytes;
|
||||
u32 dma_width;
|
||||
int cs_change;
|
||||
int (*write)(struct driver_data *drv_data);
|
||||
int (*read)(struct driver_data *drv_data);
|
||||
irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
|
||||
|
|
@ -406,8 +406,45 @@ static void giveback(struct driver_data *drv_data)
|
|||
struct spi_transfer,
|
||||
transfer_list);
|
||||
|
||||
/* Delay if requested before any change in chip select */
|
||||
if (last_transfer->delay_usecs)
|
||||
udelay(last_transfer->delay_usecs);
|
||||
|
||||
/* Drop chip select UNLESS cs_change is true or we are returning
|
||||
* a message with an error, or next message is for another chip
|
||||
*/
|
||||
if (!last_transfer->cs_change)
|
||||
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
||||
else {
|
||||
struct spi_message *next_msg;
|
||||
|
||||
/* Holding of cs was hinted, but we need to make sure
|
||||
* the next message is for the same chip. Don't waste
|
||||
* time with the following tests unless this was hinted.
|
||||
*
|
||||
* We cannot postpone this until pump_messages, because
|
||||
* after calling msg->complete (below) the driver that
|
||||
* sent the current message could be unloaded, which
|
||||
* could invalidate the cs_control() callback...
|
||||
*/
|
||||
|
||||
/* get a pointer to the next message, if any */
|
||||
spin_lock_irqsave(&drv_data->lock, flags);
|
||||
if (list_empty(&drv_data->queue))
|
||||
next_msg = NULL;
|
||||
else
|
||||
next_msg = list_entry(drv_data->queue.next,
|
||||
struct spi_message, queue);
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
|
||||
/* see if the next and current messages point
|
||||
* to the same chip
|
||||
*/
|
||||
if (next_msg && next_msg->spi != msg->spi)
|
||||
next_msg = NULL;
|
||||
if (!next_msg || msg->state == ERROR_STATE)
|
||||
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
||||
}
|
||||
|
||||
msg->state = NULL;
|
||||
if (msg->complete)
|
||||
|
|
@ -490,10 +527,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
|
|||
msg->actual_length += drv_data->len -
|
||||
(drv_data->rx_end - drv_data->rx);
|
||||
|
||||
/* Release chip select if requested, transfer delays are
|
||||
* handled in pump_transfers */
|
||||
if (drv_data->cs_change)
|
||||
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
||||
/* Transfer delays and chip select release are
|
||||
* handled in pump_transfers or giveback
|
||||
*/
|
||||
|
||||
/* Move to next transfer */
|
||||
msg->state = next_transfer(drv_data);
|
||||
|
|
@ -602,10 +638,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
|
|||
drv_data->cur_msg->actual_length += drv_data->len -
|
||||
(drv_data->rx_end - drv_data->rx);
|
||||
|
||||
/* Release chip select if requested, transfer delays are
|
||||
* handled in pump_transfers */
|
||||
if (drv_data->cs_change)
|
||||
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
||||
/* Transfer delays and chip select release are
|
||||
* handled in pump_transfers or giveback
|
||||
*/
|
||||
|
||||
/* Move to next transfer */
|
||||
drv_data->cur_msg->state = next_transfer(drv_data);
|
||||
|
|
@ -840,23 +875,40 @@ static void pump_transfers(unsigned long data)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Delay if requested at end of transfer*/
|
||||
/* Delay if requested at end of transfer before CS change */
|
||||
if (message->state == RUNNING_STATE) {
|
||||
previous = list_entry(transfer->transfer_list.prev,
|
||||
struct spi_transfer,
|
||||
transfer_list);
|
||||
if (previous->delay_usecs)
|
||||
udelay(previous->delay_usecs);
|
||||
|
||||
/* Drop chip select only if cs_change is requested */
|
||||
if (previous->cs_change)
|
||||
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
||||
}
|
||||
|
||||
/* Check transfer length */
|
||||
if (transfer->len > 8191)
|
||||
{
|
||||
dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
|
||||
"length greater than 8191\n");
|
||||
message->status = -EINVAL;
|
||||
giveback(drv_data);
|
||||
return;
|
||||
/* Check for transfers that need multiple DMA segments */
|
||||
if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
|
||||
|
||||
/* reject already-mapped transfers; PIO won't always work */
|
||||
if (message->is_dma_mapped
|
||||
|| transfer->rx_dma || transfer->tx_dma) {
|
||||
dev_err(&drv_data->pdev->dev,
|
||||
"pump_transfers: mapped transfer length "
|
||||
"of %u is greater than %d\n",
|
||||
transfer->len, MAX_DMA_LEN);
|
||||
message->status = -EINVAL;
|
||||
giveback(drv_data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* warn ... we force this to PIO mode */
|
||||
if (printk_ratelimit())
|
||||
dev_warn(&message->spi->dev, "pump_transfers: "
|
||||
"DMA disabled for transfer length %ld "
|
||||
"greater than %d\n",
|
||||
(long)drv_data->len, MAX_DMA_LEN);
|
||||
}
|
||||
|
||||
/* Setup the transfer state based on the type of transfer */
|
||||
|
|
@ -878,7 +930,6 @@ static void pump_transfers(unsigned long data)
|
|||
drv_data->len = transfer->len & DCMD_LENGTH;
|
||||
drv_data->write = drv_data->tx ? chip->write : null_writer;
|
||||
drv_data->read = drv_data->rx ? chip->read : null_reader;
|
||||
drv_data->cs_change = transfer->cs_change;
|
||||
|
||||
/* Change speed and bit per word on a per transfer */
|
||||
cr0 = chip->cr0;
|
||||
|
|
@ -925,7 +976,7 @@ static void pump_transfers(unsigned long data)
|
|||
&dma_thresh))
|
||||
if (printk_ratelimit())
|
||||
dev_warn(&message->spi->dev,
|
||||
"pump_transfer: "
|
||||
"pump_transfers: "
|
||||
"DMA burst size reduced to "
|
||||
"match bits_per_word\n");
|
||||
}
|
||||
|
|
@ -939,8 +990,23 @@ static void pump_transfers(unsigned long data)
|
|||
|
||||
message->state = RUNNING_STATE;
|
||||
|
||||
/* Try to map dma buffer and do a dma transfer if successful */
|
||||
if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
|
||||
/* Try to map dma buffer and do a dma transfer if successful, but
|
||||
* only if the length is non-zero and less than MAX_DMA_LEN.
|
||||
*
|
||||
* Zero-length non-descriptor DMA is illegal on PXA2xx; force use
|
||||
* of PIO instead. Care is needed above because the transfer may
|
||||
* have have been passed with buffers that are already dma mapped.
|
||||
* A zero-length transfer in PIO mode will not try to write/read
|
||||
* to/from the buffers
|
||||
*
|
||||
* REVISIT large transfers are exactly where we most want to be
|
||||
* using DMA. If this happens much, split those transfers into
|
||||
* multiple DMA segments rather than forcing PIO.
|
||||
*/
|
||||
drv_data->dma_mapped = 0;
|
||||
if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
|
||||
drv_data->dma_mapped = map_dma_buffers(drv_data);
|
||||
if (drv_data->dma_mapped) {
|
||||
|
||||
/* Ensure we have the correct interrupt handler */
|
||||
drv_data->transfer_handler = dma_transfer;
|
||||
|
|
|
|||
|
|
@ -267,16 +267,13 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
|
|||
cs->hw_mode |= SPMODE_LEN(bits_per_word);
|
||||
|
||||
if ((mpc83xx_spi->spibrg / hz) > 64) {
|
||||
cs->hw_mode |= SPMODE_DIV16;
|
||||
pm = mpc83xx_spi->spibrg / (hz * 64);
|
||||
if (pm > 16) {
|
||||
cs->hw_mode |= SPMODE_DIV16;
|
||||
pm /= 16;
|
||||
if (pm > 16) {
|
||||
dev_err(&spi->dev, "Requested speed is too "
|
||||
"low: %d Hz. Will use %d Hz instead.\n",
|
||||
hz, mpc83xx_spi->spibrg / 1024);
|
||||
pm = 16;
|
||||
}
|
||||
dev_err(&spi->dev, "Requested speed is too "
|
||||
"low: %d Hz. Will use %d Hz instead.\n",
|
||||
hz, mpc83xx_spi->spibrg / 1024);
|
||||
pm = 16;
|
||||
}
|
||||
} else
|
||||
pm = mpc83xx_spi->spibrg / (hz * 4);
|
||||
|
|
@ -315,11 +312,20 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
|
|||
if (t->bits_per_word)
|
||||
bits_per_word = t->bits_per_word;
|
||||
len = t->len;
|
||||
if (bits_per_word > 8)
|
||||
if (bits_per_word > 8) {
|
||||
/* invalid length? */
|
||||
if (len & 1)
|
||||
return -EINVAL;
|
||||
len /= 2;
|
||||
if (bits_per_word > 16)
|
||||
}
|
||||
if (bits_per_word > 16) {
|
||||
/* invalid length? */
|
||||
if (len & 1)
|
||||
return -EINVAL;
|
||||
len /= 2;
|
||||
}
|
||||
mpc83xx_spi->count = len;
|
||||
|
||||
INIT_COMPLETION(mpc83xx_spi->done);
|
||||
|
||||
/* enable rx ints */
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
|
|||
#endif
|
||||
|
||||
MODULE_ALIAS("platform:s3c2410-spi");
|
||||
static struct platform_driver s3c24xx_spidrv = {
|
||||
static struct platform_driver s3c24xx_spi_driver = {
|
||||
.remove = __exit_p(s3c24xx_spi_remove),
|
||||
.suspend = s3c24xx_spi_suspend,
|
||||
.resume = s3c24xx_spi_resume,
|
||||
|
|
@ -442,12 +442,12 @@ static struct platform_driver s3c24xx_spidrv = {
|
|||
|
||||
static int __init s3c24xx_spi_init(void)
|
||||
{
|
||||
return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
|
||||
return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
|
||||
}
|
||||
|
||||
static void __exit s3c24xx_spi_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c24xx_spidrv);
|
||||
platform_driver_unregister(&s3c24xx_spi_driver);
|
||||
}
|
||||
|
||||
module_init(s3c24xx_spi_init);
|
||||
|
|
|
|||
Loading…
Reference in a new issue