return reg & mask;
}
-static inline void set_dma_type(struct gpmi_nand_data *this,
- enum dma_ops_type type)
-{
- this->last_dma_type = this->dma_type;
- this->dma_type = type;
-}
-
int gpmi_send_command(struct gpmi_nand_data *this)
{
struct dma_chan *channel = get_dma_chan(this);
struct dma_async_tx_descriptor *desc;
struct scatterlist *sgl;
int chip = this->current_chip;
+ int ret;
u32 pio[3];
/* [1] send out the PIO words */
return -EINVAL;
/* [3] submit the DMA */
- set_dma_type(this, DMA_FOR_COMMAND);
- return start_dma_without_bch_irq(this, desc);
+ ret = start_dma_without_bch_irq(this, desc);
+
+ dma_unmap_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
+
+ return ret;
}
int gpmi_send_data(struct gpmi_nand_data *this)
struct dma_async_tx_descriptor *desc;
struct dma_chan *channel = get_dma_chan(this);
int chip = this->current_chip;
+ int ret;
uint32_t command_mode;
uint32_t address;
u32 pio[2];
return -EINVAL;
/* [3] submit the DMA */
- set_dma_type(this, DMA_FOR_WRITE_DATA);
- return start_dma_without_bch_irq(this, desc);
+ ret = start_dma_without_bch_irq(this, desc);
+
+ dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE);
+
+ return ret;
}
int gpmi_read_data(struct gpmi_nand_data *this)
struct dma_async_tx_descriptor *desc;
struct dma_chan *channel = get_dma_chan(this);
int chip = this->current_chip;
+ int ret;
u32 pio[2];
/* [1] : send PIO */
return -EINVAL;
/* [3] : submit the DMA */
- set_dma_type(this, DMA_FOR_READ_DATA);
- return start_dma_without_bch_irq(this, desc);
+
+ ret = start_dma_without_bch_irq(this, desc);
+
+ dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE);
+ if (this->direct_dma_map_ok == false)
+ memcpy(this->upper_buf, this->data_buffer_dma, this->upper_len);
+
+ return ret;
}
int gpmi_send_page(struct gpmi_nand_data *this,
if (!desc)
return -EINVAL;
- set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
return start_dma_with_bch_irq(this, desc);
}
return -EINVAL;
/* [4] submit the DMA */
- set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
return start_dma_with_bch_irq(this, desc);
}
struct gpmi_nand_data *this = param;
struct completion *dma_c = &this->dma_done;
- switch (this->dma_type) {
- case DMA_FOR_COMMAND:
- dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE);
- break;
-
- case DMA_FOR_READ_DATA:
- dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE);
- if (this->direct_dma_map_ok == false)
- memcpy(this->upper_buf, this->data_buffer_dma,
- this->upper_len);
- break;
-
- case DMA_FOR_WRITE_DATA:
- dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE);
- break;
-
- case DMA_FOR_READ_ECC_PAGE:
- case DMA_FOR_WRITE_ECC_PAGE:
- /* We have to wait the BCH interrupt to finish. */
- break;
-
- default:
- dev_err(this->dev, "in wrong DMA operation.\n");
- }
-
complete(dma_c);
}
/* Wait for the interrupt from the DMA block. */
timeout = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000));
if (!timeout) {
- dev_err(this->dev, "DMA timeout, last DMA :%d\n",
- this->last_dma_type);
+ dev_err(this->dev, "DMA timeout, last DMA\n");
gpmi_dump_info(this);
return -ETIMEDOUT;
}
/* Wait for the interrupt from the BCH block. */
timeout = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000));
if (!timeout) {
- dev_err(this->dev, "BCH timeout, last DMA :%d\n",
- this->last_dma_type);
+ dev_err(this->dev, "BCH timeout\n");
gpmi_dump_info(this);
return -ETIMEDOUT;
}