[PATCH v2] net/phy: micrel: configure intterupts after autoneg workaround

2017-06-20 Thread Zach Brown
The commit ("net/phy: micrel: Add workaround for bad autoneg") fixes an
autoneg failure case by resetting the hardware. This turns off
intterupts. Things will work themselves out if the phy polls, as it will
figure out it's state during a poll. However if the phy uses only
intterupts, the phy will stall, since interrupts are off. This patch
fixes the issue by calling config_intr after resetting the phy.

Fixes: d2fd719bcb0e ("net/phy: micrel: Add workaround for bad autoneg ")
Signed-off-by: Zach Brown 
---
v2:
 * Check phy_intterupt_is_valid before calling config_intr

 drivers/net/phy/micrel.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 9365b07..fdb43dd 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -620,6 +620,8 @@ static int ksz9031_read_status(struct phy_device *phydev)
if ((regval & 0xFF) == 0xFF) {
phy_init_hw(phydev);
phydev->link = 0;
+   if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev))
+   phydev->drv->config_intr(phydev);
}
 
return 0;
-- 
2.7.4



[PATCH] net/phy: micrel: configure intterupts after autoneg workaround

2017-06-16 Thread Zach Brown
The commit ("net/phy: micrel: Add workaround for bad autoneg") fixes
an autoneg failure case by resetting the hardware. This turns off
intterupts. Things will work themselves out if the phy
polls, as it will figure out it's state during a poll. However if the
phy uses only intterupts, the phy will stall, since interrupts
are off.

This patch fixes the issue by calling config_intr after resetting the
phy.

Fixes: d2fd719bcb0e ("net/phy: micrel: Add workaround for bad autoneg ")
Signed-off-by: Zach Brown 
---
 drivers/net/phy/micrel.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 9365b07..bc2a0a4 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -620,6 +620,8 @@ static int ksz9031_read_status(struct phy_device *phydev)
if ((regval & 0xFF) == 0xFF) {
phy_init_hw(phydev);
phydev->link = 0;
+   if (phydev->drv->config_intr)
+   phydev->drv->config_intr(phydev);
}
 
return 0;
-- 
2.7.4



Re: [RESEND PATCH v3] UBI: add debugfs file for tracking PEB state

2017-05-17 Thread Zach Brown
On Wed, May 17, 2017 at 12:36:35PM +0200, Honza Petrouš wrote:
> 2017-05-16 20:22 GMT+02:00 Richard Weinberger :
> > Zach,
> >
> > Am 16.05.2017 um 19:58 schrieb Zach Brown:
> >> From: Ben Shelton 
> >>
> >> Add a file under debugfs to allow easy access to the erase count for
> >> each physical erase block on an UBI device.  This is useful when
> >> debugging data integrity issues with UBIFS on NAND flash devices.
> >>
> >> Signed-off-by: Ben Shelton 
> >> Signed-off-by: Zach Brown 
> >
> > Hmmm, I thought I applied this to my v4.12 queue, but seems
> > like I didn't. So, it will be part of v4.13.
> > I'm very sorry, please accept my apologies.
> 
> Yes, you did it - at least my Linus' github repo clone has it already
> = 7bccd12d27b7e358823feb5429731b8ee698b173
> 
> /Honza

My mistake then. My apologies for the confusion. Thank you for noticing.



[RESEND PATCH v3] UBI: add debugfs file for tracking PEB state

2017-05-16 Thread Zach Brown
From: Ben Shelton 

Add a file under debugfs to allow easy access to the erase count for
each physical erase block on an UBI device.  This is useful when
debugging data integrity issues with UBIFS on NAND flash devices.

Signed-off-by: Ben Shelton 
Signed-off-by: Zach Brown 
---
v2:
* If ubi_io_is_bad eraseblk_count_seq_show just returns the err.
* if ubi->lookuptbl returns null, its no longer treated as an error
  instead info for that block is not printeded
* Removed check for UBI_MAX_ERASECOUNTER since it is impossible to hit
* Removed block state from print, if a block is printed then it is good and
  if it is not printed, then it is bad.

