X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fspi%2Fpxa2xx_spi.c;h=147e26a78d648c5d343454de8fca05f200faccac;hb=5eb691805f7ec5960fe9d5d7fc57a7fc3097bbd0;hp=eb817b8eb02439eeb12944e89fc2f55749adc009;hpb=2f1a74e5a2de0459139b85af95e901448726c375;p=linux-2.6-omap-h63xx.git diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index eb817b8eb02..147e26a78d6 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -44,6 +44,7 @@ MODULE_AUTHOR("Stephen Street"); MODULE_DESCRIPTION("PXA2xx SSP SPI Controller"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-spi"); #define MAX_BUSES 3 @@ -51,13 +52,19 @@ MODULE_LICENSE("GPL"); #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) -/* for testing SSCR1 changes that require SSP restart, basically - * everything except the service and interrupt enables */ -#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \ +/* + * for testing SSCR1 changes that require SSP restart, basically + * everything except the service and interrupt enables, the pxa270 developer + * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this + * list, but the PXA255 dev man says all bits without really meaning the + * service and interrupt enables + */ +#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ - | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \ - | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \ - | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) + | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ + | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ + | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ + | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) #define DEFINE_SSP_REG(reg, off) \ static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ @@ -973,9 +980,6 @@ static void pump_transfers(unsigned long data) if (drv_data->ssp_type == PXA25x_SSP) DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status and start DMA engine */ cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -985,9 +989,6 @@ static void pump_transfers(unsigned long data) /* Ensure we have the correct interrupt handler */ drv_data->transfer_handler = interrupt_transfer; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status */ cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -998,16 +999,29 @@ static void pump_transfers(unsigned long data) || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != (cr1 & SSCR1_CHANGE_MASK)) { + /* stop the SSP, and update the other bits */ write_SSCR0(cr0 & ~SSCR0_SSE, reg); if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); + /* first set CR1 without interrupt and service enables */ + write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); + /* restart the SSP */ write_SSCR0(cr0, reg); + } else { if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); } + + /* FIXME, need to handle cs polarity, + * this driver uses struct pxa2xx_spi_chip.cs_control to + * specify a CS handling function, and it ignores most + * struct spi_device.mode[s], including SPI_CS_HIGH */ + drv_data->cs_control(PXA2XX_CS_ASSERT); + + /* after chip select, release the data by enabling service + * requests and interrupts, without changing any mode bits */ + write_SSCR1(cr1, reg); } static void pump_messages(struct work_struct *work) @@ -1526,17 +1540,6 @@ static void pxa2xx_spi_shutdown(struct platform_device *pdev) } #ifdef CONFIG_PM -static int suspend_devices(struct device *dev, void *pm_message) -{ - pm_message_t *state = pm_message; - - if (dev->power.power_state.event != state->event) { - dev_warn(dev, "pm state does not match request\n"); - return -1; - } - - return 0; -} static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) { @@ -1544,12 +1547,6 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) struct ssp_device *ssp = drv_data->ssp; int status = 0; - /* Check all childern for current power state */ - if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) { - dev_warn(&pdev->dev, "suspend aborted\n"); - return -1; - } - status = stop_queue(drv_data); if (status != 0) return status; @@ -1585,7 +1582,6 @@ static int pxa2xx_spi_resume(struct platform_device *pdev) static struct platform_driver driver = { .driver = { .name = "pxa2xx-spi", - .bus = &platform_bus_type, .owner = THIS_MODULE, }, .remove = pxa2xx_spi_remove,