* [PATCH v3 01/10] ARM: OMAP2+: gpmc: update nand register helper
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
@ 2012-08-21 9:41 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 02/10] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs Afzal Mohammed
` (8 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:41 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
Provide helper function for updating NAND register details for
the necessary chip select. NAND drivers platform data can be
updated with this information so that NAND driver can handle
GPMC NAND operations by itself.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 20 ++++++++++++++++++++
arch/arm/plat-omap/include/plat/gpmc.h | 18 ++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index b2b5759..5cce9b0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -682,6 +682,26 @@ int gpmc_prefetch_reset(int cs)
}
EXPORT_SYMBOL(gpmc_prefetch_reset);
+void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+{
+ reg->gpmc_status = gpmc_base + GPMC_STATUS;
+ reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
+ reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
+ reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
+ reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1;
+ reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2;
+ reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL;
+ reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS;
+ reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG;
+ reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
+ reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
+ reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
+ reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0;
+}
+
static void __init gpmc_mem_init(void)
{
int cs;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index f37764a..06198a5 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -133,6 +133,24 @@ struct gpmc_timings {
u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
};
+struct gpmc_nand_regs {
+ void __iomem *gpmc_status;
+ void __iomem *gpmc_nand_command;
+ void __iomem *gpmc_nand_address;
+ void __iomem *gpmc_nand_data;
+ void __iomem *gpmc_prefetch_config1;
+ void __iomem *gpmc_prefetch_config2;
+ void __iomem *gpmc_prefetch_control;
+ void __iomem *gpmc_prefetch_status;
+ void __iomem *gpmc_ecc_config;
+ void __iomem *gpmc_ecc_control;
+ void __iomem *gpmc_ecc_size_config;
+ void __iomem *gpmc_ecc1_result;
+ void __iomem *gpmc_bch_result0;
+};
+
+extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 02/10] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
2012-08-21 9:41 ` [PATCH v3 01/10] ARM: OMAP2+: gpmc: update nand register helper Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 03/10] mtd: nand: omap2: handle nand on gpmc Afzal Mohammed
` (7 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
GPMC has NAND registers, update nand platform data with those details
so that NAND driver can configure those by itself instead of using
exported symbols.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 2 ++
arch/arm/plat-omap/include/plat/nand.h | 1 +
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 386dec8..d4e803c 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -108,6 +108,8 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
}
+ gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
+
err = platform_device_register(&gpmc_nand_device);
if (err < 0) {
dev_err(dev, "Unable to register NAND device\n");
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index 67fc506..86e4d9c 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -29,6 +29,7 @@ struct omap_nand_platform_data {
unsigned long phys_base;
int devsize;
enum omap_ecc ecc_opt;
+ struct gpmc_nand_regs reg;
};
/* minimum size for IO mapping */
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 03/10] mtd: nand: omap2: handle nand on gpmc
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
2012-08-21 9:41 ` [PATCH v3 01/10] ARM: OMAP2+: gpmc: update nand register helper Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 02/10] ARM: OMAP2+: gpmc-nand: update gpmc-nand regs Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 04/10] ARM: OMAP2+: gpmc-nand: update resource with memory Afzal Mohammed
` (6 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
GPMC platform initialization has been modified to fill NAND
platform data with GPMC NAND register details. As these
registers are accessible in NAND driver itself, configure
NAND in GPMC by itself.
Modified prefetch and ecc functions are logically same as
the corresponding exported symbols from GPMC code.
Note: Verfying that other CS have not yet enabled for
prefetch & ecc has to be incorporated. Currently this
causes no issues as there are no boards that use NAND
on multiple CS. With ongoing GPMC driver migration,
perhaps it would be better to consider NAND connected
on multiple CS as a single peripheral using multiple CS.
This would make handling multiple CS issues easier.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
v2: simplify omap_prefetch_enable()
drivers/mtd/nand/omap2.c | 206 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 161 insertions(+), 45 deletions(-)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index e9309b3..8ddca98 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -101,6 +101,16 @@
#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
+#define PREFETCH_CONFIG1_CS_SHIFT 24
+#define ECC_CONFIG_CS_SHIFT 1
+#define CS_MASK 0x7
+#define ENABLE_PREFETCH (0x1 << 7)
+#define DMA_MPU_MODE_SHIFT 2
+#define ECCSIZE1_SHIFT 22
+#define ECC1RESULTSIZE 0x1
+#define ECCCLEAR 0x100
+#define ECC1 0x1
+
/* oob info generated runtime depending on ecc algorithm and layout selected */
static struct nand_ecclayout omap_oobinfo;
/* Define some generic bad / good block scan pattern which are used
@@ -133,6 +143,7 @@ struct omap_nand_info {
} iomode;
u_char *buf;
int buf_len;
+ struct gpmc_nand_regs reg;
#ifdef CONFIG_MTD_NAND_OMAP_BCH
struct bch_control *bch;
@@ -141,6 +152,63 @@ struct omap_nand_info {
};
/**
+ * omap_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @dma_mode: dma mode enable (1) or disable (0)
+ * @u32_count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode,
+ unsigned int u32_count, int is_write, struct omap_nand_info *info)
+{
+ u32 val;
+
+ if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
+ return -1;
+
+ if (readl(info->reg.gpmc_prefetch_control))
+ return -EBUSY;
+
+ /* Set the amount of bytes to be prefetched */
+ writel(u32_count, info->reg.gpmc_prefetch_config2);
+
+ /* Set dma/mpu mode, the prefetch read / post write and
+ * enable the engine. Set which cs is has requested for.
+ */
+ val = ((cs << PREFETCH_CONFIG1_CS_SHIFT) |
+ PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH |
+ (dma_mode << DMA_MPU_MODE_SHIFT) | (0x1 & is_write));
+ writel(val, info->reg.gpmc_prefetch_config1);
+
+ /* Start the prefetch engine */
+ writel(0x1, info->reg.gpmc_prefetch_control);
+
+ return 0;
+}
+
+/**
+ * omap_prefetch_reset - disables and stops the prefetch engine
+ */
+static int omap_prefetch_reset(int cs, struct omap_nand_info *info)
+{
+ u32 config1;
+
+ /* check if the same module/cs is trying to reset */
+ config1 = readl(info->reg.gpmc_prefetch_config1);
+ if (((config1 >> PREFETCH_CONFIG1_CS_SHIFT) & CS_MASK) != cs)
+ return -EINVAL;
+
+ /* Stop the PFPW engine */
+ writel(0x0, info->reg.gpmc_prefetch_control);
+
+ /* Reset/disable the PFPW engine */
+ writel(0x0, info->reg.gpmc_prefetch_config1);
+
+ return 0;
+}
+
+/**
* omap_hwcontrol - hardware specific access to control-lines
* @mtd: MTD device structure
* @cmd: command to device
@@ -158,13 +226,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
if (cmd != NAND_CMD_NONE) {
if (ctrl & NAND_CLE)
- gpmc_nand_write(info->gpmc_cs, GPMC_NAND_COMMAND, cmd);
+ writeb(cmd, info->reg.gpmc_nand_command);
else if (ctrl & NAND_ALE)
- gpmc_nand_write(info->gpmc_cs, GPMC_NAND_ADDRESS, cmd);
+ writeb(cmd, info->reg.gpmc_nand_address);
else /* NAND_NCE */
- gpmc_nand_write(info->gpmc_cs, GPMC_NAND_DATA, cmd);
+ writeb(cmd, info->reg.gpmc_nand_data);
}
}
@@ -198,7 +266,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
iowrite8(*p++, info->nand.IO_ADDR_W);
/* wait until buffer is available for write */
do {
- status = gpmc_read_status(GPMC_STATUS_BUFFER);
+ status = readl(info->reg.gpmc_status) &
+ GPMC_STATUS_BUFF_EMPTY;
} while (!status);
}
}
@@ -235,7 +304,8 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
iowrite16(*p++, info->nand.IO_ADDR_W);
/* wait until buffer is available for write */
do {
- status = gpmc_read_status(GPMC_STATUS_BUFFER);
+ status = readl(info->reg.gpmc_status) &
+ GPMC_STATUS_BUFF_EMPTY;
} while (!status);
}
}
@@ -265,8 +335,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
}
/* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs,
- PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0);
+ ret = omap_prefetch_enable(info->gpmc_cs,
+ PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0, info);
if (ret) {
/* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16)
@@ -275,14 +345,15 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
omap_read_buf8(mtd, (u_char *)p, len);
} else {
do {
- r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
+ r_count = readl(info->reg.gpmc_prefetch_status);
+ r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count);
r_count = r_count >> 2;
ioread32_rep(info->nand.IO_ADDR_R, p, r_count);
p += r_count;
len -= r_count << 2;
} while (len);
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset(info->gpmc_cs);
+ omap_prefetch_reset(info->gpmc_cs, info);
}
}
@@ -301,6 +372,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
int i = 0, ret = 0;
u16 *p = (u16 *)buf;
unsigned long tim, limit;
+ u32 val;
/* take care of subpage writes */
if (len % 2 != 0) {
@@ -310,8 +382,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
}
/* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs,
- PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1);
+ ret = omap_prefetch_enable(info->gpmc_cs,
+ PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1, info);
if (ret) {
/* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16)
@@ -320,7 +392,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
omap_write_buf8(mtd, (u_char *)p, len);
} else {
while (len) {
- w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
+ w_count = readl(info->reg.gpmc_prefetch_status);
+ w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count);
w_count = w_count >> 1;
for (i = 0; (i < w_count) && len; i++, len -= 2)
iowrite16(*p++, info->nand.IO_ADDR_W);
@@ -329,11 +402,14 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
tim = 0;
limit = (loops_per_jiffy *
msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
- while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit))
+ do {
cpu_relax();
+ val = readl(info->reg.gpmc_prefetch_status);
+ val = GPMC_PREFETCH_STATUS_COUNT(val);
+ } while (val && (tim++ < limit));
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset(info->gpmc_cs);
+ omap_prefetch_reset(info->gpmc_cs, info);
}
}
@@ -365,6 +441,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
unsigned long tim, limit;
unsigned n;
int ret;
+ u32 val;
if (addr >= high_memory) {
struct page *p1;
@@ -396,9 +473,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
tx->callback_param = &info->comp;
dmaengine_submit(tx);
- /* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs,
- PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
+ /* configure and start prefetch transfer */
+ ret = omap_prefetch_enable(info->gpmc_cs,
+ PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write, info);
if (ret)
/* PFPW engine is busy, use cpu copy method */
goto out_copy_unmap;
@@ -410,11 +487,15 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
wait_for_completion(&info->comp);
tim = 0;
limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
- while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit))
+
+ do {
cpu_relax();
+ val = readl(info->reg.gpmc_prefetch_status);
+ val = GPMC_PREFETCH_STATUS_COUNT(val);
+ } while (val && (tim++ < limit));
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset(info->gpmc_cs);
+ omap_prefetch_reset(info->gpmc_cs, info);
dma_unmap_sg(info->dma->device->dev, &sg, 1, dir);
return 0;
@@ -474,7 +555,8 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
u32 irq_stat;
irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
- bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
+ bytes = readl(info->reg.gpmc_prefetch_status);
+ bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */
if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
if (irq_stat & 0x2)
@@ -534,8 +616,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
init_completion(&info->comp);
/* configure and start prefetch transfer */
- ret = gpmc_prefetch_enable(info->gpmc_cs,
- PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0);
+ ret = omap_prefetch_enable(info->gpmc_cs,
+ PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0, info);
if (ret)
/* PFPW engine is busy, use cpu copy method */
goto out_copy;
@@ -549,7 +631,7 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
wait_for_completion(&info->comp);
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset(info->gpmc_cs);
+ omap_prefetch_reset(info->gpmc_cs, info);
return;
out_copy:
@@ -572,6 +654,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
struct omap_nand_info, mtd);
int ret = 0;
unsigned long tim, limit;
+ u32 val;
if (len <= mtd->oobsize) {
omap_write_buf_pref(mtd, buf, len);
@@ -583,8 +666,8 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
init_completion(&info->comp);
/* configure and start prefetch transfer : size=24 */
- ret = gpmc_prefetch_enable(info->gpmc_cs,
- (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1);
+ ret = omap_prefetch_enable(info->gpmc_cs,
+ (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1, info);
if (ret)
/* PFPW engine is busy, use cpu copy method */
goto out_copy;
@@ -599,11 +682,14 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
/* wait for data to flushed-out before reset the prefetch */
tim = 0;
limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
- while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit))
+ do {
+ val = readl(info->reg.gpmc_prefetch_status);
+ val = GPMC_PREFETCH_STATUS_COUNT(val);
cpu_relax();
+ } while (val && (tim++ < limit));
/* disable and stop the PFPW engine */
- gpmc_prefetch_reset(info->gpmc_cs);
+ omap_prefetch_reset(info->gpmc_cs, info);
return;
out_copy:
@@ -843,7 +929,20 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
{
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
mtd);
- return gpmc_calculate_ecc(info->gpmc_cs, dat, ecc_code);
+ u32 val;
+
+ val = readl(info->reg.gpmc_ecc_config);
+ if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs)
+ return -EINVAL;
+
+ /* read ecc result */
+ val = readl(info->reg.gpmc_ecc1_result);
+ *ecc_code++ = val; /* P128e, ..., P1e */
+ *ecc_code++ = val >> 16; /* P128o, ..., P1o */
+ /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
+ *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
+
+ return 0;
}
/**
@@ -857,8 +956,34 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
mtd);
struct nand_chip *chip = mtd->priv;
unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+ u32 val;
- gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size);
+ /* clear ecc and enable bits */
+ val = ECCCLEAR | ECC1;
+ writel(val, info->reg.gpmc_ecc_control);
+
+ /* program ecc and result sizes */
+ val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) |
+ ECC1RESULTSIZE);
+ writel(val, info->reg.gpmc_ecc_size_config);
+
+ switch (mode) {
+ case NAND_ECC_READ:
+ case NAND_ECC_WRITE:
+ writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
+ break;
+ case NAND_ECC_READSYN:
+ writel(ECCCLEAR, info->reg.gpmc_ecc_control);
+ break;
+ default:
+ dev_info(&info->pdev->dev,
+ "error: unrecognized Mode[%d]!\n", mode);
+ break;
+ }
+
+ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
+ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
+ writel(val, info->reg.gpmc_ecc_config);
}
/**
@@ -886,10 +1011,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
else
timeo += (HZ * 20) / 1000;
- gpmc_nand_write(info->gpmc_cs,
- GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF));
+ writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command);
while (time_before(jiffies, timeo)) {
- status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA);
+ status = readb(info->reg.gpmc_nand_data);
if (status & NAND_STATUS_READY)
break;
cond_resched();
@@ -909,22 +1033,13 @@ static int omap_dev_ready(struct mtd_info *mtd)
struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
mtd);
- val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
+ val = readl(info->reg.gpmc_status);
+
if ((val & 0x100) == 0x100) {
- /* Clear IRQ Interrupt */
- val |= 0x100;
- val &= ~(0x0);
- gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val);
+ return 1;
} else {
- unsigned int cnt = 0;
- while (cnt++ < 0x1FF) {
- if ((val & 0x100) == 0x100)
- return 0;
- val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
- }
+ return 0;
}
-
- return 1;
}
#ifdef CONFIG_MTD_NAND_OMAP_BCH
@@ -1175,6 +1290,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->gpmc_cs = pdata->cs;
info->phys_base = pdata->phys_base;
+ info->reg = pdata->reg;
info->mtd.priv = &info->nand;
info->mtd.name = dev_name(&pdev->dev);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 04/10] ARM: OMAP2+: gpmc-nand: update resource with memory
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (2 preceding siblings ...)
2012-08-21 9:43 ` [PATCH v3 03/10] mtd: nand: omap2: handle nand on gpmc Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 05/10] ARM: OMAP2+: gpmc-onenand: provide memory as resource Afzal Mohammed
` (5 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
Currently omap nand driver uses a field in platform data - phys_base
for passing the address space allocated by gpmc for nand. Use struct
resource instead. With this change omap nand driver has to get
address space from memory resource.
This helps in smooth migration of gpmc to driver.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index d4e803c..c0320d2 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -90,12 +90,14 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
gpmc_nand_device.dev.platform_data = gpmc_nand_data;
err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
- &gpmc_nand_data->phys_base);
+ (unsigned long *)&gpmc_nand_resource.start);
if (err < 0) {
dev_err(dev, "Cannot request GPMC CS\n");
return err;
}
+ gpmc_nand_resource.end = gpmc_nand_resource.start + NAND_IO_SIZE - 1;
+
/* Set timings in GPMC */
err = omap2_nand_gpmc_retime(gpmc_nand_data);
if (err < 0) {
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 05/10] ARM: OMAP2+: gpmc-onenand: provide memory as resource
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (3 preceding siblings ...)
2012-08-21 9:43 ` [PATCH v3 04/10] ARM: OMAP2+: gpmc-nand: update resource with memory Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 06/10] mtd: nand: omap2: obtain memory from resource Afzal Mohammed
` (4 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
Currently omap onenand driver invokes gpmc_cs_request, obtains address
space allocated by gpmc to onenand. Remove this, instead use resource
structure; this is now updated with address space for onenand by gpmc
initialization with the help of gpmc_cs_request. And remove usage of
gpmc_cs_request in onenand driver.
This helps in smooth migration of gpmc to driver.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc-onenand.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index a0fa9bb..71d7c07 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -23,11 +23,19 @@
#include <plat/board.h>
#include <plat/gpmc.h>
+#define ONENAND_IO_SIZE SZ_128K
+
static struct omap_onenand_platform_data *gpmc_onenand_data;
+static struct resource gpmc_onenand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
static struct platform_device gpmc_onenand_device = {
.name = "omap2-onenand",
.id = -1,
+ .num_resources = 1,
+ .resource = &gpmc_onenand_resource,
};
static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
@@ -390,6 +398,8 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
{
+ int err;
+
gpmc_onenand_data = _onenand_data;
gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
@@ -401,8 +411,19 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
}
+ err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
+ (unsigned long *)&gpmc_onenand_resource.start);
+ if (err < 0) {
+ pr_err("%s: Cannot request GPMC CS\n", __func__);
+ return;
+ }
+
+ gpmc_onenand_resource.end = gpmc_onenand_resource.start +
+ ONENAND_IO_SIZE - 1;
+
if (platform_device_register(&gpmc_onenand_device) < 0) {
- printk(KERN_ERR "Unable to register OneNAND device\n");
+ pr_err("%s: Unable to register OneNAND device\n", __func__);
+ gpmc_cs_free(gpmc_onenand_data->cs);
return;
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 06/10] mtd: nand: omap2: obtain memory from resource
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (4 preceding siblings ...)
2012-08-21 9:43 ` [PATCH v3 05/10] ARM: OMAP2+: gpmc-onenand: provide memory as resource Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:43 ` [PATCH v3 07/10] mtd: onenand: " Afzal Mohammed
` (3 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
gpmc initialization done by platform code now updates struct resource
with the address space alloted for nand. Use this interface to obtain
memory rather than relying on platform data field - phys_base.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
arch/arm/plat-omap/include/plat/nand.h | 1 -
drivers/mtd/nand/omap2.c | 19 +++++++++++++++----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index 86e4d9c..290cef5 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
bool dev_ready;
int gpmc_irq;
enum nand_io xfer_type;
- unsigned long phys_base;
int devsize;
enum omap_ecc ecc_opt;
struct gpmc_nand_regs reg;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8ddca98..f65f7f8 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -134,6 +134,7 @@ struct omap_nand_info {
int gpmc_cs;
unsigned long phys_base;
+ unsigned long mem_size;
struct completion comp;
struct dma_chan *dma;
int gpmc_irq;
@@ -1270,6 +1271,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
int i, offset;
dma_cap_mask_t mask;
unsigned sig;
+ struct resource *res;
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
@@ -1289,7 +1291,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->pdev = pdev;
info->gpmc_cs = pdata->cs;
- info->phys_base = pdata->phys_base;
info->reg = pdata->reg;
info->mtd.priv = &info->nand;
@@ -1302,13 +1303,23 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
/* NAND write protect off */
gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0);
- if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ err = -EINVAL;
+ dev_err(&pdev->dev, "error getting memory resource\n");
+ goto out_free_info;
+ }
+
+ info->phys_base = res->start;
+ info->mem_size = resource_size(res);
+
+ if (!request_mem_region(info->phys_base, info->mem_size,
pdev->dev.driver->name)) {
err = -EBUSY;
goto out_free_info;
}
- info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE);
+ info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
if (!info->nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1480,7 +1491,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
out_release_mem_region:
if (info->dma)
dma_release_channel(info->dma);
- release_mem_region(info->phys_base, NAND_IO_SIZE);
+ release_mem_region(info->phys_base, info->mem_size);
out_free_info:
kfree(info);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 07/10] mtd: onenand: omap2: obtain memory from resource
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (5 preceding siblings ...)
2012-08-21 9:43 ` [PATCH v3 06/10] mtd: nand: omap2: obtain memory from resource Afzal Mohammed
@ 2012-08-21 9:43 ` Afzal Mohammed
2012-08-21 9:44 ` [PATCH v3 08/10] ARM: OMAP2+: gpmc: Modify interrupt handling Afzal Mohammed
` (2 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:43 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
gpmc initialization for onenand done by platform code now provides
onenand address space as memory resource. Hence remove usage of
gpmc_cs_request in onenand driver and obtain memory details from
resource structure.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
drivers/mtd/onenand/omap2.c | 29 ++++++++++++++++-------------
1 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 398a827..3ff893d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -48,13 +48,13 @@
#define DRIVER_NAME "omap2-onenand"
-#define ONENAND_IO_SIZE SZ_128K
#define ONENAND_BUFRAM_SIZE (1024 * 5)
struct omap2_onenand {
struct platform_device *pdev;
int gpmc_cs;
unsigned long phys_base;
+ unsigned int mem_size;
int gpio_irq;
struct mtd_info mtd;
struct onenand_chip onenand;
@@ -626,6 +626,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
struct omap2_onenand *c;
struct onenand_chip *this;
int r;
+ struct resource *res;
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
@@ -647,20 +648,24 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
c->gpio_irq = 0;
}
- r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base);
- if (r < 0) {
- dev_err(&pdev->dev, "Cannot request GPMC CS\n");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ r = -EINVAL;
+ dev_err(&pdev->dev, "error getting memory resource\n");
goto err_kfree;
}
- if (request_mem_region(c->phys_base, ONENAND_IO_SIZE,
+ c->phys_base = res->start;
+ c->mem_size = resource_size(res);
+
+ if (request_mem_region(c->phys_base, c->mem_size,
pdev->dev.driver->name) == NULL) {
- dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, "
- "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE);
+ dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
+ c->phys_base, c->mem_size);
r = -EBUSY;
- goto err_free_cs;
+ goto err_kfree;
}
- c->onenand.base = ioremap(c->phys_base, ONENAND_IO_SIZE);
+ c->onenand.base = ioremap(c->phys_base, c->mem_size);
if (c->onenand.base == NULL) {
r = -ENOMEM;
goto err_release_mem_region;
@@ -776,9 +781,7 @@ err_release_gpio:
err_iounmap:
iounmap(c->onenand.base);
err_release_mem_region:
- release_mem_region(c->phys_base, ONENAND_IO_SIZE);
-err_free_cs:
- gpmc_cs_free(c->gpmc_cs);
+ release_mem_region(c->phys_base, c->mem_size);
err_kfree:
kfree(c);
@@ -800,7 +803,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
gpio_free(c->gpio_irq);
}
iounmap(c->onenand.base);
- release_mem_region(c->phys_base, ONENAND_IO_SIZE);
+ release_mem_region(c->phys_base, c->mem_size);
gpmc_cs_free(c->gpmc_cs);
kfree(c);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 08/10] ARM: OMAP2+: gpmc: Modify interrupt handling
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (6 preceding siblings ...)
2012-08-21 9:43 ` [PATCH v3 07/10] mtd: onenand: " Afzal Mohammed
@ 2012-08-21 9:44 ` Afzal Mohammed
2012-08-21 9:44 ` [PATCH v3 09/10] ARM: OMAP2+: gpmc-nand: Modify Interrupt handling Afzal Mohammed
2012-08-21 9:44 ` [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs Afzal Mohammed
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:44 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
Modify interrupt handling such that interrupts can be handled by GPMC
client drivers using standard interrupt APIs rather than requiring
the drivers to have knowledge about GPMC interrupt handling. Currently
only NAND related interrupts has been considered (which is the case
even without this change) as the only user of GPMC interrupt is NAND.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 136 ++++++++++++++++++++++++++++----
arch/arm/plat-omap/include/plat/gpmc.h | 1 +
2 files changed, 120 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 5cce9b0..39c30d9 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -78,6 +78,15 @@
#define ENABLE_PREFETCH (0x1 << 7)
#define DMA_MPU_MODE 2
+/* XXX: Only NAND irq has been considered,currently these are the only ones used
+ */
+#define GPMC_NR_IRQ 2
+
+struct gpmc_client_irq {
+ unsigned irq;
+ u32 bitmask;
+};
+
/* Structure to save gpmc cs context */
struct gpmc_cs_config {
u32 config1;
@@ -105,6 +114,10 @@ struct omap3_gpmc_regs {
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
};
+static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
+static struct irq_chip gpmc_irq_chip;
+static unsigned gpmc_irq_start;
+
static struct resource gpmc_mem_root;
static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -702,6 +715,97 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0;
}
+int gpmc_get_client_irq(unsigned irq_config)
+{
+ int i;
+
+ if (hweight32(irq_config) > 1)
+ return 0;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++)
+ if (gpmc_client_irq[i].bitmask & irq_config)
+ return gpmc_client_irq[i].irq;
+
+ return 0;
+}
+
+static int gpmc_irq_endis(unsigned irq, bool endis)
+{
+ int i;
+ u32 regval;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++)
+ if (irq == gpmc_client_irq[i].irq) {
+ regval = gpmc_read_reg(GPMC_IRQENABLE);
+ if (endis)
+ regval |= gpmc_client_irq[i].bitmask;
+ else
+ regval &= ~gpmc_client_irq[i].bitmask;
+ gpmc_write_reg(GPMC_IRQENABLE, regval);
+ break;
+ }
+
+ return 0;
+}
+
+static void gpmc_irq_disable(struct irq_data *p)
+{
+ gpmc_irq_endis(p->irq, false);
+}
+
+static void gpmc_irq_enable(struct irq_data *p)
+{
+ gpmc_irq_endis(p->irq, true);
+}
+
+static void gpmc_irq_noop(struct irq_data *data) { }
+
+static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+
+static int gpmc_setup_irq(int gpmc_irq)
+{
+ int i;
+ u32 regval;
+
+ if (!gpmc_irq)
+ return -EINVAL;
+
+ gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
+ if (IS_ERR_VALUE(gpmc_irq_start)) {
+ pr_err("irq_alloc_descs failed\n");
+ return gpmc_irq_start;
+ }
+
+ gpmc_irq_chip.name = "gpmc";
+ gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
+ gpmc_irq_chip.irq_enable = gpmc_irq_enable;
+ gpmc_irq_chip.irq_disable = gpmc_irq_disable;
+ gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
+ gpmc_irq_chip.irq_ack = gpmc_irq_noop;
+ gpmc_irq_chip.irq_mask = gpmc_irq_noop;
+ gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
+
+ gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
+ gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++) {
+ gpmc_client_irq[i].irq = gpmc_irq_start + i;
+ irq_set_chip_and_handler(gpmc_client_irq[i].irq,
+ &gpmc_irq_chip, handle_simple_irq);
+ set_irq_flags(gpmc_client_irq[i].irq,
+ IRQF_VALID | IRQF_NOAUTOEN);
+ }
+
+ /* Disable interrupts */
+ gpmc_write_reg(GPMC_IRQENABLE, 0);
+
+ /* clear interrupts */
+ regval = gpmc_read_reg(GPMC_IRQSTATUS);
+ gpmc_write_reg(GPMC_IRQSTATUS, regval);
+
+ return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
+}
+
static void __init gpmc_mem_init(void)
{
int cs;
@@ -731,8 +835,8 @@ static void __init gpmc_mem_init(void)
static int __init gpmc_init(void)
{
- u32 l, irq;
- int cs, ret = -EINVAL;
+ u32 l;
+ int ret = -EINVAL;
int gpmc_irq;
char *ck = NULL;
@@ -781,16 +885,7 @@ static int __init gpmc_init(void)
gpmc_write_reg(GPMC_SYSCONFIG, l);
gpmc_mem_init();
- /* initalize the irq_chained */
- irq = OMAP_GPMC_IRQ_BASE;
- for (cs = 0; cs < GPMC_CS_NUM; cs++) {
- irq_set_chip_and_handler(irq, &dummy_irq_chip,
- handle_simple_irq);
- set_irq_flags(irq, IRQF_VALID);
- irq++;
- }
-
- ret = request_irq(gpmc_irq, gpmc_handle_irq, IRQF_SHARED, "gpmc", NULL);
+ ret = gpmc_setup_irq(gpmc_irq);
if (ret)
pr_err("gpmc: irq-%d could not claim: err %d\n",
gpmc_irq, ret);
@@ -800,12 +895,19 @@ postcore_initcall(gpmc_init);
static irqreturn_t gpmc_handle_irq(int irq, void *dev)
{
- u8 cs;
+ int i;
+ u32 regval;
+
+ regval = gpmc_read_reg(GPMC_IRQSTATUS);
+
+ if (!regval)
+ return IRQ_NONE;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++)
+ if (regval & gpmc_client_irq[i].bitmask)
+ generic_handle_irq(gpmc_client_irq[i].irq);
- /* check cs to invoke the irq */
- cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7;
- if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END)
- generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs);
+ gpmc_write_reg(GPMC_IRQSTATUS, regval);
return IRQ_HANDLED;
}
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 06198a5..2e6e259 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -150,6 +150,7 @@ struct gpmc_nand_regs {
};
extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+extern int gpmc_get_client_irq(unsigned irq_config);
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 09/10] ARM: OMAP2+: gpmc-nand: Modify Interrupt handling
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (7 preceding siblings ...)
2012-08-21 9:44 ` [PATCH v3 08/10] ARM: OMAP2+: gpmc: Modify interrupt handling Afzal Mohammed
@ 2012-08-21 9:44 ` Afzal Mohammed
2012-08-21 9:44 ` [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs Afzal Mohammed
9 siblings, 0 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:44 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
Now GPMC provides its client with interrupts that can be handled
using the standard interrupt API. Modify GPMC NAND setup to work
with it.
Also disable write protect in GPMC code, so that NAND driver can
be ignorant of GPMC configuration.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index c0320d2..045596a 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,15 +21,23 @@
#include <plat/board.h>
#include <plat/gpmc.h>
-static struct resource gpmc_nand_resource = {
- .flags = IORESOURCE_MEM,
+static struct resource gpmc_nand_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .flags = IORESOURCE_IRQ,
+ },
};
static struct platform_device gpmc_nand_device = {
.name = "omap2-nand",
.id = 0,
- .num_resources = 1,
- .resource = &gpmc_nand_resource,
+ .num_resources = ARRAY_SIZE(gpmc_nand_resource),
+ .resource = gpmc_nand_resource,
};
static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data)
@@ -75,6 +83,7 @@ static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data
gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0);
gpmc_cs_configure(gpmc_nand_data->cs,
GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
if (err)
return err;
@@ -90,14 +99,19 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
gpmc_nand_device.dev.platform_data = gpmc_nand_data;
err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
- (unsigned long *)&gpmc_nand_resource.start);
+ (unsigned long *)&gpmc_nand_resource[0].start);
if (err < 0) {
dev_err(dev, "Cannot request GPMC CS\n");
return err;
}
- gpmc_nand_resource.end = gpmc_nand_resource.start + NAND_IO_SIZE - 1;
+ gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
+ NAND_IO_SIZE - 1;
+ gpmc_nand_resource[1].start =
+ gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
+ gpmc_nand_resource[2].start =
+ gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
/* Set timings in GPMC */
err = omap2_nand_gpmc_retime(gpmc_nand_data);
if (err < 0) {
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-08-21 9:38 [PATCH v3 00/10] Prepare for GPMC driver conversion (w.r.t MTD) Afzal Mohammed
` (8 preceding siblings ...)
2012-08-21 9:44 ` [PATCH v3 09/10] ARM: OMAP2+: gpmc-nand: Modify Interrupt handling Afzal Mohammed
@ 2012-08-21 9:44 ` Afzal Mohammed
2012-08-24 19:29 ` Tony Lindgren
2012-08-25 11:48 ` Artem Bityutskiy
9 siblings, 2 replies; 20+ messages in thread
From: Afzal Mohammed @ 2012-08-21 9:44 UTC (permalink / raw)
To: tony, artem.bityutskiy, linux-omap, linux-mtd; +Cc: ivan.djelic, Afzal Mohammed
GPMC platform initialization provides it's clients
with interrupts that can be used through struct
resource. Make use of it for irq mode functionality.
Also now write protect disable is done by GPMC,
hence remove it.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
v3: Handle error path properly
drivers/mtd/nand/omap2.c | 76 +++++++++++++++++++++++++++++-----------------
1 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f65f7f8..0e9d7b3 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -137,7 +137,8 @@ struct omap_nand_info {
unsigned long mem_size;
struct completion comp;
struct dma_chan *dma;
- int gpmc_irq;
+ int gpmc_irq_fifo;
+ int gpmc_irq_count;
enum {
OMAP_NAND_IO_READ = 0, /* read */
OMAP_NAND_IO_WRITE, /* write */
@@ -553,14 +554,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
{
struct omap_nand_info *info = (struct omap_nand_info *) dev;
u32 bytes;
- u32 irq_stat;
- irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
bytes = readl(info->reg.gpmc_prefetch_status);
bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */
if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
- if (irq_stat & 0x2)
+ if (this_irq == info->gpmc_irq_count)
goto done;
if (info->buf_len && (info->buf_len < bytes))
@@ -577,20 +576,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
(u32 *)info->buf, bytes >> 2);
info->buf = info->buf + bytes;
- if (irq_stat & 0x2)
+ if (this_irq == info->gpmc_irq_count)
goto done;
}
- gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
return IRQ_HANDLED;
done:
complete(&info->comp);
- /* disable irq */
- gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0);
- /* clear status */
- gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
+ disable_irq_nosync(info->gpmc_irq_fifo);
+ disable_irq_nosync(info->gpmc_irq_count);
return IRQ_HANDLED;
}
@@ -624,9 +620,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
goto out_copy;
info->buf_len = len;
- /* enable irq */
- gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
- (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+ enable_irq(info->gpmc_irq_count);
+ enable_irq(info->gpmc_irq_fifo);
/* waiting for read to complete */
wait_for_completion(&info->comp);
@@ -674,12 +670,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
goto out_copy;
info->buf_len = len;
- /* enable irq */
- gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
- (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+ enable_irq(info->gpmc_irq_count);
+ enable_irq(info->gpmc_irq_fifo);
/* waiting for write to complete */
wait_for_completion(&info->comp);
+
/* wait for data to flushed-out before reset the prefetch */
tim = 0;
limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
@@ -1300,9 +1297,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->nand.options = pdata->devsize;
info->nand.options |= NAND_SKIP_BBTSCAN;
- /* NAND write protect off */
- gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
err = -EINVAL;
@@ -1393,17 +1387,37 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
break;
case NAND_OMAP_PREFETCH_IRQ:
- err = request_irq(pdata->gpmc_irq,
- omap_nand_irq, IRQF_SHARED, "gpmc-nand", info);
+ info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
+ if (info->gpmc_irq_fifo <= 0) {
+ dev_err(&pdev->dev, "error getting fifo irq\n");
+ goto out_release_mem_region;
+ }
+ err = request_irq(info->gpmc_irq_fifo, omap_nand_irq,
+ IRQF_SHARED, "gpmc-nand-fifo", info);
if (err) {
dev_err(&pdev->dev, "requesting irq(%d) error:%d",
- pdata->gpmc_irq, err);
+ info->gpmc_irq_fifo, err);
+ info->gpmc_irq_fifo = 0;
+ goto out_release_mem_region;
+ }
+
+ info->gpmc_irq_count = platform_get_irq(pdev, 1);
+ if (info->gpmc_irq_count <= 0) {
+ dev_err(&pdev->dev, "error getting count irq\n");
+ goto out_release_mem_region;
+ }
+ err = request_irq(info->gpmc_irq_count, omap_nand_irq,
+ IRQF_SHARED, "gpmc-nand-count", info);
+ if (err) {
+ dev_err(&pdev->dev, "requesting irq(%d) error:%d",
+ info->gpmc_irq_count, err);
+ info->gpmc_irq_count = 0;
goto out_release_mem_region;
- } else {
- info->gpmc_irq = pdata->gpmc_irq;
- info->nand.read_buf = omap_read_buf_irq_pref;
- info->nand.write_buf = omap_write_buf_irq_pref;
}
+
+ info->nand.read_buf = omap_read_buf_irq_pref;
+ info->nand.write_buf = omap_write_buf_irq_pref;
+
break;
default:
@@ -1491,6 +1505,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
out_release_mem_region:
if (info->dma)
dma_release_channel(info->dma);
+ if (info->gpmc_irq_count > 0)
+ free_irq(info->gpmc_irq_count, info);
+ if (info->gpmc_irq_fifo > 0)
+ free_irq(info->gpmc_irq_fifo, info);
release_mem_region(info->phys_base, info->mem_size);
out_free_info:
kfree(info);
@@ -1509,8 +1527,10 @@ static int omap_nand_remove(struct platform_device *pdev)
if (info->dma)
dma_release_channel(info->dma);
- if (info->gpmc_irq)
- free_irq(info->gpmc_irq, info);
+ if (info->gpmc_irq_count > 0)
+ free_irq(info->gpmc_irq_count, info);
+ if (info->gpmc_irq_fifo > 0)
+ free_irq(info->gpmc_irq_fifo, info);
/* Release NAND device, its internal structures and partitions */
nand_release(&info->mtd);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-08-21 9:44 ` [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs Afzal Mohammed
@ 2012-08-24 19:29 ` Tony Lindgren
2012-08-25 11:48 ` Artem Bityutskiy
1 sibling, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2012-08-24 19:29 UTC (permalink / raw)
To: Afzal Mohammed; +Cc: artem.bityutskiy, linux-omap, linux-mtd, ivan.djelic
Artem,
* Afzal Mohammed <afzal@ti.com> [120821 02:44]:
> GPMC platform initialization provides it's clients
> with interrupts that can be used through struct
> resource. Make use of it for irq mode functionality.
>
> Also now write protect disable is done by GPMC,
> hence remove it.
>
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>
> v3: Handle error path properly
Care to (re)ack this one as the error path handling changed?
Regards,
Tony
> drivers/mtd/nand/omap2.c | 76 +++++++++++++++++++++++++++++-----------------
> 1 files changed, 48 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index f65f7f8..0e9d7b3 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -137,7 +137,8 @@ struct omap_nand_info {
> unsigned long mem_size;
> struct completion comp;
> struct dma_chan *dma;
> - int gpmc_irq;
> + int gpmc_irq_fifo;
> + int gpmc_irq_count;
> enum {
> OMAP_NAND_IO_READ = 0, /* read */
> OMAP_NAND_IO_WRITE, /* write */
> @@ -553,14 +554,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
> {
> struct omap_nand_info *info = (struct omap_nand_info *) dev;
> u32 bytes;
> - u32 irq_stat;
>
> - irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
> bytes = readl(info->reg.gpmc_prefetch_status);
> bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
> bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */
> if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
> - if (irq_stat & 0x2)
> + if (this_irq == info->gpmc_irq_count)
> goto done;
>
> if (info->buf_len && (info->buf_len < bytes))
> @@ -577,20 +576,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
> (u32 *)info->buf, bytes >> 2);
> info->buf = info->buf + bytes;
>
> - if (irq_stat & 0x2)
> + if (this_irq == info->gpmc_irq_count)
> goto done;
> }
> - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
>
> return IRQ_HANDLED;
>
> done:
> complete(&info->comp);
> - /* disable irq */
> - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0);
>
> - /* clear status */
> - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
> + disable_irq_nosync(info->gpmc_irq_fifo);
> + disable_irq_nosync(info->gpmc_irq_count);
>
> return IRQ_HANDLED;
> }
> @@ -624,9 +620,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
> goto out_copy;
>
> info->buf_len = len;
> - /* enable irq */
> - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
> - (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
> +
> + enable_irq(info->gpmc_irq_count);
> + enable_irq(info->gpmc_irq_fifo);
>
> /* waiting for read to complete */
> wait_for_completion(&info->comp);
> @@ -674,12 +670,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
> goto out_copy;
>
> info->buf_len = len;
> - /* enable irq */
> - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ,
> - (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
> +
> + enable_irq(info->gpmc_irq_count);
> + enable_irq(info->gpmc_irq_fifo);
>
> /* waiting for write to complete */
> wait_for_completion(&info->comp);
> +
> /* wait for data to flushed-out before reset the prefetch */
> tim = 0;
> limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
> @@ -1300,9 +1297,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
> info->nand.options = pdata->devsize;
> info->nand.options |= NAND_SKIP_BBTSCAN;
>
> - /* NAND write protect off */
> - gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0);
> -
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (res == NULL) {
> err = -EINVAL;
> @@ -1393,17 +1387,37 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
> break;
>
> case NAND_OMAP_PREFETCH_IRQ:
> - err = request_irq(pdata->gpmc_irq,
> - omap_nand_irq, IRQF_SHARED, "gpmc-nand", info);
> + info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
> + if (info->gpmc_irq_fifo <= 0) {
> + dev_err(&pdev->dev, "error getting fifo irq\n");
> + goto out_release_mem_region;
> + }
> + err = request_irq(info->gpmc_irq_fifo, omap_nand_irq,
> + IRQF_SHARED, "gpmc-nand-fifo", info);
> if (err) {
> dev_err(&pdev->dev, "requesting irq(%d) error:%d",
> - pdata->gpmc_irq, err);
> + info->gpmc_irq_fifo, err);
> + info->gpmc_irq_fifo = 0;
> + goto out_release_mem_region;
> + }
> +
> + info->gpmc_irq_count = platform_get_irq(pdev, 1);
> + if (info->gpmc_irq_count <= 0) {
> + dev_err(&pdev->dev, "error getting count irq\n");
> + goto out_release_mem_region;
> + }
> + err = request_irq(info->gpmc_irq_count, omap_nand_irq,
> + IRQF_SHARED, "gpmc-nand-count", info);
> + if (err) {
> + dev_err(&pdev->dev, "requesting irq(%d) error:%d",
> + info->gpmc_irq_count, err);
> + info->gpmc_irq_count = 0;
> goto out_release_mem_region;
> - } else {
> - info->gpmc_irq = pdata->gpmc_irq;
> - info->nand.read_buf = omap_read_buf_irq_pref;
> - info->nand.write_buf = omap_write_buf_irq_pref;
> }
> +
> + info->nand.read_buf = omap_read_buf_irq_pref;
> + info->nand.write_buf = omap_write_buf_irq_pref;
> +
> break;
>
> default:
> @@ -1491,6 +1505,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
> out_release_mem_region:
> if (info->dma)
> dma_release_channel(info->dma);
> + if (info->gpmc_irq_count > 0)
> + free_irq(info->gpmc_irq_count, info);
> + if (info->gpmc_irq_fifo > 0)
> + free_irq(info->gpmc_irq_fifo, info);
> release_mem_region(info->phys_base, info->mem_size);
> out_free_info:
> kfree(info);
> @@ -1509,8 +1527,10 @@ static int omap_nand_remove(struct platform_device *pdev)
> if (info->dma)
> dma_release_channel(info->dma);
>
> - if (info->gpmc_irq)
> - free_irq(info->gpmc_irq, info);
> + if (info->gpmc_irq_count > 0)
> + free_irq(info->gpmc_irq_count, info);
> + if (info->gpmc_irq_fifo > 0)
> + free_irq(info->gpmc_irq_fifo, info);
>
> /* Release NAND device, its internal structures and partitions */
> nand_release(&info->mtd);
> --
> 1.7.1
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-08-21 9:44 ` [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs Afzal Mohammed
2012-08-24 19:29 ` Tony Lindgren
@ 2012-08-25 11:48 ` Artem Bityutskiy
2012-08-30 19:53 ` Tony Lindgren
1 sibling, 1 reply; 20+ messages in thread
From: Artem Bityutskiy @ 2012-08-25 11:48 UTC (permalink / raw)
To: Afzal Mohammed; +Cc: tony, artem.bityutskiy, linux-omap, linux-mtd, ivan.djelic
[-- Attachment #1: Type: text/plain, Size: 451 bytes --]
On Tue, 2012-08-21 at 15:14 +0530, Afzal Mohammed wrote:
> GPMC platform initialization provides it's clients
> with interrupts that can be used through struct
> resource. Make use of it for irq mode functionality.
>
> Also now write protect disable is done by GPMC,
> hence remove it.
>
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
--
Best Regards,
Artem Bityutskiy
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-08-25 11:48 ` Artem Bityutskiy
@ 2012-08-30 19:53 ` Tony Lindgren
2012-09-11 0:17 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2012-08-30 19:53 UTC (permalink / raw)
To: Artem Bityutskiy
Cc: artem.bityutskiy, Afzal Mohammed, linux-omap, linux-mtd,
ivan.djelic
* Artem Bityutskiy <dedekind1@gmail.com> [120825 04:49]:
> On Tue, 2012-08-21 at 15:14 +0530, Afzal Mohammed wrote:
> > GPMC platform initialization provides it's clients
> > with interrupts that can be used through struct
> > resource. Make use of it for irq mode functionality.
> >
> > Also now write protect disable is done by GPMC,
> > hence remove it.
> >
> > Signed-off-by: Afzal Mohammed <afzal@ti.com>
>
> Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Thanks I'll apply these into omap devel-gpmc branch.
Regards,
Tony
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-08-30 19:53 ` Tony Lindgren
@ 2012-09-11 0:17 ` Tony Lindgren
2012-09-11 5:36 ` Mohammed, Afzal
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2012-09-11 0:17 UTC (permalink / raw)
To: Artem Bityutskiy
Cc: Afzal Mohammed, artem.bityutskiy, linux-omap, linux-mtd,
ivan.djelic
* Tony Lindgren <tony@atomide.com> [120830 12:54]:
> * Artem Bityutskiy <dedekind1@gmail.com> [120825 04:49]:
> > On Tue, 2012-08-21 at 15:14 +0530, Afzal Mohammed wrote:
> > > GPMC platform initialization provides it's clients
> > > with interrupts that can be used through struct
> > > resource. Make use of it for irq mode functionality.
> > >
> > > Also now write protect disable is done by GPMC,
> > > hence remove it.
> > >
> > > Signed-off-by: Afzal Mohammed <afzal@ti.com>
> >
> > Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
>
> Thanks I'll apply these into omap devel-gpmc branch.
FYI, looks like a new warning got introduced, so I've
committed the following trivial patch on top of this series.
Regards,
Tony
From: Tony Lindgren <tony@atomide.com>
Date: Mon, 10 Sep 2012 17:14:13 -0700
Subject: [PATCH] mtd: nand omap2: Fix uninitialized err warning
Commit bd4156fd (mtd: nand: omap2: use gpmc provided irqs)
introduced a new warning:
drivers/mtd/nand/omap2.c: In function ‘omap_nand_probe’:
drivers/mtd/nand/omap2.c:1267: warning: ‘err’ may be used uninitialized in this function
Signed-off-by: Tony Lindgren <tony@atomide.com>
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1389,6 +1389,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
if (info->gpmc_irq_fifo <= 0) {
dev_err(&pdev->dev, "error getting fifo irq\n");
+ err = -ENODEV;
goto out_release_mem_region;
}
err = request_irq(info->gpmc_irq_fifo, omap_nand_irq,
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-09-11 0:17 ` Tony Lindgren
@ 2012-09-11 5:36 ` Mohammed, Afzal
2012-09-11 5:42 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Mohammed, Afzal @ 2012-09-11 5:36 UTC (permalink / raw)
To: Tony Lindgren, Artem Bityutskiy
Cc: artem.bityutskiy@linux.intel.com, linux-omap@vger.kernel.org,
linux-mtd@lists.infradead.org, ivan.djelic@parrot.com
Hi Tony,
On Tue, Sep 11, 2012 at 05:47:10, Tony Lindgren wrote:
> FYI, looks like a new warning got introduced, so I've
> committed the following trivial patch on top of this series.
I was not careful enough, sorry. Thanks for fixing it.
Another hunk as follows would also be required for error
path even though compiler didn't complain.
Not sure whether you can fixup or I should post as a
separate patch.
As an aside, there was compiler warning before this
series, but I didn't dare to touch it, so a warning
was seen but thought it was due to the earlier one.
And now Arnd has fixed the original warning.
Regards
Afzal
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 337cf0a..27293e3 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1404,6 +1404,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->gpmc_irq_count = platform_get_irq(pdev, 1);
if (info->gpmc_irq_count <= 0) {
dev_err(&pdev->dev, "error getting count irq\n");
+ err = -ENODEV;
goto out_release_mem_region;
}
err = request_irq(info->gpmc_irq_count, omap_nand_irq,
> From: Tony Lindgren <tony@atomide.com>
> Date: Mon, 10 Sep 2012 17:14:13 -0700
> Subject: [PATCH] mtd: nand omap2: Fix uninitialized err warning
>
> Commit bd4156fd (mtd: nand: omap2: use gpmc provided irqs)
> introduced a new warning:
>
> drivers/mtd/nand/omap2.c: In function ‘omap_nand_probe’:
> drivers/mtd/nand/omap2.c:1267: warning: ‘err’ may be used uninitialized in this function
>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
>
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1389,6 +1389,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
> info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
> if (info->gpmc_irq_fifo <= 0) {
> dev_err(&pdev->dev, "error getting fifo irq\n");
> + err = -ENODEV;
> goto out_release_mem_region;
> }
> err = request_irq(info->gpmc_irq_fifo, omap_nand_irq,
>
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-09-11 5:36 ` Mohammed, Afzal
@ 2012-09-11 5:42 ` Tony Lindgren
2012-09-11 6:40 ` Mohammed, Afzal
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2012-09-11 5:42 UTC (permalink / raw)
To: Mohammed, Afzal
Cc: Artem Bityutskiy, artem.bityutskiy@linux.intel.com,
linux-omap@vger.kernel.org, linux-mtd@lists.infradead.org,
ivan.djelic@parrot.com
* Mohammed, Afzal <afzal@ti.com> [120910 22:36]:
> Hi Tony,
>
> On Tue, Sep 11, 2012 at 05:47:10, Tony Lindgren wrote:
>
> > FYI, looks like a new warning got introduced, so I've
> > committed the following trivial patch on top of this series.
>
> I was not careful enough, sorry. Thanks for fixing it.
>
> Another hunk as follows would also be required for error
> path even though compiler didn't complain.
>
> Not sure whether you can fixup or I should post as a
> separate patch.
Oh OK, please just post a separate patch as I've
already pushed it out.
> As an aside, there was compiler warning before this
> series, but I didn't dare to touch it, so a warning
> was seen but thought it was due to the earlier one.
> And now Arnd has fixed the original warning.
OK
Regards,
Tony
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-09-11 5:42 ` Tony Lindgren
@ 2012-09-11 6:40 ` Mohammed, Afzal
2012-09-11 18:21 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Mohammed, Afzal @ 2012-09-11 6:40 UTC (permalink / raw)
To: Tony Lindgren
Cc: Artem Bityutskiy, artem.bityutskiy@linux.intel.com,
linux-omap@vger.kernel.org, linux-mtd@lists.infradead.org,
ivan.djelic@parrot.com
Hi Tony,
On Tue, Sep 11, 2012 at 11:12:27, Tony Lindgren wrote:
> * Mohammed, Afzal <afzal@ti.com> [120910 22:36]:
> > I was not careful enough, sorry. Thanks for fixing it.
> >
> > Another hunk as follows would also be required for error
> > path even though compiler didn't complain.
> >
> > Not sure whether you can fixup or I should post as a
> > separate patch.
>
> Oh OK, please just post a separate patch as I've
> already pushed it out.
I have posted a separate patch, please consider for
inclusion in your tree.
BTW, you original commit that fixes the compiler
warning has some strange characters.
Regards
Afzal
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-09-11 6:40 ` Mohammed, Afzal
@ 2012-09-11 18:21 ` Tony Lindgren
2012-09-12 9:21 ` Mohammed, Afzal
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2012-09-11 18:21 UTC (permalink / raw)
To: Mohammed, Afzal
Cc: Artem Bityutskiy, artem.bityutskiy@linux.intel.com,
linux-omap@vger.kernel.org, linux-mtd@lists.infradead.org,
ivan.djelic@parrot.com
* Mohammed, Afzal <afzal@ti.com> [120910 23:40]:
> Hi Tony,
>
> On Tue, Sep 11, 2012 at 11:12:27, Tony Lindgren wrote:
> > * Mohammed, Afzal <afzal@ti.com> [120910 22:36]:
>
> > > I was not careful enough, sorry. Thanks for fixing it.
> > >
> > > Another hunk as follows would also be required for error
> > > path even though compiler didn't complain.
> > >
> > > Not sure whether you can fixup or I should post as a
> > > separate patch.
> >
> > Oh OK, please just post a separate patch as I've
> > already pushed it out.
>
> I have posted a separate patch, please consider for
> inclusion in your tree.
>
> BTW, you original commit that fixes the compiler
> warning has some strange characters.
Ah thanks, that's a copy paste UTF-8 issue. I'll just fold
in the fixes and push them out to a new devel-gpmc-fixed
branch.
Regards,
Tony
^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs
2012-09-11 18:21 ` Tony Lindgren
@ 2012-09-12 9:21 ` Mohammed, Afzal
0 siblings, 0 replies; 20+ messages in thread
From: Mohammed, Afzal @ 2012-09-12 9:21 UTC (permalink / raw)
To: Tony Lindgren
Cc: Artem Bityutskiy, artem.bityutskiy@linux.intel.com,
linux-omap@vger.kernel.org, linux-mtd@lists.infradead.org,
ivan.djelic@parrot.com
On Tue, Sep 11, 2012 at 23:51:07, Tony Lindgren wrote:
> Ah thanks, that's a copy paste UTF-8 issue. I'll just fold
> in the fixes and push them out to a new devel-gpmc-fixed
> branch.
Thanks Tony
Regards
Afzal
^ permalink raw reply [flat|nested] 20+ messages in thread