v3:
* Remove errant ! symbol from if statement checking if erase count is valid.

 drivers/mtd/ubi/debug.c | 126 +++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index f101a49..7bc9629 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 /**
@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char 
__user *user_buf,
return count;
 }
 
-/* File operations for all UBI debugfs files */
+/* File operations for all UBI debugfs files except
+ * detailed_erase_block_info
+ */
 static const struct file_operations dfs_fops = {
.read   = dfs_file_read,
.write  = dfs_file_write,
@@ -395,6 +398,121 @@ static const struct file_operations dfs_fops = {
.owner  = THIS_MODULE,
 };
 
+/* As long as the position is less then that total number of erase blocks,
+ * we still have more to print.
+ */
+static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (*pos == 0)
+   return SEQ_START_TOKEN;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+/* Since we are using the position as the iterator, we just need to check if we
+ * are done and increment the position.
+ */
+static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (v == SEQ_START_TOKEN)
+   return pos;
+   (*pos)++;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
+{
+   struct ubi_device *ubi = s->private;
+   struct ubi_wl_entry *wl;
+   int *block_number = iter;
+   int erase_count = -1;
+   int err;
+
+   /* If this is the start, print a header */
+   if (iter == SEQ_START_TOKEN) {
+   seq_puts(s,
+
"physical_block_number\terase_count\tblock_status\tread_status\n");
+   return 0;
+   }
+
+   err = ubi_io_is_bad(ubi, *block_number);
+   if (err)
+   return err;
+
+   spin_lock(&ubi->wl_lock);
+
+   wl = ubi->lookuptbl[*block_number];
+   if (wl)
+   erase_count = wl->ec;
+
+   spin_unlock(&ubi->wl_lock);
+
+   if (erase_count < 0)
+   return 0;
+
+   seq_printf(s, "%-22d\t%-11d\n", *block_number, erase_count);
+
+   return 0;
+}
+
+static const struct seq_operations eraseblk_count_seq_ops = {
+   .start = eraseblk_count_seq_start,
+   .next = eraseblk_count_seq_next,
+   .stop = eraseblk_count_seq_stop,
+   .show = eraseblk_count_seq_show
+};
+
+static int eraseblk_count_open(struct inode *inode, struct file *f)
+{
+   struct seq_file *s;
+   int err;
+
+   err = seq_open(f, &eraseblk_count_seq_ops);
+   if (err)
+   return err;
+
+   s = f->private_data;
+   s->private = ubi_get_device((unsigned long)inode->i_private);
+
+   if (!s->private)
+   return -ENODEV;
+   else
+   return 0;
+}
+
+static int eraseblk_count_release(struct inode *inode, struct file *f)
+{
+   struct seq_file *s = f->private_data;
+   struct ubi_device *ubi = s->private;
+
+   ubi_put_device(ubi);
+
+   return seq_release(inode, f);
+}
+
+static const struct file_operations eraseblk_count_fops = {
+   .owner = THIS_MODULE,
+   .open = eraseblk_count_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = eraseblk_count_release,
+};
+
 /**
  * ubi_debugfs_init_dev - initialize debugfs for an UBI device.
  * @ubi: UBI device description object
@@ -491,6 +609,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove;
d->dfs_power_cut_max = dent;
 
+   fname = "detailed_erase_block_info";
+   dent = debugfs_create_file(fname, S_IRUSR, d->dfs_dir, (void *)ubi_num,
+  

[PATCH v3] UBI: add debugfs file for tracking PEB state

2017-03-27 Thread Zach Brown
From: Ben Shelton 

Add a file under debugfs to allow easy access to the erase count for
each physical erase block on an UBI device.  This is useful when
debugging data integrity issues with UBIFS on NAND flash devices.

Signed-off-by: Ben Shelton 
Signed-off-by: Zach Brown 

v2:
* If ubi_io_is_bad eraseblk_count_seq_show just returns the err.
* if ubi->lookuptbl returns null, its no longer treated as an error
  instead info for that block is not printeded
* Removed check for UBI_MAX_ERASECOUNTER since it is impossible to hit
* Removed block state from print, if a block is printed then it is good and
  if it is not printed, then it is bad.

v3:
* Remove errant ! symbol from if statement checking if erase count is valid.

---
 drivers/mtd/ubi/debug.c | 126 +++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index f101a49..7bc9629 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 /**
@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char 
__user *user_buf,
return count;
 }
 
-/* File operations for all UBI debugfs files */
+/* File operations for all UBI debugfs files except
+ * detailed_erase_block_info
+ */
 static const struct file_operations dfs_fops = {
.read   = dfs_file_read,
.write  = dfs_file_write,
@@ -395,6 +398,121 @@ static const struct file_operations dfs_fops = {
.owner  = THIS_MODULE,
 };
 
+/* As long as the position is less then that total number of erase blocks,
+ * we still have more to print.
+ */
+static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (*pos == 0)
+   return SEQ_START_TOKEN;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+/* Since we are using the position as the iterator, we just need to check if we
+ * are done and increment the position.
+ */
+static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (v == SEQ_START_TOKEN)
+   return pos;
+   (*pos)++;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
+{
+   struct ubi_device *ubi = s->private;
+   struct ubi_wl_entry *wl;
+   int *block_number = iter;
+   int erase_count = -1;
+   int err;
+
+   /* If this is the start, print a header */
+   if (iter == SEQ_START_TOKEN) {
+   seq_puts(s,
+
"physical_block_number\terase_count\tblock_status\tread_status\n");
+   return 0;
+   }
+
+   err = ubi_io_is_bad(ubi, *block_number);
+   if (err)
+   return err;
+
+   spin_lock(&ubi->wl_lock);
+
+   wl = ubi->lookuptbl[*block_number];
+   if (wl)
+   erase_count = wl->ec;
+
+   spin_unlock(&ubi->wl_lock);
+
+   if (erase_count < 0)
+   return 0;
+
+   seq_printf(s, "%-22d\t%-11d\n", *block_number, erase_count);
+
+   return 0;
+}
+
+static const struct seq_operations eraseblk_count_seq_ops = {
+   .start = eraseblk_count_seq_start,
+   .next = eraseblk_count_seq_next,
+   .stop = eraseblk_count_seq_stop,
+   .show = eraseblk_count_seq_show
+};
+
+static int eraseblk_count_open(struct inode *inode, struct file *f)
+{
+   struct seq_file *s;
+   int err;
+
+   err = seq_open(f, &eraseblk_count_seq_ops);
+   if (err)
+   return err;
+
+   s = f->private_data;
+   s->private = ubi_get_device((unsigned long)inode->i_private);
+
+   if (!s->private)
+   return -ENODEV;
+   else
+   return 0;
+}
+
+static int eraseblk_count_release(struct inode *inode, struct file *f)
+{
+   struct seq_file *s = f->private_data;
+   struct ubi_device *ubi = s->private;
+
+   ubi_put_device(ubi);
+
+   return seq_release(inode, f);
+}
+
+static const struct file_operations eraseblk_count_fops = {
+   .owner = THIS_MODULE,
+   .open = eraseblk_count_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = eraseblk_count_release,
+};
+
 /**
  * ubi_debugfs_init_dev - initialize debugfs for an UBI device.
  * @ubi: UBI device description object
@@ -491,6 +609,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove;
d->dfs_power_cut_max = dent;
 
+   fname = "detailed_erase_block_info";
+   dent = debugfs_create_file(fname, S_IRUSR, d->dfs_dir, (void *)ubi_num,
+  

[PATCH v2] UBI: add debugfs file for tracking PEB state

2017-03-24 Thread Zach Brown
From: Ben Shelton 

Add a file under debugfs to allow easy access to the erase count for
each physical erase block on an UBI device.  This is useful when
debugging data integrity issues with UBIFS on NAND flash devices.

Signed-off-by: Ben Shelton 
Signed-off-by: Zach Brown 

v2:
* If ubi_io_is_bad eraseblk_count_seq_show just returns the err.
* if ubi->lookuptbl returns null, its no longer treated as an error
  instead info for that block is not printeded
* Removed check for UBI_MAX_ERASECOUNTER since it is impossible to hit
* Removed block state from print, if a block is printed then it is good and if
  it is not printed, then it is bad.

---
 drivers/mtd/ubi/debug.c | 126 +++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index f101a49..5f2b65d 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 


 /**
@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char 
__user *user_buf,
return count;
 }

-/* File operations for all UBI debugfs files */
+/* File operations for all UBI debugfs files except
+ * detailed_erase_block_info
+ */
 static const struct file_operations dfs_fops = {
.read   = dfs_file_read,
.write  = dfs_file_write,
@@ -395,6 +398,121 @@ static const struct file_operations dfs_fops = {
.owner  = THIS_MODULE,
 };

+/* As long as the position is less then that total number of erase blocks,
+ * we still have more to print.
+ */
+static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (*pos == 0)
+   return SEQ_START_TOKEN;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+/* Since we are using the position as the iterator, we just need to check if we
+ * are done and increment the position.
+ */
+static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (v == SEQ_START_TOKEN)
+   return pos;
+   (*pos)++;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
+{
+   struct ubi_device *ubi = s->private;
+   struct ubi_wl_entry *wl;
+   int *block_number = iter;
+   int erase_count = -1;
+   int err;
+
+   /* If this is the start, print a header */
+   if (iter == SEQ_START_TOKEN) {
+   seq_puts(s,
+
"physical_block_number\terase_count\tblock_status\tread_status\n");
+   return 0;
+   }
+
+   err = ubi_io_is_bad(ubi, *block_number);
+   if (err)
+   return err;
+
+   spin_lock(&ubi->wl_lock);
+
+   wl = ubi->lookuptbl[*block_number];
+   if (wl)
+   erase_count = wl->ec;
+
+   spin_unlock(&ubi->wl_lock);
+
+   if (!erase_count < 0)
+   return 0;
+
+   seq_printf(s, "%-22d\t%-11d\n", *block_number, erase_count);
+
+   return 0;
+}
+
+static const struct seq_operations eraseblk_count_seq_ops = {
+   .start = eraseblk_count_seq_start,
+   .next = eraseblk_count_seq_next,
+   .stop = eraseblk_count_seq_stop,
+   .show = eraseblk_count_seq_show
+};
+
+static int eraseblk_count_open(struct inode *inode, struct file *f)
+{
+   struct seq_file *s;
+   int err;
+
+   err = seq_open(f, &eraseblk_count_seq_ops);
+   if (err)
+   return err;
+
+   s = f->private_data;
+   s->private = ubi_get_device((unsigned long)inode->i_private);
+
+   if (!s->private)
+   return -ENODEV;
+   else
+   return 0;
+}
+
+static int eraseblk_count_release(struct inode *inode, struct file *f)
+{
+   struct seq_file *s = f->private_data;
+   struct ubi_device *ubi = s->private;
+
+   ubi_put_device(ubi);
+
+   return seq_release(inode, f);
+}
+
+static const struct file_operations eraseblk_count_fops = {
+   .owner = THIS_MODULE,
+   .open = eraseblk_count_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = eraseblk_count_release,
+};
+
 /**
  * ubi_debugfs_init_dev - initialize debugfs for an UBI device.
  * @ubi: UBI device description object
@@ -491,6 +609,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove;
d->dfs_power_cut_max = dent;

+   fname = "detailed_erase_block_info";
+   dent = debugfs_create_file(fname, S_IRUSR, d->dfs_dir, (void *)ubi_num,
+  &eraseblk_count_fops);
+   if (IS_ERR_OR_NULL(dent))
+   goto out_remove;
+
return 0;

 out_remove:
--
2.7.4



[PATCH] net: phy: handle state correctly in phy_stop_machine

2017-03-22 Thread Zach Brown
From: Nathan Sullivan 

If the PHY is halted on stop, then do not set the state to PHY_UP.  This
ensures the phy will be restarted later in phy_start when the machine is
started again.

Signed-off-by: Nathan Sullivan 
Signed-off-by: Brad Mouring 
Acked-by: Xander Huff 
Acked-by: Kyle Roeschley 
---
 drivers/net/phy/phy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 7cc1b7d..fe2d4c4 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -678,7 +678,7 @@ void phy_stop_machine(struct phy_device *phydev)
cancel_delayed_work_sync(&phydev->state_queue);
 
mutex_lock(&phydev->lock);
-   if (phydev->state > PHY_UP)
+   if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
phydev->state = PHY_UP;
mutex_unlock(&phydev->lock);
 }
-- 
2.7.4



[RESEND v1] UBI: add debugfs file for tracking PEB state

2017-03-22 Thread Zach Brown
From: Ben Shelton 

Add a file under debugfs to allow easy access to the erase count for
each physical erase block on an UBI device.  This is useful when
debugging data integrity issues with UBIFS on NAND flash devices.

Signed-off-by: Ben Shelton 
Signed-off-by: Zach Brown 
---
 drivers/mtd/ubi/debug.c | 151 +++-
 1 file changed, 150 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index f101a49..6086822 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 /**
@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char 
__user *user_buf,
return count;
 }
 
-/* File operations for all UBI debugfs files */
+/* File operations for all UBI debugfs files except
+ * detailed_erase_block_info
+ */
 static const struct file_operations dfs_fops = {
.read   = dfs_file_read,
.write  = dfs_file_write,
@@ -395,6 +398,146 @@ static const struct file_operations dfs_fops = {
.owner  = THIS_MODULE,
 };
 
+/* As long as the position is less then that total number of erase blocks,
+ * we still have more to print.
+ */
+static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (*pos == 0)
+   return SEQ_START_TOKEN;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+/* Since we are using the position as the iterator, we just need to check if we
+ * are done and increment the position.
+ */
+static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   struct ubi_device *ubi = s->private;
+
+   if (v == SEQ_START_TOKEN)
+   return pos;
+   (*pos)++;
+
+   if (*pos < ubi->peb_count)
+   return pos;
+
+   return NULL;
+}
+
+static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+enum block_status {
+   BLOCK_STATUS_OK,
+   BLOCK_STATUS_BAD_BLOCK,
+   BLOCK_STATUS_ERASE_COUNT_BEYOND_MAX
+};
+
+static char const *block_status_names[] = {"OK", "marked_bad",
+  "erase_count_beyond_max"};
+
+enum read_status {
+   READ_STATUS_OK,
+   READ_STATUS_ERR_READING_BLOCK,
+};
+
+static char const *read_status_names[] = {"OK", "err_reading_block"};
+
+static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
+{
+   struct ubi_device *ubi = s->private;
+   struct ubi_wl_entry *wl;
+   int *block_number = iter;
+   int erase_count = -1;
+   enum block_status b_sts = BLOCK_STATUS_OK;
+   enum read_status r_sts = READ_STATUS_OK;
+   int err;
+
+   /* If this is the start, print a header */
+   if (iter == SEQ_START_TOKEN) {
+   seq_puts(s,
+
"physical_block_number\terase_count\tblock_status\tread_status\n");
+   return 0;
+   }
+
+   err = ubi_io_is_bad(ubi, *block_number);
+   if (err) {
+   if (err < 0)
+   r_sts = READ_STATUS_ERR_READING_BLOCK;
+   else
+   b_sts = BLOCK_STATUS_BAD_BLOCK;
+   } else {
+   spin_lock(&ubi->wl_lock);
+
+   wl = ubi->lookuptbl[*block_number];
+   if (wl)
+   erase_count = wl->ec;
+   else
+   r_sts = READ_STATUS_ERR_READING_BLOCK;
+
+   spin_unlock(&ubi->wl_lock);
+
+   if (erase_count > UBI_MAX_ERASECOUNTER)
+   b_sts = BLOCK_STATUS_ERASE_COUNT_BEYOND_MAX;
+   }
+
+   seq_printf(s, "%-22d\t%-11d\t%-12s\t%-12s\n", *block_number,
+  erase_count, block_status_names[b_sts],
+  read_status_names[r_sts]);
+   return 0;
+}
+
+static const struct seq_operations eraseblk_count_seq_ops = {
+   .start = eraseblk_count_seq_start,
+   .next = eraseblk_count_seq_next,
+   .stop = eraseblk_count_seq_stop,
+   .show = eraseblk_count_seq_show
+};
+
+static int eraseblk_count_open(struct inode *inode, struct file *f)
+{
+   struct seq_file *s;
+   int err;
+
+   err = seq_open(f, &eraseblk_count_seq_ops);
+   if (err)
+   return err;
+
+   s = f->private_data;
+   s->private = ubi_get_device((unsigned long)inode->i_private);
+
+   if (!s->private)
+   return -ENODEV;
+   else
+   return 0;
+}
+
+static int eraseblk_count_release(struct inode *inode, struct file *f)
+{
+   struct seq_file *s = f->private_data;
+   struct ubi_device *ubi = s->private;
+
+   ubi_put_device(ubi);
+
+   return seq_release(inode, f);
+}
+
+static const struct file_operations erase

[PATCH v8 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2017-01-10 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue
v6:
 * Moved bounds checking from "part_max_bad_blocks" to "mtd_max_bad_blocks"
 * Added check for 'ofs < 0' to bounds checking mentioned in change above.
 * Moved assignment of slave->mtd._max_bad_blocks up to be next to the other
   bad-block-related assignments
 * s/lun/die in "nand_max_bad_blocks"
 * Fixed comment style in "nand_max_bad_blocks"
 * In "get_bad_peb_limit" made call to "mtd_max_bad_blocks" occurr only if
   !max_beb_per1024. This makes the ordering the three different ways to set
   the bad_peb_limit: cmdline > Kconfig > automatic with mtd_max_bad_blocks
v7:
 * Moved mtd_max_bad_blocks function to be with other static inline functions
   so it would not look like the odd man out.
v8:
 * Changed local variables in nand_max_bad_blocks /s/uint32_t/u32

 
Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
chips

 drivers/mtd/mtdpart.c| 10 ++
 drivers/mtd/nand/nand_base.c | 40 
 drivers/mtd/ubi/build.c  | 13 +++--
 include/linux/mtd/mtd.h  | 13 +
 include/linux/mtd/nand.h |  5 +
 5 files changed, 79 insertions(+), 2 deletions(-)

-- 
2.7.4



[PATCH v8 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2017-01-10 Thread Zach Brown
From: Jeff Westfahl 

If the user has not set max_beb_per1024 using either the cmdline or
Kconfig options for doing so, use the MTD function 'max_bad_blocks' to
compute the UBI bad_peb_limit.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/ubi/build.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..3029219 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,8 +584,17 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
-   if (!max_beb_per1024)
-   return 0;
+   if (!max_beb_per1024) {
+   /*
+* Since max_beb_per1024 has not been set by the user in either
+* the cmdline or Kconfig, use mtd_max_bad_blocks to set the
+* limit if it is supported by the device.
+*/
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit < 0)
+   return 0;
+   return limit;
+   }
 
/*
 * Here we are using size of the entire flash chip and
-- 
2.7.4



[PATCH v8 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip

2017-01-10 Thread Zach Brown
The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index c5f3a01..4e1b441 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -801,6 +801,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @max_bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -883,6 +886,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16 max_bb_per_die;
+   u32 blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH v8 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2017-01-10 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec1c28a..522baa9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3263,6 +3263,42 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   u32 part_start_block;
+   u32 part_end_block;
+   u32 part_start_die;
+   u32 part_end_die;
+
+   /*
+* max_bb_per_die and blocks_per_die used to determine
+* the maximum bad block count.
+*/
+   if (!chip->max_bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_die = part_start_block / chip->blocks_per_die;
+   part_end_die = part_end_block / chip->blocks_per_die;
+
+   /*
+* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->max_bb_per_die * (part_end_die - part_start_die + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4815,6 +4851,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v8 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

2017-01-10 Thread Zach Brown
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 522baa9..1492c12 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3628,6 +3628,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



[PATCH v8 1/5] mtd: introduce function max_bad_blocks

2017-01-10 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for a MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/mtdpart.c   | 10 ++
 include/linux/mtd/mtd.h | 13 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..08925bb 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,14 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -475,6 +483,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
slave->mtd._block_isbad = part_block_isbad;
if (master->_block_markbad)
slave->mtd._block_markbad = part_block_markbad;
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
 
if (master->_get_device)
slave->mtd._get_device = part_get_device;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..5bb42c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -397,6 +398,18 @@ static inline int mtd_oobavail(struct mtd_info *mtd, 
struct mtd_oob_ops *ops)
return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
 }
 
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (!mtd->_max_bad_blocks)
+   return -ENOTSUPP;
+
+   if (mtd->size < (len + ofs) || ofs < 0)
+   return -EINVAL;
+
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+}
+
 int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
  struct mtd_pairing_info *info);
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
-- 
2.7.4



[PATCH v7 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

2017-01-06 Thread Zach Brown
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 587cd42..11bc2c4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3628,6 +3628,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



[PATCH v7 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2017-01-06 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec1c28a..587cd42 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3263,6 +3263,42 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_die;
+   uint32_t part_end_die;
+
+   /*
+* max_bb_per_die and blocks_per_die used to determine
+* the maximum bad block count.
+*/
+   if (!chip->max_bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_die = part_start_block / chip->blocks_per_die;
+   part_end_die = part_end_block / chip->blocks_per_die;
+
+   /*
+* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->max_bb_per_die * (part_end_die - part_start_die + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4815,6 +4851,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v7 1/5] mtd: introduce function max_bad_blocks

2017-01-06 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for a MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/mtdpart.c   | 10 ++
 include/linux/mtd/mtd.h | 13 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..08925bb 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,14 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -475,6 +483,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
slave->mtd._block_isbad = part_block_isbad;
if (master->_block_markbad)
slave->mtd._block_markbad = part_block_markbad;
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
 
if (master->_get_device)
slave->mtd._get_device = part_get_device;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..5bb42c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -397,6 +398,18 @@ static inline int mtd_oobavail(struct mtd_info *mtd, 
struct mtd_oob_ops *ops)
return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
 }
 
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (!mtd->_max_bad_blocks)
+   return -ENOTSUPP;
+
+   if (mtd->size < (len + ofs) || ofs < 0)
+   return -EINVAL;
+
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+}
+
 int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
  struct mtd_pairing_info *info);
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
-- 
2.7.4



[PATCH v7 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2017-01-06 Thread Zach Brown
From: Jeff Westfahl 

If the user has not set max_beb_per1024 using either the cmdline or
Kconfig options for doing so, use the MTD function 'max_bad_blocks' to
compute the UBI bad_peb_limit.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/ubi/build.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..3029219 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,8 +584,17 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
-   if (!max_beb_per1024)
-   return 0;
+   if (!max_beb_per1024) {
+   /*
+* Since max_beb_per1024 has not been set by the user in either
+* the cmdline or Kconfig, use mtd_max_bad_blocks to set the
+* limit if it is supported by the device.
+*/
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit < 0)
+   return 0;
+   return limit;
+   }
 
/*
 * Here we are using size of the entire flash chip and
-- 
2.7.4



[PATCH v7 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip

2017-01-06 Thread Zach Brown
The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index c5f3a01..4e1b441 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -801,6 +801,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @max_bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -883,6 +886,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16 max_bb_per_die;
+   u32 blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH v7 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2017-01-06 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue
v6:
 * Moved bounds checking from "part_max_bad_blocks" to "mtd_max_bad_blocks"
 * Added check for 'ofs < 0' to bounds checking mentioned in change above.
 * Moved assignment of slave->mtd._max_bad_blocks up to be next to the other
   bad-block-related assignments
 * s/lun/die in "nand_max_bad_blocks"
 * Fixed comment style in "nand_max_bad_blocks"
 * In "get_bad_peb_limit" made call to "mtd_max_bad_blocks" occurr only if
   !max_beb_per1024. This makes the ordering the three different ways to set
   the bad_peb_limit: cmdline > Kconfig > automatic with mtd_max_bad_blocks
v7:
 * Moved mtd_max_bad_blocks function to be with other static inline functions
   so it would not look like the odd man out.


Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
chips

 drivers/mtd/mtdpart.c| 10 ++
 drivers/mtd/nand/nand_base.c | 40 
 drivers/mtd/ubi/build.c  | 13 +++--
 include/linux/mtd/mtd.h  | 13 +
 include/linux/mtd/nand.h |  5 +
 5 files changed, 79 insertions(+), 2 deletions(-)

-- 
2.7.4



[PATCH v6 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-11-30 Thread Zach Brown
From: Jeff Westfahl 

If the user has not set max_beb_per1024 using either the cmdline or
Kconfig options for doing so, use the MTD function 'max_bad_blocks' to
compute the UBI bad_peb_limit.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/ubi/build.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..3029219 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,8 +584,17 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
-   if (!max_beb_per1024)
-   return 0;
+   if (!max_beb_per1024) {
+   /*
+* Since max_beb_per1024 has not been set by the user in either
+* the cmdline or Kconfig, use mtd_max_bad_blocks to set the
+* limit if it is supported by the device.
+*/
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit < 0)
+   return 0;
+   return limit;
+   }
 
/*
 * Here we are using size of the entire flash chip and
-- 
2.7.4



[PATCH v6 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip

2016-11-30 Thread Zach Brown
The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d8905a2..8e9dce1 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @max_bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16 max_bb_per_die;
+   u32 blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH v6 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

2016-11-30 Thread Zach Brown
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b4a7c7f..623cdc5 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3601,6 +3601,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



[PATCH v6 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-11-30 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue
v6:
 * Moved bounds checking from "part_max_bad_blocks" to "mtd_max_bad_blocks"
 * Added check for 'ofs < 0' to bounds checking mentioned in change above.
 * Moved assignment of slave->mtd._max_bad_blocks up to be next to the other
   bad-block-related assignments
 * s/lun/die in "nand_max_bad_blocks"
 * Fixed comment style in "nand_max_bad_blocks"
 * In "get_bad_peb_limit" made call to "mtd_max_bad_blocks" occurr only if
   !max_beb_per1024. This makes the ordering the three different ways to set
   the bad_peb_limit: cmdline > Kconfig > automatic with mtd_max_bad_blocks


Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
chips

 drivers/mtd/mtdpart.c| 10 ++
 drivers/mtd/nand/nand_base.c | 40 
 drivers/mtd/ubi/build.c  | 13 +++--
 include/linux/mtd/mtd.h  | 14 ++
 include/linux/mtd/nand.h |  5 +
 5 files changed, 80 insertions(+), 2 deletions(-)

--
2.7.4



[PATCH v6 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2016-11-30 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/nand/nand_base.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3bde96a..b4a7c7f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3236,6 +3236,42 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_die;
+   uint32_t part_end_die;
+
+   /*
+* max_bb_per_die and blocks_per_die used to determine
+* the maximum bad block count.
+*/
+   if (!chip->max_bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_die = part_start_block / chip->blocks_per_die;
+   part_end_die = part_end_block / chip->blocks_per_die;
+
+   /*
+* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->max_bb_per_die * (part_end_die - part_start_die + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4767,6 +4803,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v6 1/5] mtd: introduce function max_bad_blocks

2016-11-30 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for a MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
Acked-by: Brian Norris 
---
 drivers/mtd/mtdpart.c   | 10 ++
 include/linux/mtd/mtd.h | 14 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..08925bb 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,14 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -475,6 +483,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
slave->mtd._block_isbad = part_block_isbad;
if (master->_block_markbad)
slave->mtd._block_markbad = part_block_markbad;
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
 
if (master->_get_device)
slave->mtd._get_device = part_get_device;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..da6d762 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -402,6 +403,19 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int 
wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
  const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (!mtd->_max_bad_blocks)
+   return -ENOTSUPP;
+
+   if (mtd->size < (len + ofs) || ofs < 0)
+   return -EINVAL;
+
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  void **virt, resource_size_t *phys);
-- 
2.7.4



Re: [PATCH v2] net: phy: Fix use after free in phy_detach()

2016-11-28 Thread Zach Brown
On Mon, Nov 28, 2016 at 03:18:31PM +0100, Geert Uytterhoeven wrote:
> If device_release_driver(&phydev->mdio.dev) is called, it releases all
> resources belonging to the PHY device. Hence the subsequent call to
> phy_led_triggers_unregister() will access already freed memory when
> unregistering the LEDs.
> 
> Move the call to phy_led_triggers_unregister() before the possible call
> to device_release_driver() to fix this.
> 
> Fixes: 2e0bc452f4721520 ("net: phy: leds: add support for led triggers on phy 
> link state change")
> Signed-off-by: Geert Uytterhoeven 
> ---
> This is v2 of "[RFC] net: phy: Fix double free in phy_detach()".
> 
> v2:
>   - Dropped RFC,
>   - Reworded, as commit a7dac9f9c1695d74 ("phy: fix error case of
> phy_led_triggers_(un)register") fixed the double free, and thus the
> warning I was seeing during "poweroff" on sh73a0/kzm9g,
>   - Verified use after free using CONFIG_DEBUG_DEVRES, log_devres = 1,
> and additional debug code printing the address of
> phy->phy_led_triggers. Adding poisoning of freed memory to
> devres_log() will cause a crash.
> ---
>  drivers/net/phy/phy_device.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index ba86c191a13ea81c..a1d6e13b1b4113a4 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -981,6 +981,8 @@ void phy_detach(struct phy_device *phydev)
>   phydev->attached_dev = NULL;
>   phy_suspend(phydev);
>  
> + phy_led_triggers_unregister(phydev);
> +
>   /* If the device had no specific driver before (i.e. - it
>* was using the generic driver), we unbind the device
>* from the generic driver so that there's a chance a
> @@ -994,8 +996,6 @@ void phy_detach(struct phy_device *phydev)
>   }
>   }
>  
> - phy_led_triggers_unregister(phydev);
> -
>   /*
>* The phydev might go away on the put_device() below, so avoid
>* a use-after-free bug by reading the underlying bus first.
> -- 
> 1.9.1
> 

I was able to recreate the issue and confirmed this patch fixes it.
Tested-by: Zach Brown 

--Zach


[PATCH v3 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host controller

2016-11-28 Thread Zach Brown
On some boards, max SDIO frequency is limited by trace lengths and other layout
choices. We would like a way to specify this limitation so the driver can
behave accordingly.

This patch set assumes that the limitation has been reported in an ACPI table
which the driver can check to get the max frequency.

The first patch creates a PCI ID and support for the Intel byt sdio where NI is
the subvendor.

If CONFIG_ACPI is set, the second patch uses the ACPI table to set f_max during
the new ni_byt_sdio_probe_slot.

rv2:
   * Use acpi_evaluate_integer() instead of
 acpi_get_handle()/acpi_evaluate_object()
pv1:
   * Removed redundant comment
   * Print info message if MXFQ not found in acpi table
pv2:
   * Changed info message to error message if MXFQ not found
   * Replaced ni_byt_sdio_probe_slot with one of two versions depending on
 whether CONFIG_ACPI is set.
pv3:
   * Replaced the two versions of ni_byt_sdio_probe_slot with new version that
 calls ni_set_max_freq.
   * Created ni_set_max_freq which sets the slot's max_freq if CONFIG_ACPI is
 set.


Zach Brown (2):
  mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller
sub-vended by NI
  mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio
controller sub-vended by NI

 drivers/mmc/host/sdhci-pci-core.c | 56 +++
 1 file changed, 56 insertions(+)

-- 
2.7.4



[PATCH v3 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio controller sub-vended by NI

2016-11-28 Thread Zach Brown
On NI 9037 boards the max SDIO frequency is limited by trace lengths
and other layout choices. The max SDIO frequency is stored in an ACPI
table.

The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
f_max field of the host.

Signed-off-by: Nathan Sullivan 
Reviewed-by: Jaeden Amero 
Reviewed-by: Josh Cartwright 
Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 9741505..c9e51b1 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pci.h"
@@ -375,8 +376,39 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static int ni_set_max_freq(struct sdhci_pci_slot *slot)
+{
+   acpi_status status;
+   unsigned long long max_freq;
+
+   status = acpi_evaluate_integer(ACPI_HANDLE(&slot->chip->pdev->dev),
+  "MXFQ", NULL, &max_freq);
+   if (ACPI_FAILURE(status)) {
+   dev_err(&slot->chip->pdev->dev,
+   "MXFQ not found in acpi table\n");
+   return -EINVAL;
+   }
+
+   slot->host->mmc->f_max = max_freq * 100;
+
+   return 0;
+}
+#else
+static inline int ni_set_max_freq(struct sdhci_pci_slot *slot)
+{
+   return 0;
+}
+#endif
+
 static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
+   int err;
+
+   err = ni_set_max_freq(slot);
+   if (err)
+   return err;
+
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
 MMC_CAP_WAIT_WHILE_BUSY;
return 0;
-- 
2.7.4



[PATCH v3 1/2] mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller sub-vended by NI

2016-11-28 Thread Zach Brown
Add PCI ID for Intel byt sdio host controller sub-vended by NI.

The controller has different behavior because of the board layout NI
puts it on.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 1d9e00a..9741505 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -375,6 +375,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+MMC_CAP_WAIT_WHILE_BUSY;
+   return 0;
+}
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -447,6 +454,15 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = 
{
.ops= &sdhci_intel_byt_ops,
 };
 
+static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
+   .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+   .quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
+ SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+   .allow_runtime_pm = true,
+   .probe_slot = ni_byt_sdio_probe_slot,
+   .ops= &sdhci_intel_byt_ops,
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
@@ -1079,6 +1095,14 @@ static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+   .subvendor  = PCI_VENDOR_ID_NI,
+   .subdevice  = 0x7884,
+   .driver_data= (kernel_ulong_t)&sdhci_ni_byt_sdio,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= (kernel_ulong_t)&sdhci_intel_byt_sdio,
-- 
2.7.4



[PATCH v2 1/2] mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller sub-vended by NI

2016-11-22 Thread Zach Brown
Add PCI ID for Intel byt sdio host controller sub-vended by NI.

The controller has different behavior because of the board layout NI
puts it on.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 1d9e00a..9741505 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -375,6 +375,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+MMC_CAP_WAIT_WHILE_BUSY;
+   return 0;
+}
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -447,6 +454,15 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = 
{
.ops= &sdhci_intel_byt_ops,
 };
 
+static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
+   .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+   .quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
+ SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+   .allow_runtime_pm = true,
+   .probe_slot = ni_byt_sdio_probe_slot,
+   .ops= &sdhci_intel_byt_ops,
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
@@ -1079,6 +1095,14 @@ static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+   .subvendor  = PCI_VENDOR_ID_NI,
+   .subdevice  = 0x7884,
+   .driver_data= (kernel_ulong_t)&sdhci_ni_byt_sdio,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= (kernel_ulong_t)&sdhci_intel_byt_sdio,
-- 
2.7.4



[PATCH v2 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host controller

2016-11-22 Thread Zach Brown
On some boards, max SDIO frequency is limited by trace lengths and other layout
choices. We would like a way to specify this limitation so the driver can
behave accordingly.

This patch set assumes that the limitation has been reported in an ACPI table
which the driver can check to get the max frequency.

The first patch creates a PCI ID and support for the Intel byt sdio where NI is
the subvendor.

If CONFIG_ACPI is set, the second patch uses the ACPI table to set f_max during
the new ni_byt_sdio_probe_slot.

rv2:
   * Use acpi_evaluate_integer() instead of
 acpi_get_handle()/acpi_evaluate_object()
pv1:
   * Removed redundant comment
   * Print info message if MXFQ not found in acpi table
pv2:
   * Changed info message to error message if MXFQ not found
   * Replaced ni_byt_sdio_probe_slot with one of two versions depending on
 whether CONFIG_ACPI is set.

Zach Brown (2):
  mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller
sub-vended by NI
  mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio
controller sub-vended by NI

 drivers/mmc/host/sdhci-pci-core.c | 52 +++
 1 file changed, 52 insertions(+)

--
2.7.4



[PATCH v2 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio controller sub-vended by NI

2016-11-22 Thread Zach Brown
On NI 9037 boards the max SDIO frequency is limited by trace lengths
and other layout choices. The max SDIO frequency is stored in an ACPI
table.

The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
f_max field of the host.

Signed-off-by: Nathan Sullivan 
Reviewed-by: Jaeden Amero 
Reviewed-by: Josh Cartwright 
Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 9741505..34284b8 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pci.h"
@@ -375,6 +376,30 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   acpi_status status;
+   unsigned long long max_freq;
+
+   status = acpi_evaluate_integer(ACPI_HANDLE(&slot->chip->pdev->dev),
+  "MXFQ", NULL, &max_freq);
+   if (ACPI_FAILURE(status)) {
+   dev_err(&slot->chip->pdev->dev,
+   "MXFQ not found in acpi table\n");
+   return -EINVAL;
+   }
+
+   slot->host->mmc->f_max = max_freq * 100;
+
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+MMC_CAP_WAIT_WHILE_BUSY;
+   return 0;
+}
+
+#else
+
 static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -382,6 +407,9 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot 
*slot)
return 0;
 }
 
+#endif
+
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
-- 
2.7.4



Re: [PATCH 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host

2016-11-22 Thread Zach Brown
On Tue, Nov 22, 2016 at 09:27:29AM +0100, Ulf Hansson wrote:
>
> Please try to not forget to bump the version number and to provide a
> history of the what changes between revisions. It makes life easier
> when reviewing and when I am about to apply patches.
>

Sorry, I'll make sure to include a history.
When switching from RFC to PATCH should the version number of the PATCH
be 1 or the lastest RFC version plus 1? Or does it not matter either way
as long as the history is present?

--
Zach


[PATCH 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host

2016-11-21 Thread Zach Brown
On some boards, max SDIO frequency is limited by trace lengths and other layout
choices. We would like a way to specify this limitation so the driver can
behave accordingly.

This patch set assumes that the limitation has been reported in an ACPI table
which the driver can check to get the max frequency.

The first patch creates a PCI ID and support for the Intel byt sdio where NI is
the subvendor.

The second patch uses the ACPI table to set f_max during the new
ni_byt_sdio_probe_slot.


Zach Brown (2):
  mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller
sub-vended by NI
  mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio
controller sub-vended by NI

 drivers/mmc/host/sdhci-pci-core.c | 39 +++
 1 file changed, 39 insertions(+)

-- 
2.7.4



[PATCH 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio controller sub-vended by NI

2016-11-21 Thread Zach Brown
On NI 9037 boards the max SDIO frequency is limited by trace lengths
and other layout choices. The max SDIO frequency is stored in an ACPI
table.

The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
f_max field of the host.

Signed-off-by: Nathan Sullivan 
Reviewed-by: Jaeden Amero 
Reviewed-by: Josh Cartwright 
Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 9741505..a855c97 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pci.h"
@@ -377,6 +378,20 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 
 static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
+#ifdef CONFIG_ACPI
+   acpi_status status;
+   unsigned long long max_freq;
+
+   status = acpi_evaluate_integer(ACPI_HANDLE(&slot->chip->pdev->dev),
+  "MXFQ", NULL, &max_freq);
+   if (ACPI_FAILURE(status)) {
+   dev_info(&slot->chip->pdev->dev,
+   "MXFQ not found in acpi table\n");
+   return -EINVAL;
+   }
+
+   slot->host->mmc->f_max = max_freq * 100;
+#endif
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
 MMC_CAP_WAIT_WHILE_BUSY;
return 0;
-- 
2.7.4



[PATCH 1/2] mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller sub-vended by NI

2016-11-21 Thread Zach Brown
Add PCI ID for Intel byt sdio host controller sub-vended by NI.

The controller has different behavior because of the board layout NI
puts it on.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 1d9e00a..9741505 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -375,6 +375,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+MMC_CAP_WAIT_WHILE_BUSY;
+   return 0;
+}
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -447,6 +454,15 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = 
{
.ops= &sdhci_intel_byt_ops,
 };
 
+static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
+   .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+   .quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
+ SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+   .allow_runtime_pm = true,
+   .probe_slot = ni_byt_sdio_probe_slot,
+   .ops= &sdhci_intel_byt_ops,
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
@@ -1079,6 +1095,14 @@ static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+   .subvendor  = PCI_VENDOR_ID_NI,
+   .subdevice  = 0x7884,
+   .driver_data= (kernel_ulong_t)&sdhci_ni_byt_sdio,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= (kernel_ulong_t)&sdhci_intel_byt_sdio,
-- 
2.7.4



[RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2016-11-21 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3bde96a..193a6b7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3236,6 +3236,40 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* max_bb_per_lun and blocks_per_lun used to determine
+* the maximum bad block count.
+*/
+   if (!chip->max_bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->blocks_per_die;
+   part_end_lun = part_end_block / chip->blocks_per_die;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->max_bb_per_die * (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4767,6 +4801,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[RESEND PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip

2016-11-21 Thread Zach Brown
The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d8905a2..8e9dce1 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @max_bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16 max_bb_per_die;
+   u32 blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[RESEND PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

2016-11-21 Thread Zach Brown
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 193a6b7..fb5b585 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3599,6 +3599,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



[RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-11-21 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
chips

 drivers/mtd/mtdpart.c| 12 
 drivers/mtd/nand/nand_base.c | 38 ++
 drivers/mtd/ubi/build.c  |  4 
 include/linux/mtd/mtd.h  | 11 +++
 include/linux/mtd/nand.h |  5 +
 5 files changed, 70 insertions(+)

-- 
2.7.4



[RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks

2016-11-21 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/mtdpart.c   | 12 
 include/linux/mtd/mtd.h | 11 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..565f0dd 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -481,6 +491,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..c02d3c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int 
wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
  const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (mtd->_max_bad_blocks)
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+
+   return -ENOTSUPP;
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  void **virt, resource_size_t *phys);
-- 
2.7.4



[RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-11-21 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/ubi/build.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..e9940a9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



[RFC v2 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host controller

2016-11-15 Thread Zach Brown
On some boards, max SDIO frequency is limited by trace lengths and other layout
choices. We would like a way to specify this limitation so the driver can
behave accordingly.

This patch set assumes that the limitation has been reported in an ACPI table
which the driver can check to get the max frequency.

The first patch creates a PCI ID and support for the Intel byt sdio where NI is
the subvendor.

The second patch uses the ACPI table to set f_max during the new
ni_byt_sdio_probe_slot.

v2:
  * Use acpi_evaluate_integer() instead of
acpi_get_handle()/acpi_evaluate_object()


Zach Brown (2):
  mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller
sub-vended by NI
  mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio
controller sub-vended by NI

 drivers/mmc/host/sdhci-pci-core.c | 37 +
 1 file changed, 37 insertions(+)

-- 
2.7.4



[RFC v2 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio controller sub-vended by NI

2016-11-15 Thread Zach Brown
On NI 9037 boards the max SDIO frequency is limited by trace lengths
and other layout choices. The max SDIO frequency is stored in an ACPI
table.

The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
f_max field of the host.

Signed-off-by: Nathan Sullivan 
Reviewed-by: Jaeden Amero 
Reviewed-by: Josh Cartwright 
Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 9741505..4c31d16 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pci.h"
@@ -377,6 +378,18 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 
 static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
+#ifdef CONFIG_ACPI
+   /* Get max freq from ACPI for NI hardware */
+   acpi_status status;
+   unsigned long long max_freq;
+
+   status = acpi_evaluate_integer(ACPI_HANDLE(&slot->chip->pdev->dev),
+  "MXFQ", NULL, &max_freq);
+   if (ACPI_FAILURE(status))
+   return -EINVAL;
+
+   slot->host->mmc->f_max = max_freq * 100;
+#endif
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
 MMC_CAP_WAIT_WHILE_BUSY;
return 0;
-- 
2.7.4



[RFC v2 1/2] mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller sub-vended by NI

2016-11-15 Thread Zach Brown
Add PCI ID for Intel byt sdio host controller sub-vended by NI.

The controller has different behavior because of the board layout NI
puts it on.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 1d9e00a..9741505 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -375,6 +375,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+MMC_CAP_WAIT_WHILE_BUSY;
+   return 0;
+}
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -447,6 +454,15 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = 
{
.ops= &sdhci_intel_byt_ops,
 };
 
+static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
+   .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+   .quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
+ SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+   .allow_runtime_pm = true,
+   .probe_slot = ni_byt_sdio_probe_slot,
+   .ops= &sdhci_intel_byt_ops,
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
@@ -1079,6 +1095,14 @@ static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+   .subvendor  = PCI_VENDOR_ID_NI,
+   .subdevice  = 0x7884,
+   .driver_data= (kernel_ulong_t)&sdhci_ni_byt_sdio,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= (kernel_ulong_t)&sdhci_intel_byt_sdio,
-- 
2.7.4



Re: [RFC 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio host controller sub-vended by NI

2016-11-09 Thread Zach Brown
On Wed, Nov 09, 2016 at 03:24:24PM +0200, Adrian Hunter wrote:
> On 08/11/16 22:07, Zach Brown wrote:
> > On NI 9037 boards the max SDIO frequency is limited by trace lengths
> > and other layout choices. The max SDIO frequency is stored in an ACPI
> > table, as MXFQ.
> >
> > The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
> > f_max field of the host with it.
> >
> > Signed-off-by: Nathan Sullivan 
> > Reviewed-by: Jaeden Amero 
> > Reviewed-by: Josh Cartwright 
> > Signed-off-by: Zach Brown 
> > ---
> >  drivers/mmc/host/sdhci-pci-core.c | 30 ++
> >  1 file changed, 30 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-pci-core.c 
> > b/drivers/mmc/host/sdhci-pci-core.c
> > index c333ce2..4ac7f16 100644
> > --- a/drivers/mmc/host/sdhci-pci-core.c
> > +++ b/drivers/mmc/host/sdhci-pci-core.c
> > @@ -27,6 +27,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include "sdhci.h"
> >  #include "sdhci-pci.h"
> > @@ -377,6 +378,35 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot 
> > *slot)
> >
> >  static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
> >  {
> > +#ifdef CONFIG_ACPI
> > +   /* Get max freq from ACPI for NI hardware */
> > +   acpi_handle acpi_hdl;
> > +   acpi_status status;
> > +   struct acpi_buffer acpi_result = {
> > +   ACPI_ALLOCATE_BUFFER, NULL };
> > +   union acpi_object *acpi_buffer;
> > +   int max_freq;
> > +
> > +   status = acpi_get_handle(ACPI_HANDLE(&slot->chip->pdev->dev), "MXFQ",
> > +&acpi_hdl);
>
> Is "MXFQ" an object that has already been deployed or are you inventing it
> now?  In the latter case, did you consider device properties as an 
> alternative?
>
"MXFQ" is an object that we have already deployed on some of our devices.

> > +   if (ACPI_FAILURE(status))
> > +   return  -ENODEV;
> > +
> > +   status = acpi_evaluate_object(acpi_hdl, NULL,
> > + NULL, &acpi_result);
> > +   if (ACPI_FAILURE(status))
> > +   return -EINVAL;
> > +
> > +   acpi_buffer = (union acpi_object *)acpi_result.pointer;
> > +
> > +   if (acpi_buffer->type != ACPI_TYPE_INTEGER)
> > +   return -EINVAL;
> > +
> > +   max_freq = acpi_buffer->integer.value;
> > +
> > +   slot->host->mmc->f_max = max_freq * 100;
> > +#endif
> > +
> > slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
> > return 0;
> >  }
> >
>


[RFC 1/2] mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller sub-vended by NI

2016-11-08 Thread Zach Brown
Add PCI ID for Intel byt sdio host controller sub-vended by NI.

The controller has different behavior because of the board layout NI
puts it on.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 1d9e00a..c333ce2 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -375,6 +375,12 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
 }
 
+static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
+   return 0;
+}
+
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
@@ -447,6 +453,12 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = 
{
.ops= &sdhci_intel_byt_ops,
 };
 
+static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
+   .quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+   .allow_runtime_pm = true,
+   .probe_slot = ni_byt_sdio_probe_slot,
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.quirks2= SDHCI_QUIRK2_HOST_OFF_CARD_ON |
@@ -1079,6 +1091,14 @@ static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+   .subvendor  = PCI_VENDOR_ID_NI,
+   .subdevice  = 0x7884,
+   .driver_data= (kernel_ulong_t)&sdhci_ni_byt_sdio,
+   },
+
+   {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
.subvendor  = PCI_ANY_ID,
.subdevice  = PCI_ANY_ID,
.driver_data= (kernel_ulong_t)&sdhci_intel_byt_sdio,
-- 
2.7.4



[RFC 0/2] mmc: sdhci-pci: Use ACPI to set max frequency of sdio host

2016-11-08 Thread Zach Brown
On some boards, max SDIO frequency is limited by trace lengths and other layout
choices. We would like a way to specify this limitation so the driver can
behave accordingly.

This patch set assumes that the limitation has been reported in an ACPI table
which the driver can check to get the max frequency.

The first patch creates a PCI ID and support for the Intel byt sdio where NI is
the subvendor.

The second patch uses the ACPI table to set f_max during the new
ni_byt_sdio_probe_slot.


Zach Brown (2):
  mmc: sdhci-pci: Add PCI ID for Intel byt sdio host controller
sub-vended by NI
  mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio
host controller sub-vended by NI

 drivers/mmc/host/sdhci-pci-core.c | 50 +++
 1 file changed, 50 insertions(+)

--
2.7.4



[RFC 2/2] mmc: sdhci-pci: Use ACPI to get max frequency for Intel byt sdio host controller sub-vended by NI

2016-11-08 Thread Zach Brown
On NI 9037 boards the max SDIO frequency is limited by trace lengths
and other layout choices. The max SDIO frequency is stored in an ACPI
table, as MXFQ.

The driver reads the ACPI entry MXFQ during sdio_probe_slot and sets the
f_max field of the host with it.

Signed-off-by: Nathan Sullivan 
Reviewed-by: Jaeden Amero 
Reviewed-by: Josh Cartwright 
Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci-pci-core.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index c333ce2..4ac7f16 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pci.h"
@@ -377,6 +378,35 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 
 static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
+#ifdef CONFIG_ACPI
+   /* Get max freq from ACPI for NI hardware */
+   acpi_handle acpi_hdl;
+   acpi_status status;
+   struct acpi_buffer acpi_result = {
+   ACPI_ALLOCATE_BUFFER, NULL };
+   union acpi_object *acpi_buffer;
+   int max_freq;
+
+   status = acpi_get_handle(ACPI_HANDLE(&slot->chip->pdev->dev), "MXFQ",
+&acpi_hdl);
+   if (ACPI_FAILURE(status))
+   return  -ENODEV;
+
+   status = acpi_evaluate_object(acpi_hdl, NULL,
+ NULL, &acpi_result);
+   if (ACPI_FAILURE(status))
+   return -EINVAL;
+
+   acpi_buffer = (union acpi_object *)acpi_result.pointer;
+
+   if (acpi_buffer->type != ACPI_TYPE_INTEGER)
+   return -EINVAL;
+
+   max_freq = acpi_buffer->integer.value;
+
+   slot->host->mmc->f_max = max_freq * 100;
+#endif
+
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
return 0;
 }
-- 
2.7.4



[PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

2016-11-07 Thread Zach Brown
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 193a6b7..fb5b585 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3599,6 +3599,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



[PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip

2016-11-07 Thread Zach Brown
The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d8905a2..8e9dce1 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @max_bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16 max_bb_per_die;
+   u32 blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2016-11-07 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/nand/nand_base.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3bde96a..193a6b7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3236,6 +3236,40 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* max_bb_per_lun and blocks_per_lun used to determine
+* the maximum bad block count.
+*/
+   if (!chip->max_bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->blocks_per_die;
+   part_end_lun = part_end_block / chip->blocks_per_die;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->max_bb_per_die * (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4767,6 +4801,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-11-07 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
chips

 drivers/mtd/mtdpart.c| 12 
 drivers/mtd/nand/nand_base.c | 38 ++
 drivers/mtd/ubi/build.c  |  4 
 include/linux/mtd/mtd.h  | 11 +++
 include/linux/mtd/nand.h |  5 +
 5 files changed, 70 insertions(+)

--
2.7.4



[PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-11-07 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/ubi/build.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..e9940a9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



[PATCH v5 1/5] mtd: introduce function max_bad_blocks

2016-11-07 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
Acked-by: Boris Brezillon 
---
 drivers/mtd/mtdpart.c   | 12 
 include/linux/mtd/mtd.h | 11 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..565f0dd 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -481,6 +491,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..c02d3c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int 
wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
  const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (mtd->_max_bad_blocks)
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+
+   return -ENOTSUPP;
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  void **virt, resource_size_t *phys);
-- 
2.7.4



[PATCH v2 2/2] mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read during __sdhci_read_caps

2016-11-02 Thread Zach Brown
The sdhci capabilities register can be incorrect. The sdhci-caps-mask
and sdhci-caps dt properties specify which bits of the register are
incorrect and what their values should be. This patch makes the sdhci
driver use those properties to correct the caps during
__sdhci_read_caps.

During __sdhci_read_caps
Use the sdhci-caps-mask property to turn off the incorrect bits of the
sdhci register after reading them.
Use the sdhci-caps to turn on bits after using sdhci-caps-mask to turn
off the incorrect ones.

Signed-off-by: Zach Brown 
Acked-by: Adrian Hunter 
---
 drivers/mmc/host/sdhci.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01..eba5f39 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -2991,6 +2992,8 @@ static int sdhci_set_dma_mask(struct sdhci_host *host)
 void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 
*caps1)
 {
u16 v;
+   u64 dt_caps_mask = 0;
+   u64 dt_caps = 0;
 
if (host->read_caps)
return;
@@ -3005,18 +3008,35 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
*ver, u32 *caps, u32 *caps1)
 
sdhci_do_reset(host, SDHCI_RESET_ALL);
 
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps-mask", &dt_caps_mask);
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps", &dt_caps);
+
v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
 
if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
return;
 
-   host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
+   if (caps) {
+   host->caps = *caps;
+   } else {
+   host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+   host->caps &= ~lower_32_bits(dt_caps_mask);
+   host->caps |= lower_32_bits(dt_caps);
+   }
 
if (host->version < SDHCI_SPEC_300)
return;
 
-   host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   if (caps1) {
+   host->caps1 = *caps1;
+   } else {
+   host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   host->caps1 &= ~upper_32_bits(dt_caps_mask);
+   host->caps1 |= upper_32_bits(dt_caps);
+   }
 }
 EXPORT_SYMBOL_GPL(__sdhci_read_caps);
 
-- 
2.7.4



[PATCH v2 1/2] mmc: sdhci: dt: Add device tree properties sdhci-caps and sdhci-caps-mask

2016-11-02 Thread Zach Brown
On some systems the sdhci capabilty register is incorrect for one
reason or another.

The sdhci-caps-mask property specifies which bits in the register
are incorrect and should be turned off before using sdhci-caps to turn
on bits.

The sdhci-caps property specifies which bits should be turned on.

Signed-off-by: Zach Brown 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/mmc/sdhci.txt | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci.txt 
b/Documentation/devicetree/bindings/mmc/sdhci.txt
new file mode 100644
index 000..0f4f1bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci.txt
@@ -0,0 +1,14 @@
+The properties specific for SD host controllers. For properties shared by MMC
+host controllers refer to the mmc[1] bindings.
+
+  [1] Documentation/devicetree/bindings/mmc/mmc.txt
+
+Optional properties:
+- sdhci-caps-mask: The sdhci capabilities register is incorrect. This 64bit
+  property corresponds to the bits in the sdhci capabilty register. If the bit
+  is on in the mask then the bit is incorrect in the register and should be
+  turned off, before applying sdhci-caps.
+- sdhci-caps: The sdhci capabilities register is incorrect. This 64bit
+  property corresponds to the bits in the sdhci capability register. If the
+  bit is on in the property then the bit should be turned on.
+
-- 
2.7.4



[PATCH v2 0/2] mmc: sdhci: Fix sdhci caps register bits with corrections provided by dt

2016-11-02 Thread Zach Brown
For various reasons the sdhci caps register can be incorrect. This patch set
introduces a general way to correct the bits when they are read to accurately
reflect the capabilties of the controller/board combo.

The first patch creates sdhci-caps and sdhci-caps-mask dt properties that
combined represent the correction to the sdhci caps register.

The second patch uses the new dt properties to correct the caps from the
register as they read during __sdhci_read_caps.

Changes from RFC:
 * /s/registers/register
 * Moved sdhci dt properties into new documentation file sdhci.txt
v2:
 * Fixed style issue, all branches of 'if' should have {}


Zach Brown (2):
  mmc: sdhci: dt: Add device tree properties sdhci-caps and
sdhci-caps-mask
  mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read
during __sdhci_read_caps

 Documentation/devicetree/bindings/mmc/sdhci.txt | 14 ++
 drivers/mmc/host/sdhci.c| 24 ++--
 2 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci.txt

-- 
2.7.4



Re: [PATCH v3 3/5] mtd: nand: Add bb_per_lun and blocks_per_lun fields to nand_chip

2016-11-01 Thread Zach Brown
On Tue, Nov 01, 2016 at 02:50:58PM +0100, Boris Brezillon wrote:
> On Fri, 28 Oct 2016 15:27:42 -0500
> Zach Brown  wrote:
>
> > The fields bb_per_lun and blocks_per_lun are useful determining the
> > number of bad blocks a MTD needs to allocate. How they are set will
> > depend on if the chip is ONFI, JEDEC or a fuill-id entry in the nand_ids
> > table.
> >
> > Signed-off-by: Zach Brown 
> > ---
> >  include/linux/mtd/nand.h | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> > index c5d3d502..efbe439 100644
> > --- a/include/linux/mtd/nand.h
> > +++ b/include/linux/mtd/nand.h
> > @@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface 
> > *conf)
> >   * supported, 0 otherwise.
> >   * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
> >   * supported, 0 otherwise.
> > + * @bb_per_lun:[INTERN] the max number of bad blocks each LUN of a
> > + * this nand device will encounter their life times.
> > + * @blocks_per_lun:[INTERN] The number of PEBs in a LUN
> >   * @read_retries:  [INTERN] the number of read retry modes supported
> >   * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
> >   * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
> > @@ -853,6 +856,8 @@ struct nand_chip {
> > struct nand_onfi_params onfi_params;
> > struct nand_jedec_params jedec_params;
> > };
> > +   __le16 bb_per_lun;
> > +   __le32 blocks_per_lun;
>
> Two things I don't like here:
> - you use little-endian types, while it should use native endianness.
>   Make it easier, and just declare those fields as int (or unsigned
>   int).
> - you stick to the ONFI spec, while I'd prefer to see the term lun
>   replaced by die, and I wonder if we don't already have a field
>   storing the number of blocks per die (I might be wrong though).
>

I looked for an existing field for number of blocks per die and could not find
it. Perhaps you were remembering chipsize? or numchips? I looked at how they
were calculated and chipsize is a multiple of (blocks_per_lun * lun_count) so
it can't be used to find blocks_per_lun without storing lun_count anyways.
Let me know if you think I missed something.


[PATCH v4 1/5] mtd: introduce function max_bad_blocks

2016-11-01 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/mtdpart.c   | 13 +
 include/linux/mtd/mtd.h | 11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..2106bd5 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -481,6 +491,9 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
+
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..c02d3c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int 
wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
  const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (mtd->_max_bad_blocks)
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+
+   return -ENOTSUPP;
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  void **virt, resource_size_t *phys);
-- 
2.7.4



[PATCH v4 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-11-01 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v1:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v2:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v3:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html


Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set bb_per_die and blocks_per_die for ONFI compliant chips

 drivers/mtd/mtdpart.c| 13 +
 drivers/mtd/nand/nand_base.c | 39 +++
 drivers/mtd/ubi/build.c  |  4 
 include/linux/mtd/mtd.h  | 11 +++
 include/linux/mtd/nand.h |  5 +
 5 files changed, 72 insertions(+)

--
2.7.4



[PATCH v4 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-11-01 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/ubi/build.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..e9940a9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



[PATCH v4 3/5] mtd: nand: Add bb_per_die and blocks_per_die fields to nand_chip

2016-11-01 Thread Zach Brown
The fields bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d8905a2..3093827 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @bb_per_die:[INTERN] the max number of bad blocks each die of a
+ * this nand device will encounter their life times.
+ * @blocks_per_die:[INTERN] The number of PEBs in a die
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   u16  bb_per_die;
+   u32  blocks_per_die;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH v4 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2016-11-01 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
bb_per_die and blocks_per_die fields to determine the maximum bad blocks
to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3bde96a..be48e37 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3236,6 +3236,40 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* bb_per_lun and blocks_per_lun used to determine
+* the maximum bad block count.
+*/
+   if (!chip->bb_per_die || !chip->blocks_per_die)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->blocks_per_die;
+   part_end_lun = part_end_block / chip->blocks_per_die;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->bb_per_die * (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4767,6 +4801,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v4 5/5] mtd: nand: set bb_per_die and blocks_per_die for ONFI compliant chips

2016-11-01 Thread Zach Brown
ONFI compliant chips contain the values for the bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index be48e37..edf28b6 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3599,6 +3599,10 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
 
+   chip->bb_per_die = le16_to_cpu(p->bb_per_lun);
+   chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
+
if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
-- 
2.7.4



Re: [RFC 1/2] mmc: sdhci: dt: Add device tree properties sdhci-caps and sdhci-caps-mask

2016-11-01 Thread Zach Brown
On Tue, Nov 01, 2016 at 07:13:29AM +0900, Jaehoon Chung wrote:
> On 10/31/2016 09:34 PM, Adrian Hunter wrote:
> > On 31/10/16 13:59, Jaehoon Chung wrote:
> >> On 10/28/2016 05:12 PM, Ulf Hansson wrote:
> >>> On 25 October 2016 at 21:58, Zach Brown  wrote:
> >>>> On some systems the sdhci capabilty registers are incorrect for one
> >>>> reason or another.
> >>>>
> >>>> The sdhci-caps-mask property specifies which bits in the registers
> >>>> are incorrect and should be turned off before using sdhci-caps to turn
> >>>> on bits.
> >>>>
> >>>> The sdhci-caps property specifies which bits should be turned on.
> >>>>
> >>>> Signed-off-by: Zach Brown 
> >>>> ---
> >>>>  Documentation/devicetree/bindings/mmc/mmc.txt | 7 +++
> >>>>  1 file changed, 7 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt 
> >>>> b/Documentation/devicetree/bindings/mmc/mmc.txt
> >>>> index 8a37782..1415aa0 100644
> >>>> --- a/Documentation/devicetree/bindings/mmc/mmc.txt
> >>>> +++ b/Documentation/devicetree/bindings/mmc/mmc.txt
> >>>
> >>> The bindings in this document are common mmc DT bindings, not bindings
> >>> specific to a mmc controller.
> >>>
> >>> So unless these bindings are applicable for another controller than
> >>> sdhci, I suggest we create a new file to document these.
> >>> How about Documentation/devicetree/bindings/mmc/sdhci.txt?
> >>>
> >>>> @@ -52,6 +52,13 @@ Optional properties:
> >>>>  - no-sdio: controller is limited to send sdio cmd during initialization
> >>>>  - no-sd: controller is limited to send sd cmd during initialization
> >>>>  - no-mmc: controller is limited to send mmc cmd during initialization
> >>>> +- sdhci-caps-mask: The sdhci capabilities registers are incorrect. This 
> >>>> 64bit
> >>>
> >>> /s/registers/register
> >>>
> >>> This applies to some more places below as well.
> >>>
> >>>> +  property corresponds to the bits in the sdhci capabilty registers. If 
> >>>> the bit
> >>>> +  is on in the mask then the bit is incorrect in the registers and 
> >>>> should be
> >>>> +  turned off.
> >>>> +- sdhci-caps: The sdhci capabilities registers are incorrect. This 64bit
> >>>> +  property corresponds to the bits in the sdhci capability registers. 
> >>>> If the
> >>>> +  bit is on in the property then the bit should be on in the reigsters.
> >>>
> >>> /s/reigsters/register
> >>>
> >>>>
> >>>>  *NOTE* on CD and WP polarity. To use common for all SD/MMC host 
> >>>> controllers line
> >>>>  polarity properties, we have to fix the meaning of the "normal" and 
> >>>> "inverted"
> >>>> --
> >>>> 2.7.4
> >>>>
> >>>
> >>> Overall, I like this idea as it gives us good flexibility. Thus it
> >>> should avoid us to having to add any further new similar "sdhci broken
> >>> cap" DT binding. We could also decide to start deprecate some of the
> >>> existing sdhci bindings, if we think that makes sense.
> >>>
> >>> The downside is that we get a "magic" hex value in the dts. Although,
> >>> people could address this issue by providing some comments about what
> >>> the bits it means in the dts files themselves.
> >>
> >> I think it's not good about getting "magic" hex value.
> >> In my experience, it's too difficult what bits means and calculate..
> >> Because some people who i know had already used like this.(locally..)
> >>
> >> It needs to consider this...otherwise..it should become really complex 
> >> magic code.
> >
> > The bits we use are listed in sdhci.h and how we use them can be determined
> > from the sdhci source code.  Also, from the hardware perspective, there is
> > the SDHCI specification.  So what the bits mean is readily available.
> >
> > With regard to calculating the values, won't it be obvious from testing if
> > they are wrong?
>
> You're right. But I didn't see the real use case for this properties.
> If it needs to add these properties, why didn't add codes relevant to these 
> in device-tree?
> Otherwise, this code should be dead code.
>

The issue here is the sdhci has a register that is supposed report the
capabilities of the device, but it can be wrong. It might turn on a mode or
behavior that should not be on.

For example, in our use case the sdhci itself is capable of highspeed so it
naturally has the highspeed capable bit set in it's capabilities register.
However due to board setup, the entire system is not actually capable of
highspeed. So we need a way to say the sdhci capabilities register's highspeed
bit is incorrect.

A simple "no-sdhci-highspeed" device tree property might suffice, but there are
roughly ~64 sdhci capabilities represented in the capabilities register.
Instead of creating ~64 device-tree properties to handle each individually this
patch set creates just two that handle them all. In a way that is flexible
enough to correct all ~64 or just 1 or any subset depending on the use case.


[PATCH v3 4/5] mtd: nand: implement 'max_bad_blocks' mtd function

2016-10-28 Thread Zach Brown
Implement the new mtd function 'max_bad_blocks'. Using the chip's
bb_per_lun and blocks_per_lun fields to determine the maximum bad blocks
to reserve for an MTD.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e5718e5..ed8dc89 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3226,6 +3226,40 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* bb_per_lun and blocks_per_lun used to determine
+* the maximum bad block count.
+*/
+   if (!chip->bb_per_lun || !chip->blocks_per_lun)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->blocks_per_lun;
+   part_end_lun = part_end_block / chip->blocks_per_lun;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->bb_per_lun * (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4743,6 +4777,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v3 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-10-28 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/ubi/build.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..e9940a9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



[PATCH v3 5/5] mtd: nand: set bb_per_lun and blocks_per_lun for ONFI compliant chips

2016-10-28 Thread Zach Brown
ONFI compliant chips contain the values for the bb_per_lun and
blocks_per_lun fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ed8dc89..c4ced91 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3619,6 +3619,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, 
struct nand_chip *chip,
if (p->jedec_id == NAND_MFR_MICRON)
nand_onfi_detect_micron(chip, p);
 
+   if (p->bb_per_lun)
+   chip->bb_per_lun = p->bb_per_lun;
+   if (p->blocks_per_lun)
+   chip->blocks_per_lun = p->blocks_per_lun;
+
return 1;
 }
 
-- 
2.7.4



[PATCH v3 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-10-28 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v1:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v2:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add bb_per_lun and blocks_per_lun fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set bb_per_lun and blocks_per_lun for ONFI compliant chips

 drivers/mtd/mtdpart.c| 13 +
 drivers/mtd/nand/nand_base.c | 40 
 drivers/mtd/ubi/build.c  |  4 
 include/linux/mtd/mtd.h  | 11 +++
 include/linux/mtd/nand.h |  5 +
 5 files changed, 73 insertions(+)

-- 
2.7.4



[PATCH v3 1/5] mtd: introduce function max_bad_blocks

2016-10-28 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/mtdpart.c   | 13 +
 include/linux/mtd/mtd.h | 11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..2106bd5 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -481,6 +491,9 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
+
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..c02d3c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
@@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int 
wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
  const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+loff_t ofs, size_t len)
+{
+   if (mtd->_max_bad_blocks)
+   return mtd->_max_bad_blocks(mtd, ofs, len);
+
+   return -ENOTSUPP;
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  void **virt, resource_size_t *phys);
-- 
2.7.4



[PATCH v3 3/5] mtd: nand: Add bb_per_lun and blocks_per_lun fields to nand_chip

2016-10-28 Thread Zach Brown
The fields bb_per_lun and blocks_per_lun are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a fuill-id entry in the nand_ids
table.

Signed-off-by: Zach Brown 
---
 include/linux/mtd/nand.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index c5d3d502..efbe439 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  * supported, 0 otherwise.
  * @jedec_params:  [INTERN] holds the JEDEC parameter page when JEDEC is
  * supported, 0 otherwise.
+ * @bb_per_lun:[INTERN] the max number of bad blocks each LUN of a
+ * this nand device will encounter their life times.
+ * @blocks_per_lun:[INTERN] The number of PEBs in a LUN
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
struct nand_onfi_params onfi_params;
struct nand_jedec_params jedec_params;
};
+   __le16 bb_per_lun;
+   __le32 blocks_per_lun;
 
struct nand_data_interface *data_interface;
 
-- 
2.7.4



[PATCH 0/2] mmc: sdhci: Fix sdhci caps register bits with corrections provided by dt

2016-10-28 Thread Zach Brown
For various reasons the sdhci caps register can be incorrect. This patch set
introduces a general way to correct the bits when they are read to accurately
reflect the capabilties of the controller/board combo.

The first patch creates sdhci-caps and sdhci-caps-mask dt properties that
combined represent the correction to the sdhci caps register.

The second patch uses the new dt properties to correct the caps from the
register as they read during __sdhci_read_caps.

Changes from RFC:
 * /s/registers/register
 * Moved sdhci dt properties into new documentation file sdhci.txt

Zach Brown (2):
  mmc: sdhci: dt: Add device tree properties sdhci-caps and
sdhci-caps-mask
  mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read
during __sdhci_read_caps

 Documentation/devicetree/bindings/mmc/sdhci.txt | 14 ++
 drivers/mmc/host/sdhci.c| 24 ++--
 2 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci.txt

-- 
2.7.4



[PATCH 2/2] mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read during __sdhci_read_caps

2016-10-28 Thread Zach Brown
The sdhci capabilities register can be incorrect. The sdhci-caps-mask
and sdhci-caps dt properties specify which bits of the register are
incorrect and what their values should be. This patch makes the sdhci
driver use those properties to correct the caps during
__sdhci_read_caps.

During __sdhci_read_caps
Use the sdhci-caps-mask property to turn off the incorrect bits of the
sdhci register after reading them.
Use the sdhci-caps to turn on bits after using sdhci-caps-mask to turn
off the incorrect ones.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01..d5feae4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -2991,6 +2992,8 @@ static int sdhci_set_dma_mask(struct sdhci_host *host)
 void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 
*caps1)
 {
u16 v;
+   u64 dt_caps_mask = 0;
+   u64 dt_caps = 0;
 
if (host->read_caps)
return;
@@ -3005,18 +3008,35 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
*ver, u32 *caps, u32 *caps1)
 
sdhci_do_reset(host, SDHCI_RESET_ALL);
 
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps-mask", &dt_caps_mask);
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps", &dt_caps);
+
v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
 
if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
return;
 
-   host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
+   if (caps)
+   host->caps = *caps;
+   else {
+   host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+   host->caps &= ~lower_32_bits(dt_caps_mask);
+   host->caps |= lower_32_bits(dt_caps);
+   }
 
if (host->version < SDHCI_SPEC_300)
return;
 
-   host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   if (caps1)
+   host->caps1 = *caps1;
+   else {
+   host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   host->caps1 &= ~upper_32_bits(dt_caps_mask);
+   host->caps1 |= upper_32_bits(dt_caps);
+   }
 }
 EXPORT_SYMBOL_GPL(__sdhci_read_caps);
 
-- 
2.7.4



[PATCH 1/2] mmc: sdhci: dt: Add device tree properties sdhci-caps and sdhci-caps-mask

2016-10-28 Thread Zach Brown
On some systems the sdhci capabilty register is incorrect for one
reason or another.

The sdhci-caps-mask property specifies which bits in the register
are incorrect and should be turned off before using sdhci-caps to turn
on bits.

The sdhci-caps property specifies which bits should be turned on.

Signed-off-by: Zach Brown 
---
 Documentation/devicetree/bindings/mmc/sdhci.txt | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci.txt 
b/Documentation/devicetree/bindings/mmc/sdhci.txt
new file mode 100644
index 000..0f4f1bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci.txt
@@ -0,0 +1,14 @@
+The properties specific for SD host controllers. For properties shared by MMC
+host controllers refer to the mmc[1] bindings.
+
+  [1] Documentation/devicetree/bindings/mmc/mmc.txt
+
+Optional properties:
+- sdhci-caps-mask: The sdhci capabilities register is incorrect. This 64bit
+  property corresponds to the bits in the sdhci capabilty register. If the bit
+  is on in the mask then the bit is incorrect in the register and should be
+  turned off, before applying sdhci-caps.
+- sdhci-caps: The sdhci capabilities register is incorrect. This 64bit
+  property corresponds to the bits in the sdhci capability register. If the
+  bit is on in the property then the bit should be turned on.
+
-- 
2.7.4



[RESEND PATCH v2 2/3] mtd: nand: implement 'max_bad_blocks' mtd function

2016-10-27 Thread Zach Brown
From: Jeff Westfahl 

Implement the new mtd function 'max_bad_blocks'. Use the ONFI parameter
page to find the maximum bad blocks to reserve for an MTD, taking into
account how many LUNs the MTD spans.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e5718e5..ac08224 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3226,6 +3226,39 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* ONFI is used to determine the maximum bad block count. */
+   if (!chip->onfi_version)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->onfi_params.blocks_per_lun;
+   part_end_lun = part_end_block / chip->onfi_params.blocks_per_lun;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->onfi_params.bb_per_lun *
+   (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4743,6 +4776,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[RESEND PATCH v2 1/3] mtd: introduce function max_bad_blocks

2016-10-27 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/mtdpart.c   | 12 
 include/linux/mtd/mtd.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..565f0dd 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -481,6 +491,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..bd277eb 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
-- 
2.7.4



[RESEND PATCH v2 0/3] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-10-27 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 3
would need to be applied for this to work as intended.

v1:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (3):
  mtd: introduce function max_bad_blocks
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

 drivers/mtd/mtdpart.c| 12 
 drivers/mtd/nand/nand_base.c | 34 ++
 drivers/mtd/ubi/build.c  |  9 +
 include/linux/mtd/mtd.h  |  1 +
 4 files changed, 56 insertions(+)

-- 
2.7.4



[RESEND PATCH v2 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-10-27 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/ubi/build.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..0648863 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,15 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   /* If the MTD provides a max_bad_blocks function, use that value. Fall
+* back to max_beb_per1024 if that function returns an error.
+*/
+   if (ubi->mtd->_max_bad_blocks) {
+   limit = ubi->mtd->_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+   }
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



Re: Pure polling mode for netdevices

2016-10-27 Thread Zach Brown
On Fri, Oct 21, 2016 at 11:41:46AM -0700, Eric Dumazet wrote:
> On Fri, 2016-10-21 at 13:03 -0500, Zach Brown wrote:
> > Is there a way to get NAPI to poll all the time?
> > Or just any way to get netdevices to use only polling and no interrupts?
> > 
> > We have some rt targets where the jitter can be improved by disabling
> > interrupts and using just polling. In these cases we're okay with the
> > performance downsides that come with polling.
> > 
> > In particular we already have an implementation for the cadence macb driver
> > that does only polling mode and have verified that it improves the
> > jitter.
> > 
> > We're hoping for a more general existing solution or at the very least a
> > solution that would be accepted upstream. Any thoughts?
> 
> This is not yet done, although you could use busy poll infrastructure to
> get this without a kernel change.
> 
> Open as many TCP flows are necessary to traverse all the queues you care
> about, then loop on recvmsg() to trigger NAPI polling.
> 
> 

I looked into the busy poll infrastructure and I don't think it meets our
needs. We're not interested in minimizing the latency of the ethernet device,
but rather diminishing if not eliminating the system jitter cause by ethernet
interrupts. Not to mention that some interfaces like macb don't provide a lot
of the config options to make busy polling really work well. For example,
interrupt coalescing configuration. 

I was thinking more along the lines of an extenstion to the NAPI interface that
drivers can opt into that allows them to enter NAPI polling mode and never
leave when configured to do so.  



Re: [RFC v2 2/2] mmc: sdhci: Ignore capability register when it comes to speeds and use DT binding instead when sdhci-cap-speed-modes-broken is set.

2016-10-26 Thread Zach Brown
On Tue, Oct 25, 2016 at 02:30:25PM +0300, Adrian Hunter wrote:
> On 24/10/16 18:48, Zach Brown wrote:
> > On Mon, Oct 24, 2016 at 10:34:46AM +0300, Adrian Hunter wrote:
> >> On 22/10/16 00:35, Zach Brown wrote:
> >>> When the sdhci-cap-speed-modes-broken DT property is set, the driver
> >>> will ignore the bits of the capability registers that correspond to
> >>> speed modes.
> >>>
> >>> Signed-off-by: Zach Brown 
> >>> ---
> >>>  drivers/mmc/host/sdhci.c | 10 ++
> >>>  1 file changed, 10 insertions(+)
> >>>
> >>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> >>> index 1e25b01..59c62d3 100644
> >>> --- a/drivers/mmc/host/sdhci.c
> >>> +++ b/drivers/mmc/host/sdhci.c
> >>> @@ -22,6 +22,7 @@
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>> +#include 
> >>>
> >>>  #include 
> >>>
> >>> @@ -3013,10 +3014,19 @@ void __sdhci_read_caps(struct sdhci_host *host, 
> >>> u16 *ver, u32 *caps, u32 *caps1)
> >>>
> >>>   host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
> >>>
> >>> + if (of_property_read_bool(mmc_dev(host->mmc)->of_node,
> >>> +   "sdhci-cap-speed-modes-broken"))
> >>
> >> It rather begs the question: if you are going to do something sdhci
> >> specific, why not just read the whole of the caps register from DT?
> >>
> > 
> > Throwing out the whole of the caps register seems like overkill. Also
> 
> What about 2 values: one for the 64-bit caps register and one for a 64-bit
> mask of bits to override.  That way you can select which bits to override
> and what to override them to.
> 

I like this idea. I sent a RFC of it. 

> > there are some things set by the caps that are not available in the DT.
> > For example, SDHCI_CAN_64BIT is set by the cap register and is used in
> > sdhci_setup_host to set host->flags SDHCI_USE_64_BIT_DMA.
> 
> Not sure what you mean.
> 

Your suggestion addresses my concern. So it's not an issue. 


[RFC 2/2] mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read during __sdhci_read_caps

2016-10-25 Thread Zach Brown
The sdhci capabilities registers can be incorrect. The sdhci-caps-mask
and sdhci-caps dt properties specify which bits of the registers are
incorrect and what their values should be. This patch makes the sdhci
driver use those properties to correct the caps during
__sdhci_read_caps.

During __sdhci_read_caps
Use the sdhci-caps-mask property to turn off the incorrect bits of the
sdhci registers after reading them.
Use the sdhci-caps to turn on bits after using sdhci-caps-mask to turn
off the incorrect ones.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01..d5feae4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -2991,6 +2992,8 @@ static int sdhci_set_dma_mask(struct sdhci_host *host)
 void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 
*caps1)
 {
u16 v;
+   u64 dt_caps_mask = 0;
+   u64 dt_caps = 0;
 
if (host->read_caps)
return;
@@ -3005,18 +3008,35 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
*ver, u32 *caps, u32 *caps1)
 
sdhci_do_reset(host, SDHCI_RESET_ALL);
 
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps-mask", &dt_caps_mask);
+   of_property_read_u64(mmc_dev(host->mmc)->of_node,
+"sdhci-caps", &dt_caps);
+
v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
 
if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
return;
 
-   host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
+   if (caps)
+   host->caps = *caps;
+   else {
+   host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+   host->caps &= ~lower_32_bits(dt_caps_mask);
+   host->caps |= lower_32_bits(dt_caps);
+   }
 
if (host->version < SDHCI_SPEC_300)
return;
 
-   host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   if (caps1)
+   host->caps1 = *caps1;
+   else {
+   host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   host->caps1 &= ~upper_32_bits(dt_caps_mask);
+   host->caps1 |= upper_32_bits(dt_caps);
+   }
 }
 EXPORT_SYMBOL_GPL(__sdhci_read_caps);
 
-- 
2.7.4



[RFC 0/2] mmc: sdhci: Fix sdhci caps register bits with corrections provided by dt

2016-10-25 Thread Zach Brown
For various reasons the sdhci caps register can be incorrect. This patch set
introduces a general way to correct the bits when they are read to accurately
reflect the capabilties of the controller/board combo.

The first patch creates sdhci-caps and sdhci-caps-mask dt properties that
combined represent the correction to the sdhci caps register.

The second patch uses the new dt properties to correct the caps from the
register as they read during __sdhci_read_caps.

Zach Brown (2):
  mmc: sdhci: dt: Add device tree properties sdhci-caps and sdhci-caps-mask
  mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read
during __sdhci_read_caps

 Documentation/devicetree/bindings/mmc/mmc.txt |  7 +++
 drivers/mmc/host/sdhci.c  | 24 ++--
 2 files changed, 29 insertions(+), 2 deletions(-)

--
2.7.4



[RFC 1/2] mmc: sdhci: dt: Add device tree properties sdhci-caps and sdhci-caps-mask

2016-10-25 Thread Zach Brown
On some systems the sdhci capabilty registers are incorrect for one
reason or another.

The sdhci-caps-mask property specifies which bits in the registers
are incorrect and should be turned off before using sdhci-caps to turn
on bits.

The sdhci-caps property specifies which bits should be turned on.

Signed-off-by: Zach Brown 
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt 
b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8a37782..1415aa0 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -52,6 +52,13 @@ Optional properties:
 - no-sdio: controller is limited to send sdio cmd during initialization
 - no-sd: controller is limited to send sd cmd during initialization
 - no-mmc: controller is limited to send mmc cmd during initialization
+- sdhci-caps-mask: The sdhci capabilities registers are incorrect. This 64bit
+  property corresponds to the bits in the sdhci capabilty registers. If the bit
+  is on in the mask then the bit is incorrect in the registers and should be
+  turned off.
+- sdhci-caps: The sdhci capabilities registers are incorrect. This 64bit
+  property corresponds to the bits in the sdhci capability registers. If the
+  bit is on in the property then the bit should be on in the reigsters.
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers 
line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
-- 
2.7.4



[RFC v3 1/2] mmc: sdhci: Add device tree property sdhci-cap-speed-modes-broken

2016-10-24 Thread Zach Brown
On some systems the sdhci capabilty registers are incorrect for one
reason or another.

The sdhci-cap-speed-modes-broken property will let the driver know that
the sdhci capability registers should not be relied on for speed modes.
Instead the driver should check the mmc generic DT bindings.

Signed-off-by: Zach Brown 
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt 
b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8a37782..671d6c0 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -52,6 +52,9 @@ Optional properties:
 - no-sdio: controller is limited to send sdio cmd during initialization
 - no-sd: controller is limited to send sd cmd during initialization
 - no-mmc: controller is limited to send mmc cmd during initialization
+- sdhci-cap-speed-modes-broken: One or more of the bits in the sdhci
+  capabilities registers representing speed modes are incorrect. All the bits
+  representing speed modes should be ignored.
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers 
line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
-- 
2.7.4



[RFC v3 2/2] mmc: sdhci: Ignore capability register when it comes to speeds and use DT binding instead when sdhci-cap-speed-modes-broken is set.

2016-10-24 Thread Zach Brown
When the sdhci-cap-speed-modes-broken DT property is set, the driver
will ignore the bits of the capability registers that correspond to
speed modes.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci.c | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01..a17c47e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -2991,6 +2992,7 @@ static int sdhci_set_dma_mask(struct sdhci_host *host)
 void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 
*caps1)
 {
u16 v;
+   unsigned int speed_cap_broken = false;
 
if (host->read_caps)
return;
@@ -3005,18 +3007,37 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
*ver, u32 *caps, u32 *caps1)
 
sdhci_do_reset(host, SDHCI_RESET_ALL);
 
+   if (of_property_read_bool(mmc_dev(host->mmc)->of_node,
+ "sdhci-cap-speed-modes-broken"))
+   speed_cap_broken = true;
+
v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
 
if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
return;
 
-   host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
+   if (caps)
+   host->caps = *caps;
+   else {
+   host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+   if (speed_cap_broken)
+   host->caps &= ~SDHCI_CAN_DO_HISPD;
+   }
 
if (host->version < SDHCI_SPEC_300)
return;
 
-   host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   if (caps1)
+   host->caps1 = *caps1;
+   else {
+   host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+   if (speed_cap_broken)
+   host->caps1 &= ~(SDHCI_SUPPORT_SDR50 |
+SDHCI_SUPPORT_SDR104 |
+SDHCI_SUPPORT_DDR50 |
+SDHCI_SUPPORT_HS400);
+   }
 }
 EXPORT_SYMBOL_GPL(__sdhci_read_caps);
 
-- 
2.7.4



[RFC v3 0/2] mmc: sdhci: Ignore capability register when it comes to speeds and use DT binding instead when sdhci-cap-speed-modes-broken is set.

2016-10-24 Thread Zach Brown
The first patch add documentation about a new devicetree property
sdhci-cap-speed-modes-broken.

The second patch makes the sdhci use the DT binding instead of the caps
register for determining which speed modes are supported by the controller.

This RFC is an alternative to another patch[1] set I sent up.

[1]
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1251944.html

v2:
 * Removed separate OF parsing function, relying on mmc_of_parse to be called
   before read_caps
 * Moved check of sdhci-cap-speed-modes-broken into sdhci_read_caps.
 * Added SDHCI_SUPPORT_HS400 to list of bits to clear in sdhci cap1, not
   sure that's all of the them now, but I think so.
v3:
 * Read "sdhci-cap-speed-modes-broken" only once.
 * If caps are provided to sdhci_read_caps the speed bits are not overwritten.


Zach Brown (2):
  mmc: sdhci: Add device tree property sdhci-cap-speed-modes-broken
  mmc: sdhci: Ignore capability register when it comes to speeds and use
DT binding instead when sdhci-cap-speed-modes-broken is set.

 Documentation/devicetree/bindings/mmc/mmc.txt |  3 +++
 drivers/mmc/host/sdhci.c  | 25 +++--
 2 files changed, 26 insertions(+), 2 deletions(-)

-- 
2.7.4



Re: [RFC v2 2/2] mmc: sdhci: Ignore capability register when it comes to speeds and use DT binding instead when sdhci-cap-speed-modes-broken is set.

2016-10-24 Thread Zach Brown
On Mon, Oct 24, 2016 at 10:34:46AM +0300, Adrian Hunter wrote:
> On 22/10/16 00:35, Zach Brown wrote:
> > When the sdhci-cap-speed-modes-broken DT property is set, the driver
> > will ignore the bits of the capability registers that correspond to
> > speed modes.
> >
> > Signed-off-by: Zach Brown 
> > ---
> >  drivers/mmc/host/sdhci.c | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> > index 1e25b01..59c62d3 100644
> > --- a/drivers/mmc/host/sdhci.c
> > +++ b/drivers/mmc/host/sdhci.c
> > @@ -22,6 +22,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include 
> >
> > @@ -3013,10 +3014,19 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
> > *ver, u32 *caps, u32 *caps1)
> >
> > host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
> >
> > +   if (of_property_read_bool(mmc_dev(host->mmc)->of_node,
> > + "sdhci-cap-speed-modes-broken"))
>
> It rather begs the question: if you are going to do something sdhci
> specific, why not just read the whole of the caps register from DT?
>

Throwing out the whole of the caps register seems like overkill. Also
there are some things set by the caps that are not available in the DT.
For example, SDHCI_CAN_64BIT is set by the cap register and is used in
sdhci_setup_host to set host->flags SDHCI_USE_64_BIT_DMA.


[RFC v2 0/2] Ignore capability registers when it comes to speeds and use DT binding instead.

2016-10-21 Thread Zach Brown
The first patch add documentation about a new devicetree property
sdhci-cap-speed-modes-broken.

The second patch makes the sdhci use the DT binding instead of the caps
register for determining which speed modes are supported by the controller.

This RFC is an alternative to another patch[1] set I sent up.

[1]
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1251944.html

v2:
 * Removed separate OF parsing function, relying on mmc_of_parse to be called
   before read_caps
 * Moved check of sdhci-cap-speed-modes-broken into sdhci_read_caps.
 * Added SDHCI_SUPPORT_HS400 to list of bits to clear in sdhci cap1, not sure
   that's all of the them now, but I think so.

Zach Brown (2):
  mmc: sdhci: Add device tree property sdhci-cap-speed-modes-broken
  mmc: sdhci: Ignore capability register when it comes to speeds and use
DT binding instead when sdhci-cap-speed-modes-broken is set.

 Documentation/devicetree/bindings/mmc/mmc.txt |  3 +++
 drivers/mmc/host/sdhci.c  | 10 ++
 2 files changed, 13 insertions(+)

--
2.7.4



[RFC v2 2/2] mmc: sdhci: Ignore capability register when it comes to speeds and use DT binding instead when sdhci-cap-speed-modes-broken is set.

2016-10-21 Thread Zach Brown
When the sdhci-cap-speed-modes-broken DT property is set, the driver
will ignore the bits of the capability registers that correspond to
speed modes.

Signed-off-by: Zach Brown 
---
 drivers/mmc/host/sdhci.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01..59c62d3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -3013,10 +3014,19 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 
*ver, u32 *caps, u32 *caps1)
 
host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
 
+   if (of_property_read_bool(mmc_dev(host->mmc)->of_node,
+ "sdhci-cap-speed-modes-broken"))
+   host->caps &= ~SDHCI_CAN_DO_HISPD;
+
if (host->version < SDHCI_SPEC_300)
return;
 
host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
+
+   if (of_property_read_bool(mmc_dev(host->mmc)->of_node,
+ "sdhci-cap-speed-modes-broken"))
+   host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
+SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_HS400);
 }
 EXPORT_SYMBOL_GPL(__sdhci_read_caps);
 
