Patchwork [U-Boot,1/4] onenand:samsung Target dependent OneNAND chip probe function

login
register
mail settings
Submitter Łukasz Majewski
Date Nov. 10, 2011, 8:41 a.m.
Message ID <1320914477-27885-2-git-send-email-l.majewski@samsung.com>
Download mbox | patch
Permalink /patch/124824/
State Accepted
Commit 6b3967bbbb4182ab7298a816c1db7cc86adaee5e
Headers show

Comments

Łukasz Majewski - Nov. 10, 2011, 8:41 a.m.
Separate callback for probing OneNAND memory chip.
If no special function is defined, default implementation will be used.

This approach gives more flexibility for OneNAND device probing.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 ./tools/checkpatch.pl -
total: 0 errors, 0 warnings, 108 lines checked

NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX MULTISTATEMENT_MACRO_USE_DO_WHILE

---
 drivers/mtd/onenand/onenand_base.c  |   43 +++++++++++++++++++++++++++++-----
 drivers/mtd/onenand/samsung.c       |   10 ++++++++
 include/linux/mtd/onenand.h         |    1 +
 include/linux/mtd/samsung_onenand.h |    2 +
 4 files changed, 49 insertions(+), 7 deletions(-)
Marek Vasut - Nov. 20, 2011, 12:06 a.m.
> Separate callback for probing OneNAND memory chip.
> If no special function is defined, default implementation will be used.
> 
> This approach gives more flexibility for OneNAND device probing.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  ./tools/checkpatch.pl -
> total: 0 errors, 0 warnings, 108 lines checked
> 
> NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX
> MULTISTATEMENT_MACRO_USE_DO_WHILE
> 
> ---
>  drivers/mtd/onenand/onenand_base.c  |   43
> +++++++++++++++++++++++++++++----- drivers/mtd/onenand/samsung.c       |  
> 10 ++++++++
>  include/linux/mtd/onenand.h         |    1 +
>  include/linux/mtd/samsung_onenand.h |    2 +
>  4 files changed, 49 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/onenand_base.c
> b/drivers/mtd/onenand/onenand_base.c index 24e02c2..a557d48 100644
> --- a/drivers/mtd/onenand/onenand_base.c
> +++ b/drivers/mtd/onenand/onenand_base.c
> @@ -2505,23 +2505,24 @@ out:
>  }
> 
>  /**
> - * onenand_probe - [OneNAND Interface] Probe the OneNAND device
> + * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
>   * @param mtd		MTD device structure
>   *
>   * OneNAND detection method:
>   *   Compare the the values from command with ones from register
>   */
> -static int onenand_probe(struct mtd_info *mtd)
> +static int onenand_chip_probe(struct mtd_info *mtd)
>  {
>  	struct onenand_chip *this = mtd->priv;
> -	int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
> -	int density;
> +	int bram_maf_id, bram_dev_id, maf_id, dev_id;
>  	int syscfg;
> 
>  	/* Save system configuration 1 */
>  	syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
> +
>  	/* Clear Sync. Burst Read mode to read BootRAM */
> -	this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base +
> ONENAND_REG_SYS_CFG1); +	this->write_word((syscfg &
> ~ONENAND_SYS_CFG1_SYNC_READ),
> +			 this->base + ONENAND_REG_SYS_CFG1);
> 
>  	/* Send the command for reading device ID from BootRAM */
>  	this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
> @@ -2546,13 +2547,38 @@ static int onenand_probe(struct mtd_info *mtd)
>  	/* Read manufacturer and device IDs from Register */
>  	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
>  	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
> -	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
> -	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
> 
>  	/* Check OneNAND device */
>  	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
>  		return -ENXIO;
> 
> +	return 0;
> +}
> +
> +/**
> + * onenand_probe - [OneNAND Interface] Probe the OneNAND device
> + * @param mtd		MTD device structure
> + *
> + * OneNAND detection method:
> + *   Compare the the values from command with ones from register
> + */
> +int onenand_probe(struct mtd_info *mtd)
> +{
> +	struct onenand_chip *this = mtd->priv;
> +	int maf_id, dev_id, ver_id;
> +	int density;
> +	int ret;
> +
> +	ret = this->chip_probe(mtd);
> +	if (ret)
> +		return ret;
> +
> +	/* Read manufacturer and device IDs from Register */
> +	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
> +	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
> +	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
> +	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
> +
>  	/* Flash device information */
>  	mtd->name = onenand_print_device_info(dev_id, ver_id);
>  	this->device_id = dev_id;
> @@ -2659,6 +2685,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
>  	if (!this->write_bufferram)
>  		this->write_bufferram = onenand_write_bufferram;
> 
> +	if (!this->chip_probe)
> +		this->chip_probe = onenand_chip_probe;
> +
>  	if (!this->block_markbad)
>  		this->block_markbad = onenand_default_block_markbad;
>  	if (!this->scan_bbt)
> diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
> index 20b4912..1f4bd81 100644
> --- a/drivers/mtd/onenand/samsung.c
> +++ b/drivers/mtd/onenand/samsung.c
> @@ -590,6 +590,16 @@ static void s3c_set_width_regs(struct onenand_chip
> *this) }
>  #endif
> 
> +int s5pc110_chip_probe(struct mtd_info *mtd)
> +{
> +	return 0;
> +}
> +
> +int s5pc210_chip_probe(struct mtd_info *mtd)
> +{
> +	return 0;
> +}
> +

