Skip to content

Commit

Permalink
MTD: nand: jz4740: supply memory bank address through platform resource
Browse files Browse the repository at this point in the history
  • Loading branch information
larsclausen committed Jul 14, 2010
1 parent d2d5cee commit 1b3e64a
Showing 1 changed file with 61 additions and 33 deletions.
94 changes: 61 additions & 33 deletions drivers/mtd/nand/jz4740_nand.c
Expand Up @@ -52,16 +52,15 @@
#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT(x << 1) #define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT(x << 1)
#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT((x << 1) + 1) #define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT((x << 1) + 1)


#define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
#define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
#define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)

struct jz_nand { struct jz_nand {
struct mtd_info mtd; struct mtd_info mtd;
struct nand_chip chip; struct nand_chip chip;
void __iomem *base; void __iomem *base;
struct resource *mem; struct resource *mem;


void __iomem *bank_base;
struct resource *bank_mem;

struct jz_nand_platform_data *pdata; struct jz_nand_platform_data *pdata;
bool is_reading; bool is_reading;
}; };
Expand All @@ -71,6 +70,9 @@ static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
return container_of(mtd, struct jz_nand, mtd); return container_of(mtd, struct jz_nand, mtd);
} }


#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
#define JZ_NAND_MEM_CMD_OFFSET 0x08000

static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
{ {
struct jz_nand *nand = mtd_to_jz_nand(mtd); struct jz_nand *nand = mtd_to_jz_nand(mtd);
Expand All @@ -80,11 +82,11 @@ static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_CTRL_CHANGE) {
BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE)); BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
if (ctrl & NAND_ALE) if (ctrl & NAND_ALE)
chip->IO_ADDR_W = JZ_NAND_ADDR_ADDR; chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_ADDR_OFFSET;
else if (ctrl & NAND_CLE) else if (ctrl & NAND_CLE)
chip->IO_ADDR_W = JZ_NAND_CMD_ADDR; chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_CMD_OFFSET;
else else
chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; chip->IO_ADDR_W = nand->bank_base;


reg = readl(nand->base + JZ_REG_NAND_CTRL); reg = readl(nand->base + JZ_REG_NAND_CTRL);
if (ctrl & NAND_NCE) if (ctrl & NAND_NCE)
Expand Down Expand Up @@ -296,6 +298,43 @@ static void jz_nand_write_page_hwecc(struct mtd_info *mtd,
static const char *part_probes[] = {"cmdline", NULL}; static const char *part_probes[] = {"cmdline", NULL};
#endif #endif


static int jz_nand_ioremap_resource(struct platform_device *pdev,
const char *name, struct resource **res, void __iomem **base)
{
int ret;

*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
if (!*res) {
dev_err(&pdev->dev, "Failed to get platform %s memory\n", name);
ret = -ENXIO;
goto err;
}

*res = request_mem_region((*res)->start, resource_size(*res),
pdev->name);
if (!*res) {
dev_err(&pdev->dev, "Failed to request %s memory region\n", name);
ret = -EBUSY;
goto err;
}

*base = ioremap((*res)->start, resource_size(*res));
if (!*base) {
dev_err(&pdev->dev, "Failed to ioremap %s memory region\n", name);
ret = -EBUSY;
goto err_release_mem;
}

return 0;

err_release_mem:
release_mem_region((*res)->start, resource_size(*res));
err:
*res = NULL;
*base = NULL;
return ret;
}

static int __devinit jz_nand_probe(struct platform_device *pdev) static int __devinit jz_nand_probe(struct platform_device *pdev)
{ {
int ret; int ret;
Expand All @@ -314,35 +353,21 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }


nand->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
if (!nand->mem) { if (ret)
dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
ret = -ENXIO;
goto err_free; goto err_free;
} ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,

&nand->bank_base);
nand->mem = request_mem_region(nand->mem->start, if (ret)
resource_size(nand->mem), pdev->name); goto err_iounmap_mmio;
if (!nand->mem) {
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
ret = -EBUSY;
goto err_free;
}

nand->base = ioremap(nand->mem->start, resource_size(nand->mem));
if (!nand->base) {
dev_err(&pdev->dev, "Failed to ioremap mmio memory region\n");
ret = -EBUSY;
goto err_release_mem;
}


if (pdata && gpio_is_valid(pdata->busy_gpio)) { if (pdata && gpio_is_valid(pdata->busy_gpio)) {
ret = gpio_request(pdata->busy_gpio, "NAND busy pin"); ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Failed to request busy gpio %d: %d\n", "Failed to request busy gpio %d: %d\n",
pdata->busy_gpio, ret); pdata->busy_gpio, ret);
goto err_iounmap; goto err_iounmap_mem;
} }
} }


Expand Down Expand Up @@ -371,8 +396,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
if (pdata && gpio_is_valid(pdata->busy_gpio)) if (pdata && gpio_is_valid(pdata->busy_gpio))
chip->dev_ready = jz_nand_dev_ready; chip->dev_ready = jz_nand_dev_ready;


chip->IO_ADDR_R = JZ_NAND_DATA_ADDR; chip->IO_ADDR_R = nand->bank_base;
chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; chip->IO_ADDR_W = nand->bank_base;


nand->pdata = pdata; nand->pdata = pdata;
platform_set_drvdata(pdev, nand); platform_set_drvdata(pdev, nand);
Expand Down Expand Up @@ -418,15 +443,16 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n"); dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n");


return 0; return 0;

err_nand_release: err_nand_release:
nand_release(&nand->mtd); nand_release(&nand->mtd);
err_gpio_free: err_gpio_free:
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
gpio_free(pdata->busy_gpio); gpio_free(pdata->busy_gpio);
err_iounmap: err_iounmap_mem:
iounmap(nand->bank_base);
err_iounmap_mmio:
iounmap(nand->base); iounmap(nand->base);
err_release_mem:
release_mem_region(nand->mem->start, resource_size(nand->mem));
err_free: err_free:
kfree(nand); kfree(nand);
return ret; return ret;
Expand All @@ -438,6 +464,8 @@ static int __devexit jz_nand_remove(struct platform_device *pdev)


nand_release(&nand->mtd); nand_release(&nand->mtd);


iounmap(nand->bank_base);
release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem));
iounmap(nand->base); iounmap(nand->base);
release_mem_region(nand->mem->start, resource_size(nand->mem)); release_mem_region(nand->mem->start, resource_size(nand->mem));


Expand Down

0 comments on commit 1b3e64a

Please sign in to comment.