-- 
2.7.4



[RFC v2 1/2] mmc: sdhci: Add device tree property sdhci-cap-speed-modes-broken

2016-10-21 Thread Zach Brown
On some systems the sdhci capabilty registers are incorrect for one
reason or another.

The sdhci-cap-speed-modes-broken property will let the driver know that
the sdhci capability registers should not be relied on for speed modes.
Instead the driver should check the mmc generic DT bindings.

Signed-off-by: Zach Brown 
---
 Documentation/devicetree/bindings/mmc/mmc.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt 
b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8a37782..671d6c0 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -52,6 +52,9 @@ Optional properties:
 - no-sdio: controller is limited to send sdio cmd during initialization
 - no-sd: controller is limited to send sd cmd during initialization
 - no-mmc: controller is limited to send mmc cmd during initialization
+- sdhci-cap-speed-modes-broken: One or more of the bits in the sdhci
+  capabilities registers representing speed modes are incorrect. All the bits
+  representing speed modes should be ignored.
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers 
line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
-- 
2.7.4



Pure polling mode for netdevices

2016-10-21 Thread Zach Brown
Is there a way to get NAPI to poll all the time?
Or just any way to get netdevices to use only polling and no interrupts?

We have some rt targets where the jitter can be improved by disabling
interrupts and using just polling. In these cases we're okay with the
performance downsides that come with polling.