Will there be a problem if you used the default chip_probe() method from the 
driver ?

>  void s3c_onenand_init(struct mtd_info *mtd)
>  {
>  	struct onenand_chip *this = mtd->priv;
> diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
> index 5465562..dea42f4 100644
> --- a/include/linux/mtd/onenand.h
> +++ b/include/linux/mtd/onenand.h
> @@ -101,6 +101,7 @@ struct onenand_chip {
>  				size_t count);
>  	unsigned short (*read_word) (void __iomem *addr);
>  	void (*write_word) (unsigned short value, void __iomem *addr);
> +	int (*chip_probe)(struct mtd_info *mtd);
>  	void (*mmcontrol) (struct mtd_info *mtd, int sync_read);
>  	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
>  	int (*scan_bbt)(struct mtd_info *mtd);
> diff --git a/include/linux/mtd/samsung_onenand.h
> b/include/linux/mtd/samsung_onenand.h index 021fa27..ddb29bb 100644
> --- a/include/linux/mtd/samsung_onenand.h
> +++ b/include/linux/mtd/samsung_onenand.h
> @@ -127,5 +127,7 @@ struct samsung_onenand {
> 
>  /* common initialize function */
>  extern void s3c_onenand_init(struct mtd_info *);
> +extern int s5pc110_chip_probe(struct mtd_info *);
> +extern int s5pc210_chip_probe(struct mtd_info *);
> 
>  #endif
Kyungmin Park - Nov. 20, 2011, 11:29 p.m.
On 11/20/11, Marek Vasut <marek.vasut@gmail.com> wrote:
>> Separate callback for probing OneNAND memory chip.
>> If no special function is defined, default implementation will be used.
>>
>> This approach gives more flexibility for OneNAND device probing.
>>
>> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  ./tools/checkpatch.pl -
>> total: 0 errors, 0 warnings, 108 lines checked
>>
>> NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX
>> MULTISTATEMENT_MACRO_USE_DO_WHILE
>>
>> ---
>>  drivers/mtd/onenand/onenand_base.c  |   43
>> +++++++++++++++++++++++++++++----- drivers/mtd/onenand/samsung.c       |
>> 10 ++++++++
>>  include/linux/mtd/onenand.h         |    1 +
>>  include/linux/mtd/samsung_onenand.h |    2 +
>>  4 files changed, 49 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mtd/onenand/onenand_base.c
>> b/drivers/mtd/onenand/onenand_base.c index 24e02c2..a557d48 100644
>> --- a/drivers/mtd/onenand/onenand_base.c
>> +++ b/drivers/mtd/onenand/onenand_base.c
>> @@ -2505,23 +2505,24 @@ out:
>>  }
>>
>>  /**
>> - * onenand_probe - [OneNAND Interface] Probe the OneNAND device
>> + * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
>>   * @param mtd		MTD device structure
>>   *
>>   * OneNAND detection method:
>>   *   Compare the the values from command with ones from register
>>   */
>> -static int onenand_probe(struct mtd_info *mtd)
>> +static int onenand_chip_probe(struct mtd_info *mtd)
>>  {
>>  	struct onenand_chip *this = mtd->priv;
>> -	int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
>> -	int density;
>> +	int bram_maf_id, bram_dev_id, maf_id, dev_id;
>>  	int syscfg;
>>
>>  	/* Save system configuration 1 */
>>  	syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
>> +
>>  	/* Clear Sync. Burst Read mode to read BootRAM */
>> -	this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base +
>> ONENAND_REG_SYS_CFG1); +	this->write_word((syscfg &
>> ~ONENAND_SYS_CFG1_SYNC_READ),
>> +			 this->base + ONENAND_REG_SYS_CFG1);
>>
>>  	/* Send the command for reading device ID from BootRAM */
>>  	this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
>> @@ -2546,13 +2547,38 @@ static int onenand_probe(struct mtd_info *mtd)
>>  	/* Read manufacturer and device IDs from Register */
>>  	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
>>  	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
>> -	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
>> -	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
>>
>>  	/* Check OneNAND device */
>>  	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
>>  		return -ENXIO;
>>
>> +	return 0;
>> +}
>> +
>> +/**
>> + * onenand_probe - [OneNAND Interface] Probe the OneNAND device
>> + * @param mtd		MTD device structure
>> + *
>> + * OneNAND detection method:
>> + *   Compare the the values from command with ones from register
>> + */
>> +int onenand_probe(struct mtd_info *mtd)
>> +{
>> +	struct onenand_chip *this = mtd->priv;
>> +	int maf_id, dev_id, ver_id;
>> +	int density;
>> +	int ret;
>> +
>> +	ret = this->chip_probe(mtd);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Read manufacturer and device IDs from Register */
>> +	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
>> +	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
>> +	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
>> +	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
>> +
>>  	/* Flash device information */
>>  	mtd->name = onenand_print_device_info(dev_id, ver_id);
>>  	this->device_id = dev_id;
>> @@ -2659,6 +2685,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
>>  	if (!this->write_bufferram)
>>  		this->write_bufferram = onenand_write_bufferram;
>>
>> +	if (!this->chip_probe)
>> +		this->chip_probe = onenand_chip_probe;
>> +
>>  	if (!this->block_markbad)
>>  		this->block_markbad = onenand_default_block_markbad;
>>  	if (!this->scan_bbt)
>> diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
>> index 20b4912..1f4bd81 100644
>> --- a/drivers/mtd/onenand/samsung.c
>> +++ b/drivers/mtd/onenand/samsung.c
>> @@ -590,6 +590,16 @@ static void s3c_set_width_regs(struct onenand_chip
>> *this) }
>>  #endif
>>
>> +int s5pc110_chip_probe(struct mtd_info *mtd)
>> +{
>> +	return 0;
>> +}
>> +
>> +int s5pc210_chip_probe(struct mtd_info *mtd)
>> +{
>> +	return 0;
>> +}
>> +
>
> Will there be a problem if you used the default chip_probe() method from the
> driver ?
Samsung SoCs have their own OneNAND controller and difficult to access
OneNAND directly. instead it provides the registers which is mapped
OneNAND registers.
e.g., Manufacture ID, device ID and so on.

