summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/raw/r852.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/raw/r852.c')
-rw-r--r--drivers/mtd/nand/raw/r852.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/drivers/mtd/nand/raw/r852.c b/drivers/mtd/nand/raw/r852.c
index f865e3a47b01..918974d088cf 100644
--- a/drivers/mtd/nand/raw/r852.c
+++ b/drivers/mtd/nand/raw/r852.c
@@ -335,7 +335,7 @@ static void r852_cmdctl(struct nand_chip *chip, int dat, unsigned int ctrl)
else
dev->ctlreg &= ~R852_CTL_WRITE;
- /* when write is stareted, enable write access */
+ /* when write is started, enable write access */
if (dat == NAND_CMD_ERASE1)
dev->ctlreg |= R852_CTL_WRITE;
@@ -372,7 +372,7 @@ static int r852_wait(struct nand_chip *chip)
nand_status_op(chip, &status);
- /* Unfortunelly, no way to send detailed error status... */
+ /* Unfortunately, no way to send detailed error status... */
if (dev->dma_error) {
status |= NAND_STATUS_FAIL;
dev->dma_error = 0;
@@ -387,6 +387,9 @@ static int r852_wait(struct nand_chip *chip)
static int r852_ready(struct nand_chip *chip)
{
struct r852_device *dev = r852_get_dev(nand_to_mtd(chip));
+ if (dev->card_unstable)
+ return 0;
+
return !(r852_read_reg(dev, R852_CARD_STA) & R852_CARD_STA_BUSY);
}
@@ -583,8 +586,8 @@ static void r852_update_card_detect(struct r852_device *dev)
r852_write_reg(dev, R852_CARD_IRQ_ENABLE, card_detect_reg);
}
-static ssize_t r852_media_type_show(struct device *sys_dev,
- struct device_attribute *attr, char *buf)
+static ssize_t media_type_show(struct device *sys_dev,
+ struct device_attribute *attr, char *buf)
{
struct mtd_info *mtd = container_of(sys_dev, struct mtd_info, dev);
struct r852_device *dev = r852_get_dev(mtd);
@@ -593,8 +596,7 @@ static ssize_t r852_media_type_show(struct device *sys_dev,
strcpy(buf, data);
return strlen(data);
}
-
-static DEVICE_ATTR(media_type, S_IRUGO, r852_media_type_show, NULL);
+static DEVICE_ATTR_RO(media_type);
/* Detect properties of card in slot */
@@ -724,10 +726,9 @@ static irqreturn_t r852_irq(int irq, void *data)
struct r852_device *dev = (struct r852_device *)data;
uint8_t card_status, dma_status;
- unsigned long flags;
irqreturn_t ret = IRQ_NONE;
- spin_lock_irqsave(&dev->irqlock, flags);
+ spin_lock(&dev->irqlock);
/* handle card detection interrupts first */
card_status = r852_read_reg(dev, R852_CARD_IRQ_STA);
@@ -813,10 +814,33 @@ static irqreturn_t r852_irq(int irq, void *data)
dbg("strange card status = %x", card_status);
out:
- spin_unlock_irqrestore(&dev->irqlock, flags);
+ spin_unlock(&dev->irqlock);
return ret;
}
+static int r852_attach_chip(struct nand_chip *chip)
+{
+ if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
+ return 0;
+
+ chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
+ chip->ecc.size = R852_DMA_LEN;
+ chip->ecc.bytes = SM_OOB_SIZE;
+ chip->ecc.strength = 2;
+ chip->ecc.hwctl = r852_ecc_hwctl;
+ chip->ecc.calculate = r852_ecc_calculate;
+ chip->ecc.correct = r852_ecc_correct;
+
+ /* TODO: hack */
+ chip->ecc.read_oob = r852_read_oob;
+
+ return 0;
+}
+
+static const struct nand_controller_ops r852_ops = {
+ .attach_chip = r852_attach_chip,
+};
+
static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
{
int error;
@@ -858,18 +882,6 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
chip->legacy.read_buf = r852_read_buf;
chip->legacy.write_buf = r852_write_buf;
- /* ecc */
- chip->ecc.mode = NAND_ECC_HW_SYNDROME;
- chip->ecc.size = R852_DMA_LEN;
- chip->ecc.bytes = SM_OOB_SIZE;
- chip->ecc.strength = 2;
- chip->ecc.hwctl = r852_ecc_hwctl;
- chip->ecc.calculate = r852_ecc_calculate;
- chip->ecc.correct = r852_ecc_correct;
-
- /* TODO: hack */
- chip->ecc.read_oob = r852_read_oob;
-
/* init our device structure */
dev = kzalloc(sizeof(struct r852_device), GFP_KERNEL);
@@ -881,6 +893,10 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
dev->pci_dev = pci_dev;
pci_set_drvdata(pci_dev, dev);
+ nand_controller_init(&dev->controller);
+ dev->controller.ops = &r852_ops;
+ chip->controller = &dev->controller;
+
dev->bounce_buffer = dma_alloc_coherent(&pci_dev->dev, R852_DMA_LEN,
&dev->phys_bounce_buffer, GFP_KERNEL);