In particular we already have an implementation for the cadence macb driver
that does only polling mode and have verified that it improves the
jitter.

We're hoping for a more general existing solution or at the very least a
solution that would be accepted upstream. Any thoughts?


[PATCH v2 2/3] mtd: nand: implement 'max_bad_blocks' mtd function

2016-10-20 Thread Zach Brown
From: Jeff Westfahl 

Implement the new mtd function 'max_bad_blocks'. Use the ONFI parameter
page to find the maximum bad blocks to reserve for an MTD, taking into
account how many LUNs the MTD spans.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/nand/nand_base.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e5718e5..ac08224 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3226,6 +3226,39 @@ static int nand_block_markbad(struct mtd_info *mtd, 
loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct nand_chip *chip = mtd_to_nand(mtd);
+   uint32_t part_start_block;
+   uint32_t part_end_block;
+   uint32_t part_start_lun;
+   uint32_t part_end_lun;
+
+   /* ONFI is used to determine the maximum bad block count. */
+   if (!chip->onfi_version)
+   return -ENOTSUPP;
+
+   /* Get the start and end of the partition in erase blocks. */
+   part_start_block = mtd_div_by_eb(ofs, mtd);
+   part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+   /* Get the start and end LUNs of the partition. */
+   part_start_lun = part_start_block / chip->onfi_params.blocks_per_lun;
+   part_end_lun = part_end_block / chip->onfi_params.blocks_per_lun;
+
+   /* Look up the bad blocks per unit and multiply by the number of units
+* that the partition spans.
+*/
+   return chip->onfi_params.bb_per_lun *
+   (part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4743,6 +4776,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
+   mtd->_max_bad_blocks = nand_max_bad_blocks;
mtd->writebufsize = mtd->writesize;
 
/*
-- 
2.7.4



[PATCH v2 0/3] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

2016-10-20 Thread Zach Brown
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 3
would need to be applied for this to work as intended.

v1:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (3):
  mtd: introduce function max_bad_blocks
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

 drivers/mtd/mtdpart.c| 12 
 drivers/mtd/nand/nand_base.c | 34 ++
 drivers/mtd/ubi/build.c  |  9 +
 include/linux/mtd/mtd.h  |  1 +
 4 files changed, 56 insertions(+)

--
2.7.4



[PATCH v2 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

2016-10-20 Thread Zach Brown
From: Jeff Westfahl 

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/ubi/build.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 0680516..f713a30 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,15 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, 
int max_beb_per1024)
int limit, device_pebs;
uint64_t device_size;
 
+   /* If the MTD provides a max_bad_blocks function, use that value. Fall
+* back to max_beb_per1024 if that function returns an error.
+*/
+   if (ubi->mtd->_max_bad_blocks) {
+   limit = ubi->mtd->_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+   if (limit > 0)
+   return limit;
+   }
+
if (!max_beb_per1024)
return 0;
 
-- 
2.7.4



[PATCH v2 1/3] mtd: introduce function max_bad_blocks

2016-10-20 Thread Zach Brown
From: Jeff Westfahl 

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Zach Brown 
---
 drivers/mtd/mtdpart.c   | 12 
 include/linux/mtd/mtd.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index c1f34f0..65d3563 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -350,6 +350,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = 
{
.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+   struct mtd_part *part = mtd_to_part(mtd);
+
+   if ((len + ofs) > mtd->size)
+   return -EINVAL;
+   return part->master->_max_bad_blocks(part->master,
+ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
kfree(p->mtd.name);
@@ -482,6 +492,8 @@ static struct mtd_part *allocate_partition(struct mtd_info 
*master,
if (master->_put_device)
slave->mtd._put_device = part_put_device;
 
+   if (master->_max_bad_blocks)
+   slave->mtd._max_bad_blocks = part_max_bad_blocks;
slave->mtd._erase = part_erase;
slave->master = master;
slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..bd277eb 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+   int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
void (*_reboot) (struct mtd_info *mtd);
-- 
2.7.4



[PATCH 0/2] Add ethtool get_ringparam and set_ringparam to cadence

2016-10-19 Thread Zach Brown
There are use cases like RT that would benefit from being able to tune the
macb rx/tx ring sizes. The ethtool set_ringparam function is the standard way
of doing so.

The first patch changes the hardcoded tx/rx ring sizes to variables that are
set to a hardcoded default.

The second patch implements the get_ringparam and set_ringparam fucntions.

Zach Brown (2):
  net: macb: Use variables with defaults for tx/rx ring sizes instead of
hardcoded values
  net: macb: Add ethtool get_ringparam and set_ringparam functionality

 drivers/net/ethernet/cadence/macb.c | 173 +---
 drivers/net/ethernet/cadence/macb.h |   3 +
 2 files changed, 124 insertions(+), 52 deletions(-)

--
2.7.4



[PATCH 2/2] net: macb: Add ethtool get_ringparam and set_ringparam functionality

2016-10-19 Thread Zach Brown
Some applications want to tune the size of the macb rx/tx ring buffers.
The ethtool set_ringparam function is the standard way of doing it.

Signed-off-by: Zach Brown 
---
 drivers/net/ethernet/cadence/macb.c | 59 +
 1 file changed, 59 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 644975d..e1847ce 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -37,11 +37,16 @@

 #define MACB_RX_BUFFER_SIZE128
 #define RX_BUFFER_MULTIPLE 64  /* bytes */
+
 #define DEFAULT_RX_RING_SIZE   512 /* must be power of 2 */
+#define MIN_RX_RING_SIZE   64
+#define MAX_RX_RING_SIZE   8192
 #define RX_RING_BYTES(bp)  (sizeof(struct macb_dma_desc)   \
 * (bp)->rx_ring_size)

 #define DEFAULT_TX_RING_SIZE   512 /* must be power of 2 */
+#define MIN_TX_RING_SIZE   64
+#define MAX_TX_RING_SIZE   4096
 #define TX_RING_BYTES(bp)  (sizeof(struct macb_dma_desc)   \
 * (bp)->tx_ring_size)

@@ -2211,6 +2216,56 @@ static int macb_set_wol(struct net_device *netdev, 
struct ethtool_wolinfo *wol)
return 0;
 }

+static void macb_get_ringparam(struct net_device *netdev,
+  struct ethtool_ringparam *ring)
+{
+   struct macb *bp = netdev_priv(netdev);
+
+   ring->rx_max_pending = MAX_RX_RING_SIZE;
+   ring->tx_max_pending = MAX_TX_RING_SIZE;
+
+   ring->rx_pending = bp->rx_ring_size;
+   ring->tx_pending = bp->tx_ring_size;
+}
+
+static int macb_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+   struct macb *bp = netdev_priv(netdev);
+   u32 new_rx_size, new_tx_size;
+   unsigned int reset = 0;
+
+   if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+   return -EINVAL;
+
+   new_rx_size = clamp_t(u32, ring->rx_pending,
+ MIN_RX_RING_SIZE, MAX_RX_RING_SIZE);
+   new_rx_size = roundup_pow_of_two(new_rx_size);
+
+   new_tx_size = clamp_t(u32, ring->tx_pending,
+ MIN_TX_RING_SIZE, MAX_TX_RING_SIZE);
+   new_tx_size = roundup_pow_of_two(new_tx_size);
+
+   if ((new_tx_size == bp->tx_ring_size) &&
+   (new_rx_size == bp->rx_ring_size)) {
+   /* nothing to do */
+   return 0;
+   }
+
+   if (netif_running(bp->dev)) {
+   reset = 1;
+   macb_close(bp->dev);
+   }
+
+   bp->rx_ring_size = new_rx_size;
+   bp->tx_ring_size = new_tx_size;
+
+   if (reset)
+   macb_open(bp->dev);
+
+   return 0;
+}
+
 static const struct ethtool_ops macb_ethtool_ops = {
.get_regs_len   = macb_get_regs_len,
.get_regs   = macb_get_regs,
@@ -2220,6 +2275,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
.set_wol= macb_set_wol,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+   .get_ringparam  = macb_get_ringparam,
+   .set_ringparam  = macb_set_ringparam,
 };

 static const struct ethtool_ops gem_ethtool_ops = {
@@ -2232,6 +2289,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
.get_sset_count = gem_get_sset_count,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+   .get_ringparam  = macb_get_ringparam,
+   .set_ringparam  = macb_set_ringparam,
 };

 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
--
2.7.4



[PATCH 1/2] net: macb: Use variables with defaults for tx/rx ring sizes instead of hardcoded values

2016-10-19 Thread Zach Brown
The macb driver hardcoded the tx/rx ring sizes. This made it
impossible to change the sizes at run time.

Add tx_ring_size, and rx_ring_size variables to macb object, which
are initilized with default vales during macb_init. Change all
references to RX_RING_SIZE and TX_RING_SIZE to their respective
replacements.

Signed-off-by: Zach Brown 
---
 drivers/net/ethernet/cadence/macb.c | 114 
 drivers/net/ethernet/cadence/macb.h |   3 +
 2 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index e83781a..644975d 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -37,14 +37,16 @@
 
 #define MACB_RX_BUFFER_SIZE128
 #define RX_BUFFER_MULTIPLE 64  /* bytes */
-#define RX_RING_SIZE   512 /* must be power of 2 */
-#define RX_RING_BYTES  (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define DEFAULT_RX_RING_SIZE   512 /* must be power of 2 */
+#define RX_RING_BYTES(bp)  (sizeof(struct macb_dma_desc)   \
+* (bp)->rx_ring_size)
 
