diff options
Diffstat (limited to 'drivers/spi/spi-sh.c')
| -rw-r--r-- | drivers/spi/spi-sh.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c index 70c8af9f7cc..03edf5ed0e9 100644 --- a/drivers/spi/spi-sh.c +++ b/drivers/spi/spi-sh.c @@ -92,17 +92,26 @@ struct spi_sh_data { unsigned long cr1; wait_queue_head_t wait; spinlock_t lock; + int width; }; static void spi_sh_write(struct spi_sh_data *ss, unsigned long data, unsigned long offset) { - writel(data, ss->addr + offset); + if (ss->width == 8) + iowrite8(data, ss->addr + (offset >> 2)); + else if (ss->width == 32) + iowrite32(data, ss->addr + offset); } static unsigned long spi_sh_read(struct spi_sh_data *ss, unsigned long offset) { - return readl(ss->addr + offset); + if (ss->width == 8) + return ioread8(ss->addr + (offset >> 2)); + else if (ss->width == 32) + return ioread32(ss->addr + offset); + else + return 0; } static void spi_sh_set_bit(struct spi_sh_data *ss, unsigned long val, @@ -162,7 +171,6 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, int remain = t->len; int cur_len; unsigned char *data; - unsigned long tmp; long ret; if (t->len) @@ -204,9 +212,7 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, } if (list_is_last(&t->transfer_list, &mesg->transfers)) { - tmp = spi_sh_read(ss, SPI_SH_CR1); - tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); - spi_sh_write(ss, tmp, SPI_SH_CR1); + spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1); spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); ss->cr1 &= ~SPI_SH_TBE; @@ -230,7 +236,6 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, int remain = t->len; int cur_len; unsigned char *data; - unsigned long tmp; long ret; if (t->len > SPI_SH_MAX_BYTE) @@ -238,9 +243,7 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, else spi_sh_write(ss, t->len, SPI_SH_CR3); - tmp = spi_sh_read(ss, SPI_SH_CR1); - tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); - spi_sh_write(ss, tmp, SPI_SH_CR1); + spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1); spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); spi_sh_wait_write_buffer_empty(ss); @@ -319,7 +322,8 @@ static void spi_sh_work(struct work_struct *work) spin_lock_irqsave(&ss->lock, flags); mesg->status = 0; - mesg->complete(mesg->context); + if (mesg->complete) + mesg->complete(mesg->context); } clear_fifo(ss); @@ -337,7 +341,8 @@ static void spi_sh_work(struct work_struct *work) error: mesg->status = ret; - mesg->complete(mesg->context); + if (mesg->complete) + mesg->complete(mesg->context); spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, SPI_SH_CR1); @@ -349,9 +354,6 @@ static int spi_sh_setup(struct spi_device *spi) { struct spi_sh_data *ss = spi_master_get_devdata(spi->master); - if (!spi->bits_per_word) - spi->bits_per_word = 8; - pr_debug("%s: enter\n", __func__); spi_sh_write(ss, 0xfe, SPI_SH_CR1); /* SPI sycle stop */ @@ -423,9 +425,9 @@ static irqreturn_t spi_sh_irq(int irq, void *_ss) return IRQ_HANDLED; } -static int __devexit spi_sh_remove(struct platform_device *pdev) +static int spi_sh_remove(struct platform_device *pdev) { - struct spi_sh_data *ss = dev_get_drvdata(&pdev->dev); + struct spi_sh_data *ss = platform_get_drvdata(pdev); spi_unregister_master(ss->master); destroy_workqueue(ss->workqueue); @@ -435,7 +437,7 @@ static int __devexit spi_sh_remove(struct platform_device *pdev) return 0; } -static int __devinit spi_sh_probe(struct platform_device *pdev) +static int spi_sh_probe(struct platform_device *pdev) { struct resource *res; struct spi_master *master; @@ -462,8 +464,20 @@ static int __devinit spi_sh_probe(struct platform_device *pdev) } ss = spi_master_get_devdata(master); - dev_set_drvdata(&pdev->dev, ss); - + platform_set_drvdata(pdev, ss); + + switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_8BIT: + ss->width = 8; + break; + case IORESOURCE_MEM_32BIT: + ss->width = 32; + break; + default: + dev_err(&pdev->dev, "No support width\n"); + ret = -ENODEV; + goto error1; + } ss->irq = irq; ss->master = master; ss->addr = ioremap(res->start, resource_size(res)); @@ -518,7 +532,7 @@ static int __devinit spi_sh_probe(struct platform_device *pdev) static struct platform_driver spi_sh_driver = { .probe = spi_sh_probe, - .remove = __devexit_p(spi_sh_remove), + .remove = spi_sh_remove, .driver = { .name = "sh_spi", .owner = THIS_MODULE, |