Yes it's Samsung SoCs specific. that's reason introduce chip_probe
function. it's same as kernel.

Thank you,
Kyungmin Park
>
>>  void s3c_onenand_init(struct mtd_info *mtd)
>>  {
>>  	struct onenand_chip *this = mtd->priv;
>> diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
>> index 5465562..dea42f4 100644
>> --- a/include/linux/mtd/onenand.h
>> +++ b/include/linux/mtd/onenand.h
>> @@ -101,6 +101,7 @@ struct onenand_chip {
>>  				size_t count);
>>  	unsigned short (*read_word) (void __iomem *addr);
>>  	void (*write_word) (unsigned short value, void __iomem *addr);
>> +	int (*chip_probe)(struct mtd_info *mtd);
>>  	void (*mmcontrol) (struct mtd_info *mtd, int sync_read);
>>  	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
>>  	int (*scan_bbt)(struct mtd_info *mtd);
>> diff --git a/include/linux/mtd/samsung_onenand.h
>> b/include/linux/mtd/samsung_onenand.h index 021fa27..ddb29bb 100644
>> --- a/include/linux/mtd/samsung_onenand.h
>> +++ b/include/linux/mtd/samsung_onenand.h
>> @@ -127,5 +127,7 @@ struct samsung_onenand {
>>
>>  /* common initialize function */
>>  extern void s3c_onenand_init(struct mtd_info *);
>> +extern int s5pc110_chip_probe(struct mtd_info *);
>> +extern int s5pc210_chip_probe(struct mtd_info *);
>>
>>  #endif
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>

Patch

diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 24e02c2..a557d48 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -2505,23 +2505,24 @@  out:
 }
 
 /**
- * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
  * @param mtd		MTD device structure
  *
  * OneNAND detection method:
  *   Compare the the values from command with ones from register
  */
-static int onenand_probe(struct mtd_info *mtd)
+static int onenand_chip_probe(struct mtd_info *mtd)
 {
 	struct onenand_chip *this = mtd->priv;
-	int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
-	int density;
+	int bram_maf_id, bram_dev_id, maf_id, dev_id;
 	int syscfg;
 
 	/* Save system configuration 1 */
 	syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+
 	/* Clear Sync. Burst Read mode to read BootRAM */
-	this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
+	this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
+			 this->base + ONENAND_REG_SYS_CFG1);
 
 	/* Send the command for reading device ID from BootRAM */
 	this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -2546,13 +2547,38 @@  static int onenand_probe(struct mtd_info *mtd)
 	/* Read manufacturer and device IDs from Register */
 	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
 	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
-	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
 
 	/* Check OneNAND device */
 	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
 		return -ENXIO;
 
+	return 0;
+}
+
+/**
+ * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * @param mtd		MTD device structure
+ *
+ * OneNAND detection method:
+ *   Compare the the values from command with ones from register
+ */
+int onenand_probe(struct mtd_info *mtd)
+{
+	struct onenand_chip *this = mtd->priv;
+	int maf_id, dev_id, ver_id;
+	int density;
+	int ret;
+
+	ret = this->chip_probe(mtd);
+	if (ret)
+		return ret;
+
+	/* Read manufacturer and device IDs from Register */
+	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
+	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+	ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
+	this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
+
 	/* Flash device information */
 	mtd->name = onenand_print_device_info(dev_id, ver_id);
 	this->device_id = dev_id;
@@ -2659,6 +2685,9 @@  int onenand_scan(struct mtd_info *mtd, int maxchips)
 	if (!this->write_bufferram)
 		this->write_bufferram = onenand_write_bufferram;
 
+	if (!this->chip_probe)
+		this->chip_probe = onenand_chip_probe;
+
 	if (!this->block_markbad)
 		this->block_markbad = onenand_default_block_markbad;
 	if (!this->scan_bbt)
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index 20b4912..1f4bd81 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -590,6 +590,16 @@  static void s3c_set_width_regs(struct onenand_chip *this)
 }
 #endif
 