-#define TX_RING_SIZE   128 /* must be power of 2 */
-#define TX_RING_BYTES  (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
+#define DEFAULT_TX_RING_SIZE   512 /* must be power of 2 */
+#define TX_RING_BYTES(bp)  (sizeof(struct macb_dma_desc)   \
+* (bp)->tx_ring_size)
 
 /* level of occupied TX descriptors under which we wake up TX process */
-#define MACB_TX_WAKEUP_THRESH  (3 * TX_RING_SIZE / 4)
+#define MACB_TX_WAKEUP_THRESH(bp)  (3 * (bp)->tx_ring_size / 4)
 
 #define MACB_RX_INT_FLAGS  (MACB_BIT(RCOMP) | MACB_BIT(RXUBR)  \
 | MACB_BIT(ISR_ROVR))
@@ -67,45 +69,47 @@
 #define MACB_HALT_TIMEOUT  1230
 
 /* Ring buffer accessors */
-static unsigned int macb_tx_ring_wrap(unsigned int index)
+static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index)
 {
-   return index & (TX_RING_SIZE - 1);
+   return index & (bp->tx_ring_size - 1);
 }
 
 static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,
  unsigned int index)
 {
-   return &queue->tx_ring[macb_tx_ring_wrap(index)];
+   return &queue->tx_ring[macb_tx_ring_wrap(queue->bp, index)];
 }
 
 static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,
   unsigned int index)
 {
-   return &queue->tx_skb[macb_tx_ring_wrap(index)];
+   return &queue->tx_skb[macb_tx_ring_wrap(queue->bp, index)];
 }
 
 static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)
 {
dma_addr_t offset;
 
-   offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
+   offset = macb_tx_ring_wrap(queue->bp, index) *
+sizeof(struct macb_dma_desc);
 
return queue->tx_ring_dma + offset;
 }
 
