diff options
Diffstat (limited to 'drivers/staging/goldfish')
| -rw-r--r-- | drivers/staging/goldfish/README | 1 | ||||
| -rw-r--r-- | drivers/staging/goldfish/goldfish_audio.c | 23 | ||||
| -rw-r--r-- | drivers/staging/goldfish/goldfish_nand.c | 27 | ||||
| -rw-r--r-- | drivers/staging/goldfish/goldfish_nand_reg.h | 3 |
4 files changed, 31 insertions, 23 deletions
diff --git a/drivers/staging/goldfish/README b/drivers/staging/goldfish/README index 93d65b0f0f8..183af005323 100644 --- a/drivers/staging/goldfish/README +++ b/drivers/staging/goldfish/README @@ -5,7 +5,6 @@ Audio NAND ---- -- Switch from spinlock to mutex - Remove excess checking of parameters in calls - Use dma coherent memory not kmalloc/__pa for the memory (this is just a cleanliness issue not a correctness one) diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index f96dcec740a..cbd456770af 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <linux/dma-mapping.h> #include <linux/uaccess.h> +#include <linux/goldfish.h> MODULE_AUTHOR("Google, Inc."); MODULE_DESCRIPTION("Android QEMU Audio Driver"); @@ -60,6 +61,8 @@ struct goldfish_audio { #define AUDIO_READ(data, addr) (readl(data->reg_base + addr)) #define AUDIO_WRITE(data, addr, x) (writel(x, data->reg_base + addr)) +#define AUDIO_WRITE64(data, addr, addr2, x) \ + (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) /* * temporary variable used between goldfish_audio_probe() and @@ -78,11 +81,14 @@ enum { /* set number of bytes in buffer to write */ AUDIO_WRITE_BUFFER_1 = 0x10, AUDIO_WRITE_BUFFER_2 = 0x14, + AUDIO_SET_WRITE_BUFFER_1_HIGH = 0x28, + AUDIO_SET_WRITE_BUFFER_2_HIGH = 0x30, /* true if audio input is supported */ AUDIO_READ_SUPPORTED = 0x18, /* buffer to use for audio input */ AUDIO_SET_READ_BUFFER = 0x1C, + AUDIO_SET_READ_BUFFER_HIGH = 0x34, /* driver writes number of bytes to read */ AUDIO_START_READ = 0x20, @@ -147,6 +153,7 @@ static ssize_t goldfish_audio_write(struct file *fp, const char __user *buf, while (count > 0) { ssize_t copy = count; + if (copy > WRITE_BUFFER_SIZE) copy = WRITE_BUFFER_SIZE; wait_event_interruptible(data->wait, (data->buffer_status & @@ -321,19 +328,25 @@ static int goldfish_audio_probe(struct platform_device *pdev) goto err_misc_register_failed; } - AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_1, buf_addr); - AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_2, - buf_addr + WRITE_BUFFER_SIZE); + AUDIO_WRITE64(data, AUDIO_SET_WRITE_BUFFER_1, + AUDIO_SET_WRITE_BUFFER_1_HIGH, buf_addr); + buf_addr += WRITE_BUFFER_SIZE; + + AUDIO_WRITE64(data, AUDIO_SET_WRITE_BUFFER_2, + AUDIO_SET_WRITE_BUFFER_2_HIGH, buf_addr); + + buf_addr += WRITE_BUFFER_SIZE; data->read_supported = AUDIO_READ(data, AUDIO_READ_SUPPORTED); if (data->read_supported) - AUDIO_WRITE(data, AUDIO_SET_READ_BUFFER, - buf_addr + 2 * WRITE_BUFFER_SIZE); + AUDIO_WRITE64(data, AUDIO_SET_READ_BUFFER, + AUDIO_SET_READ_BUFFER_HIGH, buf_addr); audio_data = data; return 0; err_misc_register_failed: + free_irq(data->irq, data); err_request_irq_failed: dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE, data->buffer_virt, data->buffer_phys); diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c index 81e2ad4038f..092604c698b 100644 --- a/drivers/staging/goldfish/goldfish_nand.c +++ b/drivers/staging/goldfish/goldfish_nand.c @@ -22,16 +22,16 @@ #include <linux/slab.h> #include <linux/ioport.h> #include <linux/vmalloc.h> -#include <linux/init.h> #include <linux/mtd/mtd.h> #include <linux/platform_device.h> - +#include <linux/mutex.h> +#include <linux/goldfish.h> #include <asm/div64.h> #include "goldfish_nand_reg.h" struct goldfish_nand { - spinlock_t lock; + struct mutex lock; unsigned char __iomem *base; struct cmd_params *cmd_params; size_t mtd_count; @@ -67,7 +67,7 @@ static u32 goldfish_nand_cmd_with_params(struct mtd_info *mtd, cps->addr_high = (u32)(addr >> 32); cps->addr_low = (u32)addr; cps->transfer_size = len; - cps->data = (u32)ptr; + cps->data = (unsigned long)ptr; writel(cmdp, base + NAND_COMMAND); *rv = cps->result; return 0; @@ -78,20 +78,19 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, { struct goldfish_nand *nand = mtd->priv; u32 rv; - unsigned long irq_flags; unsigned char __iomem *base = nand->base; - spin_lock_irqsave(&nand->lock, irq_flags); + mutex_lock(&nand->lock); if (goldfish_nand_cmd_with_params(mtd, cmd, addr, len, ptr, &rv)) { writel(mtd - nand->mtd, base + NAND_DEV); writel((u32)(addr >> 32), base + NAND_ADDR_HIGH); writel((u32)addr, base + NAND_ADDR_LOW); writel(len, base + NAND_TRANSFER_SIZE); - writel((u32)ptr, base + NAND_DATA); + gf_write64((u64)ptr, base + NAND_DATA, base + NAND_DATA_HIGH); writel(cmd, base + NAND_COMMAND); rv = readl(base + NAND_RESULT); } - spin_unlock_irqrestore(&nand->lock, irq_flags); + mutex_unlock(&nand->lock); return rv; } @@ -200,8 +199,6 @@ static int goldfish_nand_read(struct mtd_info *mtd, loff_t from, size_t len, if (from + len > mtd->size) goto invalid_arg; - if (len != mtd->writesize) - goto invalid_arg; rem = do_div(from, mtd->writesize); if (rem) @@ -224,8 +221,6 @@ static int goldfish_nand_write(struct mtd_info *mtd, loff_t to, size_t len, if (to + len > mtd->size) goto invalid_arg; - if (len != mtd->writesize) - goto invalid_arg; rem = do_div(to, mtd->writesize); if (rem) @@ -308,12 +303,11 @@ static int goldfish_nand_init_device(struct platform_device *pdev, u32 name_len; u32 result; u32 flags; - unsigned long irq_flags; unsigned char __iomem *base = nand->base; struct mtd_info *mtd = &nand->mtd[id]; char *name; - spin_lock_irqsave(&nand->lock, irq_flags); + mutex_lock(&nand->lock); writel(id, base + NAND_DEV); flags = readl(base + NAND_DEV_FLAGS); name_len = readl(base + NAND_DEV_NAME_LEN); @@ -330,7 +324,7 @@ static int goldfish_nand_init_device(struct platform_device *pdev, "goldfish nand dev%d: size %llx, page %d, extra %d, erase %d\n", id, mtd->size, mtd->writesize, mtd->oobsize, mtd->erasesize); - spin_unlock_irqrestore(&nand->lock, irq_flags); + mutex_unlock(&nand->lock); mtd->priv = nand; @@ -406,7 +400,7 @@ static int goldfish_nand_probe(struct platform_device *pdev) if (nand == NULL) return -ENOMEM; - spin_lock_init(&nand->lock); + mutex_init(&nand->lock); nand->base = base; nand->mtd_count = num_dev; platform_set_drvdata(pdev, nand); @@ -426,6 +420,7 @@ static int goldfish_nand_remove(struct platform_device *pdev) { struct goldfish_nand *nand = platform_get_drvdata(pdev); int i; + for (i = 0; i < nand->mtd_count; i++) { if (nand->mtd[i].name) mtd_device_unregister(&nand->mtd[i]); diff --git a/drivers/staging/goldfish/goldfish_nand_reg.h b/drivers/staging/goldfish/goldfish_nand_reg.h index ddfda71ab27..fe7f47c7a5c 100644 --- a/drivers/staging/goldfish/goldfish_nand_reg.h +++ b/drivers/staging/goldfish/goldfish_nand_reg.h @@ -57,6 +57,7 @@ enum nand_reg { NAND_RESULT = 0x040, NAND_COMMAND = 0x044, NAND_DATA = 0x048, + NAND_DATA_HIGH = 0x100, NAND_TRANSFER_SIZE = 0x04c, NAND_ADDR_LOW = 0x050, NAND_ADDR_HIGH = 0x054, @@ -69,7 +70,7 @@ struct cmd_params { uint32_t addr_low; uint32_t addr_high; uint32_t transfer_size; - uint32_t data; + unsigned long data; uint32_t result; }; #endif |