+int s5pc110_chip_probe(struct mtd_info *mtd)
+{
+	return 0;
+}
+
+int s5pc210_chip_probe(struct mtd_info *mtd)
+{
+	return 0;
+}
+
 void s3c_onenand_init(struct mtd_info *mtd)
 {
 	struct onenand_chip *this = mtd->priv;
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 5465562..dea42f4 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -101,6 +101,7 @@  struct onenand_chip {
 				size_t count);
 	unsigned short (*read_word) (void __iomem *addr);
 	void (*write_word) (unsigned short value, void __iomem *addr);
+	int (*chip_probe)(struct mtd_info *mtd);
 	void (*mmcontrol) (struct mtd_info *mtd, int sync_read);
 	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
 	int (*scan_bbt)(struct mtd_info *mtd);
diff --git a/include/linux/mtd/samsung_onenand.h b/include/linux/mtd/samsung_onenand.h
index 021fa27..ddb29bb 100644
--- a/include/linux/mtd/samsung_onenand.h
+++ b/include/linux/mtd/samsung_onenand.h
@@ -127,5 +127,7 @@  struct samsung_onenand {
 
 /* common initialize function */
 extern void s3c_onenand_init(struct mtd_info *);
+extern int s5pc110_chip_probe(struct mtd_info *);
+extern int s5pc210_chip_probe(struct mtd_info *);
 
 #endif