-static unsigned int macb_rx_ring_wrap(unsigned int index)
+static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index)
 {
-   return index & (RX_RING_SIZE - 1);
+   return index & (bp->rx_ring_size - 1);
 }
 
 static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
 {
-   return &bp->rx_ring[macb_rx_ring_wrap(index)];
+   return &bp->rx_ring[macb_rx_ring_wrap(bp, index)];
 }
 
 static void *macb_rx_buffer(struct macb *bp, unsigned int index)
 {
-   return bp->rx_buffers + bp->rx_buffer_size * macb_rx_ring_wrap(index);
+   return bp->rx_buffers + bp->rx_buffer_size *
+  macb_rx_ring_wrap(bp, index);
 }
 
 /* I/O accessors */
@@ -608,7 +612,8 @@ static void macb_tx_error_task(struct work_struct *work)
 */
if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) {
netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX 
complete\n",
-   macb_tx_ring_wrap(tail), skb->data);
+   macb_tx_ring_wrap(bp, tail),
+   skb->data);
bp->stats.tx_packets++;
bp->stats.tx_bytes += skb->len;
}
@@ -700,7 +705,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
/* First, update TX stats if needed */
if (skb) {
netdev_vdbg(bp->dev, "skb %u (data %p) TX 
complete\n",
-   macb_tx_ring_wrap(tail), skb->data);
+   macb_tx_ring_wrap(bp, tail),
+   skb->data);
bp->stats.tx_packet

  1   2   3   4   5   6   >