Re: [PATCH 0/2] microcode: Do early microcode application during resume-from-RAM

2017-06-12 Thread Dominik Brodowski
Boris,

On Mon, Jun 12, 2017 at 07:58:52PM +0200, Borislav Petkov wrote:
> From: Borislav Petkov 
> 
> Ok,
> 
> I think I've dreamt of a simple solution to the early microcode
> application deal with suspend-to-RAM. The commit message of patch 2
> should explain it in more detail. Patch 1 is a fix for 32-bit when the
> ramdisk is being relocated.
> 
> I'm still testing but it seems to work.

Nice job; works fine here.

Best,
Dominik


Re: [PATCH 0/2] microcode: Do early microcode application during resume-from-RAM

2017-06-12 Thread Dominik Brodowski
Boris,

On Mon, Jun 12, 2017 at 07:58:52PM +0200, Borislav Petkov wrote:
> From: Borislav Petkov 
> 
> Ok,
> 
> I think I've dreamt of a simple solution to the early microcode
> application deal with suspend-to-RAM. The commit message of patch 2
> should explain it in more detail. Patch 1 is a fix for 32-bit when the
> ramdisk is being relocated.
> 
> I'm still testing but it seems to work.

Nice job; works fine here.

Best,
Dominik


Re: [PATCH v2 0/8] ACPI / PM: Suspend-to-idle rework to deal with spurious ACPI wakeups

2017-06-12 Thread Dominik Brodowski
Rafael,

On Mon, Jun 12, 2017 at 10:46:47PM +0200, Rafael J. Wysocki wrote:
> Hi All,
> 
> On Thursday, June 08, 2017 02:00:40 AM Rafael J. Wysocki wrote:
> > Hi All,
> > 
> > This series is a replacement for commit eed4d47efe95 (ACPI / sleep: Ignore
> > spurious SCI wakeups from suspend-to-idle) which is still there in 4.12-rc4 
> > but
> > will be reverted shortly, because it triggered issues on quite a few 
> > systems.
> > 
> > The last patch in the series is a counterpart of the above commit with a few
> > modifications, mostly to avoid affecting suspend-to-RAM and to reorder 
> > messages
> > printed to kernel logs to make them somewhat less confusing.
> 
> Here's a v2 which is very similar to the previous one, except for 3 things:
> - There are few build fixes in the last patch.
> - The patch from Hans mentioned previously is included now (as [7/8]).
> - There is an additional PCI change related to config space saving/restoring
>   and PME.
> 
> If anyone has any objections or concerns regarding this, please speak up now,
> as I'm going to put it into linux-next shortly to allow it to receive some 
> more
> testing than commit eed4d47efe95 had had before it went it.

suspend-to-mem works as expected, also with this v2 applied. Thanks!

Dominik


Re: [PATCH v2 0/8] ACPI / PM: Suspend-to-idle rework to deal with spurious ACPI wakeups

2017-06-12 Thread Dominik Brodowski
Rafael,

On Mon, Jun 12, 2017 at 10:46:47PM +0200, Rafael J. Wysocki wrote:
> Hi All,
> 
> On Thursday, June 08, 2017 02:00:40 AM Rafael J. Wysocki wrote:
> > Hi All,
> > 
> > This series is a replacement for commit eed4d47efe95 (ACPI / sleep: Ignore
> > spurious SCI wakeups from suspend-to-idle) which is still there in 4.12-rc4 
> > but
> > will be reverted shortly, because it triggered issues on quite a few 
> > systems.
> > 
> > The last patch in the series is a counterpart of the above commit with a few
> > modifications, mostly to avoid affecting suspend-to-RAM and to reorder 
> > messages
> > printed to kernel logs to make them somewhat less confusing.
> 
> Here's a v2 which is very similar to the previous one, except for 3 things:
> - There are few build fixes in the last patch.
> - The patch from Hans mentioned previously is included now (as [7/8]).
> - There is an additional PCI change related to config space saving/restoring
>   and PME.
> 
> If anyone has any objections or concerns regarding this, please speak up now,
> as I'm going to put it into linux-next shortly to allow it to receive some 
> more
> testing than commit eed4d47efe95 had had before it went it.

suspend-to-mem works as expected, also with this v2 applied. Thanks!

Dominik


Re: brcmfmac: Fix kernel oops on resume when request firmware fails.

2017-06-12 Thread Kalle Valo
Enric Balletbo i Serra  wrote:

> When request firmware fails, brcmf_ops_sdio_remove is being called and
> brcmf_bus freed. In such circumstancies if you do a suspend/resume cycle
> the kernel hangs on resume due a NULL pointer dereference in resume
> function.
> 
> Steps to reproduce the problem:
>  - modprobe brcmfmac without the firmware
>  brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac4354-sdio.bin
>  failed with error -2
>  - do a suspend/resume cycle (echo mem > /sys/power/state)
> 
> Protect against the NULL pointer derefence by checking if dev_get_drvdata
> returned a valid pointer.
> 
> Signed-off-by: Enric Balletbo i Serra 

My understanding is that there's a new version of this patch which fixes
the issue. If not, let me know.

Patch set to Superseded.

-- 
https://patchwork.kernel.org/patch/9743159/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches



Re: brcmfmac: Fix kernel oops on resume when request firmware fails.

2017-06-12 Thread Kalle Valo
Enric Balletbo i Serra  wrote:

> When request firmware fails, brcmf_ops_sdio_remove is being called and
> brcmf_bus freed. In such circumstancies if you do a suspend/resume cycle
> the kernel hangs on resume due a NULL pointer dereference in resume
> function.
> 
> Steps to reproduce the problem:
>  - modprobe brcmfmac without the firmware
>  brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac4354-sdio.bin
>  failed with error -2
>  - do a suspend/resume cycle (echo mem > /sys/power/state)
> 
> Protect against the NULL pointer derefence by checking if dev_get_drvdata
> returned a valid pointer.
> 
> Signed-off-by: Enric Balletbo i Serra 

My understanding is that there's a new version of this patch which fixes
the issue. If not, let me know.

Patch set to Superseded.

-- 
https://patchwork.kernel.org/patch/9743159/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches



Re: [PATCH 10/10] Staging: rtl8712: ieee80211: fixed coding style issue

2017-06-12 Thread Greg KH
On Tue, Jun 13, 2017 at 10:47:58AM +0530, R Jayadurga wrote:
> This e-mail is for the sole use of the intended recipient(s) and may
> contain confidential and privileged information. If you are not the
> intended recipient, please contact the sender by reply e-mail and destroy
> all copies and the original message. Any unauthorized review, use,
> disclosure, dissemination, forwarding, printing or copying of this email
> is strictly prohibited and appropriate legal action will be taken.
> ---

As per your footer, I am deleting your email.

Please note that I'm really not supposed to be responding to this at
all, as this type of text is not allowed at all on kernel development
mialing lists...


Re: [PATCH 10/10] Staging: rtl8712: ieee80211: fixed coding style issue

2017-06-12 Thread Greg KH
On Tue, Jun 13, 2017 at 10:47:58AM +0530, R Jayadurga wrote:
> This e-mail is for the sole use of the intended recipient(s) and may
> contain confidential and privileged information. If you are not the
> intended recipient, please contact the sender by reply e-mail and destroy
> all copies and the original message. Any unauthorized review, use,
> disclosure, dissemination, forwarding, printing or copying of this email
> is strictly prohibited and appropriate legal action will be taken.
> ---

As per your footer, I am deleting your email.

Please note that I'm really not supposed to be responding to this at
all, as this type of text is not allowed at all on kernel development
mialing lists...


Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option

2017-06-12 Thread Schöfegger Stefan
On Tuesday, June 13, 2017 2:00:16 AM CEST Richard Zhu wrote:
> > -Original Message-
> > From: Bjorn Helgaas [mailto:helg...@kernel.org]
> > Sent: Tuesday, June 13, 2017 7:49 AM
> > To: Stefan Schoefegger 
> > Cc: linux-...@vger.kernel.org; Richard Zhu ; Arnd
> > Bergmann ; open list ;
> > Kishon Vijay Abraham I ; Jingoo Han
> > ; Bjorn Helgaas ;
> > moderated list:PCI DRIVER FOR IMX6 ;
> > Lucas Stach 
> > Subject: Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option
> > 
> > On Wed, Jun 07, 2017 at 01:36:11PM +0200, Stefan Schoefegger wrote:
> > > Link speed must not be limited to gen1 during link test for compliance
> > > tests
> > > 
> > > Signed-off-by: Stefan Schoefegger 
> > > ---
> > > 
> > > Changes since v1:
> > >  - pci-imx6.c moved to dwc directory
> > >  
> > >  drivers/pci/dwc/Kconfig| 10 ++
> > >  drivers/pci/dwc/pci-imx6.c | 21 -
> > >  2 files changed, 22 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig index
> > > b7e15526d676..b6e9ced5a45d 100644
> > > --- a/drivers/pci/dwc/Kconfig
> > > +++ b/drivers/pci/dwc/Kconfig
> > > @@ -77,6 +77,16 @@ config PCI_IMX6
> > > 
> > >   select PCIEPORTBUS
> > >   select PCIE_DW_HOST
> > > 
> > > +config PCI_IMX6_COMPLIANCE_TEST
> > > + bool "Enable pcie compliance tests on imx6"
> > > + depends on PCI_IMX6
> > > + default n
> > > + help
> > > +   Enables support for pcie compliance test on FSL iMX SoCs.
> > > +   The link speed wouldn't be limited to gen1 when enabled.
> > > +   Enable only during compliance tests, otherwise
> > > +   link detection will fail on some peripherals.
> > 
> > I'm puzzled about why we would want to merge this patch.  It looks like
> > we're trying to game the system to make the device pass compliance testing
> > when it isn't really compliant.  Is this config option useful to users, or
> > is it only useful during internal development of iMX SoCs?
> 
> [Zhu hongxing] Agree with Bjorn. These modifications shouldn't be merged.
> They are used for the boards used to pass the PCIe RC certification, when
> one Standalone external OSC is used as PCIe reference clock source in the
> boards design.
Yes, passing gen2 compliance test is only possible with external clk. But this 
is a errata of imx6 pci phy of PCIe clk jitter. Why should we not be able to 
do gen2 tests? I think it is useful to do other gen2 tests (signal integrity) 
during board design.
> > >  config PCIE_SPEAR13XX
> > >  
> > >   bool "STMicroelectronics SPEAr PCIe controller"
> > >   depends on PCI
> > > 
> > > diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
> > > index 19a289b8cc94..b0fbe52e25b0 100644
> > > --- a/drivers/pci/dwc/pci-imx6.c
> > > +++ b/drivers/pci/dwc/pci-imx6.c
> > > @@ -533,15 +533,18 @@ static int imx6_pcie_establish_link(struct
> > 
> > imx6_pcie *imx6_pcie)
> > 
> > >   u32 tmp;
> > >   int ret;
> > > 
> > > - /*
> > > -  * Force Gen1 operation when starting the link.  In case the link is
> > > -  * started in Gen2 mode, there is a possibility the devices on the
> > > -  * bus will not be detected at all.  This happens with PCIe switches.
> > > -  */
> > > - tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > > - tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > > - tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > > - dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > > + if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
> > > + /*
> > > +  * Force Gen1 operation when starting the link.  In case the
> > > +  * link is started in Gen2 mode, there is a possibility the
> > > +  * devices on the bus will not be detected at all.  This
> > > +  * happens with PCIe switches.
> > > +  */
> > > + tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > > + tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > > + tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > > + dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > > + }
> > > 
> > >   /* Start LTSSM. */
> > >   if (imx6_pcie->variant == IMX7D)
> > > 
> > > --
> > > 2.11.0
> > > 
> > > 
> > > ___
> > > linux-arm-kernel mailing list
> > > linux-arm-ker...@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option

2017-06-12 Thread Schöfegger Stefan
On Tuesday, June 13, 2017 2:00:16 AM CEST Richard Zhu wrote:
> > -Original Message-
> > From: Bjorn Helgaas [mailto:helg...@kernel.org]
> > Sent: Tuesday, June 13, 2017 7:49 AM
> > To: Stefan Schoefegger 
> > Cc: linux-...@vger.kernel.org; Richard Zhu ; Arnd
> > Bergmann ; open list ;
> > Kishon Vijay Abraham I ; Jingoo Han
> > ; Bjorn Helgaas ;
> > moderated list:PCI DRIVER FOR IMX6 ;
> > Lucas Stach 
> > Subject: Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option
> > 
> > On Wed, Jun 07, 2017 at 01:36:11PM +0200, Stefan Schoefegger wrote:
> > > Link speed must not be limited to gen1 during link test for compliance
> > > tests
> > > 
> > > Signed-off-by: Stefan Schoefegger 
> > > ---
> > > 
> > > Changes since v1:
> > >  - pci-imx6.c moved to dwc directory
> > >  
> > >  drivers/pci/dwc/Kconfig| 10 ++
> > >  drivers/pci/dwc/pci-imx6.c | 21 -
> > >  2 files changed, 22 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig index
> > > b7e15526d676..b6e9ced5a45d 100644
> > > --- a/drivers/pci/dwc/Kconfig
> > > +++ b/drivers/pci/dwc/Kconfig
> > > @@ -77,6 +77,16 @@ config PCI_IMX6
> > > 
> > >   select PCIEPORTBUS
> > >   select PCIE_DW_HOST
> > > 
> > > +config PCI_IMX6_COMPLIANCE_TEST
> > > + bool "Enable pcie compliance tests on imx6"
> > > + depends on PCI_IMX6
> > > + default n
> > > + help
> > > +   Enables support for pcie compliance test on FSL iMX SoCs.
> > > +   The link speed wouldn't be limited to gen1 when enabled.
> > > +   Enable only during compliance tests, otherwise
> > > +   link detection will fail on some peripherals.
> > 
> > I'm puzzled about why we would want to merge this patch.  It looks like
> > we're trying to game the system to make the device pass compliance testing
> > when it isn't really compliant.  Is this config option useful to users, or
> > is it only useful during internal development of iMX SoCs?
> 
> [Zhu hongxing] Agree with Bjorn. These modifications shouldn't be merged.
> They are used for the boards used to pass the PCIe RC certification, when
> one Standalone external OSC is used as PCIe reference clock source in the
> boards design.
Yes, passing gen2 compliance test is only possible with external clk. But this 
is a errata of imx6 pci phy of PCIe clk jitter. Why should we not be able to 
do gen2 tests? I think it is useful to do other gen2 tests (signal integrity) 
during board design.
> > >  config PCIE_SPEAR13XX
> > >  
> > >   bool "STMicroelectronics SPEAr PCIe controller"
> > >   depends on PCI
> > > 
> > > diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
> > > index 19a289b8cc94..b0fbe52e25b0 100644
> > > --- a/drivers/pci/dwc/pci-imx6.c
> > > +++ b/drivers/pci/dwc/pci-imx6.c
> > > @@ -533,15 +533,18 @@ static int imx6_pcie_establish_link(struct
> > 
> > imx6_pcie *imx6_pcie)
> > 
> > >   u32 tmp;
> > >   int ret;
> > > 
> > > - /*
> > > -  * Force Gen1 operation when starting the link.  In case the link is
> > > -  * started in Gen2 mode, there is a possibility the devices on the
> > > -  * bus will not be detected at all.  This happens with PCIe switches.
> > > -  */
> > > - tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > > - tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > > - tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > > - dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > > + if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
> > > + /*
> > > +  * Force Gen1 operation when starting the link.  In case the
> > > +  * link is started in Gen2 mode, there is a possibility the
> > > +  * devices on the bus will not be detected at all.  This
> > > +  * happens with PCIe switches.
> > > +  */
> > > + tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > > + tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > > + tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > > + dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > > + }
> > > 
> > >   /* Start LTSSM. */
> > >   if (imx6_pcie->variant == IMX7D)
> > > 
> > > --
> > > 2.11.0
> > > 
> > > 
> > > ___
> > > linux-arm-kernel mailing list
> > > linux-arm-ker...@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



[PATCH v2 3/3] staging: rtl8188eu: Shorten lines over 80 chars

2017-06-12 Thread Aviya Erenfeld
Shorten lines over 80 chars

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 58 +++-
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index cd348ca..c924c9e 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -68,7 +68,8 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
struct sta_info *psta;
s32 i;
 
-   pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * 
NUM_STA + 4);
+   pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) *
+  NUM_STA + 4);
 
if (!pstapriv->pallocated_stainfo_buf)
return _FAIL;
@@ -91,7 +92,8 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
 
INIT_LIST_HEAD(>sta_hash[i]);
 
-   list_add_tail(>list, 
get_list_head(>free_sta_queue));
+   list_add_tail(>list,
+ get_list_head(>free_sta_queue));
 
psta++;
}
@@ -119,20 +121,25 @@ u32   _rtw_init_sta_priv(struct   sta_priv 
*pstapriv)
 
 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
 {
-   int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct 
sta_info);
+   int offset = (((u8 *)sta) - stapriv->pstainfo_buf) /
+ sizeof(struct sta_info);
 
if (!stainfo_offset_valid(offset))
-   DBG_88E("%s invalid offset(%d), out of range!!!", __func__, 
offset);
+   DBG_88E("%s invalid offset(%d), out of range!!!",
+   __func__, offset);
 
return offset;
 }
 
-inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, 
int offset)
+inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv,
+ int offset)
 {
if (!stainfo_offset_valid(offset))
-   DBG_88E("%s invalid offset(%d), out of range!!!", __func__, 
offset);
+   DBG_88E("%s invalid offset(%d), out of range!!!",
+   __func__, offset);
 
-   return (struct sta_info *)(stapriv->pstainfo_buf + offset * 
sizeof(struct sta_info));
+   return (struct sta_info *)(stapriv->pstainfo_buf +
+  offset * sizeof(struct sta_info));
 }
 
 u32_rtw_free_sta_priv(struct   sta_priv *pstapriv)
@@ -157,7 +164,8 @@ u32 _rtw_free_sta_priv(struct   sta_priv *pstapriv)
plist = plist->next;
 
for (i = 0; i < 16; i++) {
-   preorder_ctrl = 
>recvreorder_ctrl[i];
+   preorder_ctrl =
+   >recvreorder_ctrl[i];

del_timer_sync(_ctrl->reordering_ctrl_timer);
}
}
@@ -194,9 +202,11 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv 
*pstapriv, u8 *hwaddr)
_rtw_init_stainfo(psta);
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
index = wifi_mac_hash(hwaddr);
-   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, 
("rtw_alloc_stainfo: index=%x", index));
+   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
+("rtw_alloc_stainfo: index=%x", index));
if (index >= NUM_STA) {
-   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR 
=> rtw_alloc_stainfo: index >= NUM_STA"));
+   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
+("ERROR => rtw_alloc_stainfo: index >= 
NUM_STA"));
psta = NULL;
goto exit;
}
@@ -208,12 +218,16 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv 
*pstapriv, u8 *hwaddr)
spin_unlock_bh(>sta_hash_lock);
 
 /*  Commented by Albert 2009/08/13 */
-/*  For the SMC router, the sequence number of first packet of WPS handshake 
will be 0. */
-/*  In this case, this packet will be dropped by recv_decache function if we 
use the 0x00 as the default value for tid_rxseq variable. */
-/*  So, we initialize the tid_rxseq variable as the 0x. */
+/*  For the SMC router, the sequence number of first packet of WPS handshake
+ *  will be 0.
+ *  In this case, this packet will be dropped by recv_decache function if we 
use
+ *  the 0x00 as the default value for tid_rxseq variable.
+ *  So, we initialize the tid_rxseq variable as the 0x.
+ */
 
for (i = 0; i < 16; i++)
-   memcpy(>sta_recvpriv.rxcache.tid_rxseq[i], 
, 2);
+   

[PATCH v2 3/3] staging: rtl8188eu: Shorten lines over 80 chars

2017-06-12 Thread Aviya Erenfeld
Shorten lines over 80 chars

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 58 +++-
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index cd348ca..c924c9e 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -68,7 +68,8 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
struct sta_info *psta;
s32 i;
 
-   pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * 
NUM_STA + 4);
+   pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) *
+  NUM_STA + 4);
 
if (!pstapriv->pallocated_stainfo_buf)
return _FAIL;
@@ -91,7 +92,8 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
 
INIT_LIST_HEAD(>sta_hash[i]);
 
-   list_add_tail(>list, 
get_list_head(>free_sta_queue));
+   list_add_tail(>list,
+ get_list_head(>free_sta_queue));
 
psta++;
}
@@ -119,20 +121,25 @@ u32   _rtw_init_sta_priv(struct   sta_priv 
*pstapriv)
 
 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
 {
-   int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct 
sta_info);
+   int offset = (((u8 *)sta) - stapriv->pstainfo_buf) /
+ sizeof(struct sta_info);
 
if (!stainfo_offset_valid(offset))
-   DBG_88E("%s invalid offset(%d), out of range!!!", __func__, 
offset);
+   DBG_88E("%s invalid offset(%d), out of range!!!",
+   __func__, offset);
 
return offset;
 }
 
-inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, 
int offset)
+inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv,
+ int offset)
 {
if (!stainfo_offset_valid(offset))
-   DBG_88E("%s invalid offset(%d), out of range!!!", __func__, 
offset);
+   DBG_88E("%s invalid offset(%d), out of range!!!",
+   __func__, offset);
 
-   return (struct sta_info *)(stapriv->pstainfo_buf + offset * 
sizeof(struct sta_info));
+   return (struct sta_info *)(stapriv->pstainfo_buf +
+  offset * sizeof(struct sta_info));
 }
 
 u32_rtw_free_sta_priv(struct   sta_priv *pstapriv)
@@ -157,7 +164,8 @@ u32 _rtw_free_sta_priv(struct   sta_priv *pstapriv)
plist = plist->next;
 
for (i = 0; i < 16; i++) {
-   preorder_ctrl = 
>recvreorder_ctrl[i];
+   preorder_ctrl =
+   >recvreorder_ctrl[i];

del_timer_sync(_ctrl->reordering_ctrl_timer);
}
}
@@ -194,9 +202,11 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv 
*pstapriv, u8 *hwaddr)
_rtw_init_stainfo(psta);
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
index = wifi_mac_hash(hwaddr);
-   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, 
("rtw_alloc_stainfo: index=%x", index));
+   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
+("rtw_alloc_stainfo: index=%x", index));
if (index >= NUM_STA) {
-   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR 
=> rtw_alloc_stainfo: index >= NUM_STA"));
+   RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
+("ERROR => rtw_alloc_stainfo: index >= 
NUM_STA"));
psta = NULL;
goto exit;
}
@@ -208,12 +218,16 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv 
*pstapriv, u8 *hwaddr)
spin_unlock_bh(>sta_hash_lock);
 
 /*  Commented by Albert 2009/08/13 */
-/*  For the SMC router, the sequence number of first packet of WPS handshake 
will be 0. */
-/*  In this case, this packet will be dropped by recv_decache function if we 
use the 0x00 as the default value for tid_rxseq variable. */
-/*  So, we initialize the tid_rxseq variable as the 0x. */
+/*  For the SMC router, the sequence number of first packet of WPS handshake
+ *  will be 0.
+ *  In this case, this packet will be dropped by recv_decache function if we 
use
+ *  the 0x00 as the default value for tid_rxseq variable.
+ *  So, we initialize the tid_rxseq variable as the 0x.
+ */
 
for (i = 0; i < 16; i++)
-   memcpy(>sta_recvpriv.rxcache.tid_rxseq[i], 
, 2);
+   memcpy(>sta_recvpriv.rxcache.tid_rxseq[i],
+ 

[PATCH v2 2/3] staging: rtl8188eu: Remove unneeded blank lines

2017-06-12 Thread Aviya Erenfeld
Remove unneeded blank lines

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index c6a7df5..cd348ca 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -61,7 +61,6 @@ static void _rtw_init_stainfo(struct sta_info *psta)
psta->keep_alive_trycnt = 0;
 
 #endif /*  CONFIG_88EU_AP_MODE */
-
 }
 
 u32_rtw_init_sta_priv(struct   sta_priv *pstapriv)
@@ -69,7 +68,6 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
struct sta_info *psta;
s32 i;
 
-
pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * 
NUM_STA + 4);
 
if (!pstapriv->pallocated_stainfo_buf)
@@ -116,7 +114,6 @@ u32 _rtw_init_sta_priv(struct   sta_priv *pstapriv)
pstapriv->max_num_sta = NUM_STA;
 #endif
 
-
return _SUCCESS;
 }
 
@@ -263,7 +260,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
struct  xmit_priv   *pxmitpriv = >xmitpriv;
struct  sta_priv *pstapriv = >stapriv;
 
-
if (!psta)
goto exit;
 
@@ -381,7 +377,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
 exit:
 
-
return _SUCCESS;
 }
 
@@ -394,7 +389,6 @@ void rtw_free_all_stainfo(struct adapter *padapter)
struct  sta_priv *pstapriv = >stapriv;
struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
 
-
if (pstapriv->asoc_sta_count == 1)
return;
 
@@ -425,7 +419,6 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, 
u8 *hwaddr)
u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-
if (!hwaddr)
return NULL;
 
@@ -463,7 +456,6 @@ u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 
0xff};
struct  sta_priv *pstapriv = >stapriv;
 
-
psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
 
if (!psta) {
-- 
2.7.4


[PATCH v2 2/3] staging: rtl8188eu: Remove unneeded blank lines

2017-06-12 Thread Aviya Erenfeld
Remove unneeded blank lines

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index c6a7df5..cd348ca 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -61,7 +61,6 @@ static void _rtw_init_stainfo(struct sta_info *psta)
psta->keep_alive_trycnt = 0;
 
 #endif /*  CONFIG_88EU_AP_MODE */
-
 }
 
 u32_rtw_init_sta_priv(struct   sta_priv *pstapriv)
@@ -69,7 +68,6 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
struct sta_info *psta;
s32 i;
 
-
pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * 
NUM_STA + 4);
 
if (!pstapriv->pallocated_stainfo_buf)
@@ -116,7 +114,6 @@ u32 _rtw_init_sta_priv(struct   sta_priv *pstapriv)
pstapriv->max_num_sta = NUM_STA;
 #endif
 
-
return _SUCCESS;
 }
 
@@ -263,7 +260,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
struct  xmit_priv   *pxmitpriv = >xmitpriv;
struct  sta_priv *pstapriv = >stapriv;
 
-
if (!psta)
goto exit;
 
@@ -381,7 +377,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
 exit:
 
-
return _SUCCESS;
 }
 
@@ -394,7 +389,6 @@ void rtw_free_all_stainfo(struct adapter *padapter)
struct  sta_priv *pstapriv = >stapriv;
struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
 
-
if (pstapriv->asoc_sta_count == 1)
return;
 
@@ -425,7 +419,6 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, 
u8 *hwaddr)
u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-
if (!hwaddr)
return NULL;
 
@@ -463,7 +456,6 @@ u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 
0xff};
struct  sta_priv *pstapriv = >stapriv;
 
-
psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
 
if (!psta) {
-- 
2.7.4


答复: [PATCH v3] mmc: dw_mmc-k3: add sd support for hi3660

2017-06-12 Thread liwei (CM)
Hi, Jaehoon
Thank you very much for your advices; I'll follow your advices and fix all the 
other places but except for the following one:

"You have assumption...always.
mshc0 -> eMMC, 
mshc1 -> SD
mshc2 -> SDIO"

yes, mshc0 -> eMMC, mshc1 -> SD,mshc2 -> SDIO. Can you point it out in detail? 

Thanks!


-邮件原件-
发件人: Jaehoon Chung [mailto:jh80.ch...@gmail.com] 
发送时间: 2017年6月12日 22:28
收件人: liwei (CM); ulf.hans...@linaro.org; adrian.hun...@intel.com; 
jh80.ch...@samsung.com; shawn@rock-chips.com; 
wsa+rene...@sang-engineering.com; hkallwe...@gmail.com; 
linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
抄送: guodong...@linaro.org
主题: Re: [PATCH v3] mmc: dw_mmc-k3: add sd support for hi3660

Hi Li,

On 2017년 06월 12일 16:46, liwei wrote:
> Add sd card support for hi3660 soc
> 
> Major changes in v3:
>  - solve review comments from Heiner Kallweit.
>*use the GENMASK and FIELD_PREP macros replace the bit shift operation.
>*use usleep_range() replace udelay() and mdelay().

I had added the some comments about your previous patch.
Refer to below...

https://patchwork.kernel.org/patch/9747495/

> 
> Signed-off-by: Li Wei 
> Signed-off-by: Chen Jun 
> ---

Locate changelog at here.

Best Regards,
Jaehoon Chung

>  drivers/mmc/host/dw_mmc-k3.c | 314 
> +++
>  1 file changed, 314 insertions(+)
> 
> diff --git a/drivers/mmc/host/dw_mmc-k3.c 
> b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..a6e13bd83b9f 100644
> --- a/drivers/mmc/host/dw_mmc-k3.c
> +++ b/drivers/mmc/host/dw_mmc-k3.c
> @@ -8,6 +8,8 @@
>   * (at your option) any later version.
>   */
>  
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -28,7 +30,40 @@
>  #define AO_SCTRL_SEL18   BIT(10)
>  #define AO_SCTRL_CTRL3   0x40C
>  
> +#define DWMMC_SD_ID   1
> +#define DWMMC_SDIO_ID 2
> +
> +#define SOC_SCTRL_SCPERCTRL5(0x314)
> +#define SDCARD_IO_SEL18 BIT(2)
> +
> +#define GENCLK_DIV (7)
> +
> +#define GPIO_CLK_ENABLE   BIT(16)
> +#define GPIO_CLK_DIV_MASK GENMASK(11, 8)
> +#define GPIO_USE_SAMPLE_DLY_MASK  GENMASK(13, 13)
> +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16)
> +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK  GENMASK(25, 21)
> +#define UHS_REG_EXT_SAMPLE_DLY_MASK   GENMASK(30, 26)
> +
> +#define SDMMC_UHS_REG_EXT0x108
> +#define SDMMC_ENABLE_SHIFT   0x110
> +
> +#define TIMING_MODE 3
> +#define TIMING_CFG_NUM 10
> +
> +#define PULL_DOWN BIT(1)
> +#define PULL_UP   BIT(0)
> +
> +#define NUM_PHASES (40)
> +
> +#define ENABLE_SHIFT_MIN_SMPL (4)
> +#define ENABLE_SHIFT_MAX_SMPL (12)
> +#define USE_DLY_MIN_SMPL (11)
> +#define USE_DLY_MAX_SMPL (14)
> +
>  struct k3_priv {
> + u8 ctrl_id;
> + u32 cur_speed;
>   struct regmap   *reg;
>  };
>  
> @@ -38,6 +73,41 @@ static unsigned long dw_mci_hi6220_caps[] = {
>   0
>  };
>  
> +struct hs_timing {
> + int drv_phase;
> + int sam_dly;
> + int sam_phase_max;
> + int sam_phase_min;
> +};
> +
> +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = {
> + { /* reserved */ },
> + { /* SD */
> + {7, 0, 15, 15,},  /* 0: LEGACY 400k */
> + {6, 0,  4,  4,},  /* 1: MMC_HS */
> + {6, 0,  3,  3,},  /* 2: SD_HS */
> + {6, 0, 15, 15,},  /* 3: SDR12 */
> + {6, 0,  2,  2,},  /* 4: SDR25 */
> + {4, 0, 11,  0,},  /* 5: SDR50 */
> + {6, 4, 15,  0,},  /* 6: SDR104 */
> + {0},  /* 7: DDR50 */
> + {0},  /* 8: DDR52 */
> + {0},  /* 9: HS200 */
> + },
> + { /* SDIO */
> + {7, 0, 15, 15,},  /* 0: LEGACY 400k */
> + {0},  /* 1: MMC_HS */
> + {6, 0, 15, 15,},  /* 2: SD_HS */
> + {6, 0, 15, 15,},  /* 3: SDR12 */
> + {6, 0,  0,  0,},  /* 4: SDR25 */
> + {4, 0, 12,  0,},  /* 5: SDR50 */
> + {5, 4, 15,  0,},  /* 6: SDR104 */
> + {0},  /* 7: DDR50 */
> + {0},  /* 8: DDR52 */
> + {0},  /* 9: HS200 */
> + }
> +};
> +
>  static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios 
> *ios)  {
>   int ret;
> @@ -66,6 +136,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host)
>   if (IS_ERR(priv->reg))
>   priv->reg = NULL;
>  
> + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
> + if (priv->ctrl_id < 0)
> + priv->ctrl_id = 0;
> +
>   host->priv = priv;
>   return 0;
>  }
> @@ -144,7 +218,242 @@ static const struct dw_mci_drv_data hi6220_data = {
>   .execute_tuning = dw_mci_hi6220_execute_tuning,
>  };
>  
> +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, int 
> +sam_phase) {
> + int drv_phase;
> + int sam_dly;
> + int ctrl_id;
> +  

答复: [PATCH v3] mmc: dw_mmc-k3: add sd support for hi3660

2017-06-12 Thread liwei (CM)
Hi, Jaehoon
Thank you very much for your advices; I'll follow your advices and fix all the 
other places but except for the following one:

"You have assumption...always.
mshc0 -> eMMC, 
mshc1 -> SD
mshc2 -> SDIO"

yes, mshc0 -> eMMC, mshc1 -> SD,mshc2 -> SDIO. Can you point it out in detail? 

Thanks!


-邮件原件-
发件人: Jaehoon Chung [mailto:jh80.ch...@gmail.com] 
发送时间: 2017年6月12日 22:28
收件人: liwei (CM); ulf.hans...@linaro.org; adrian.hun...@intel.com; 
jh80.ch...@samsung.com; shawn@rock-chips.com; 
wsa+rene...@sang-engineering.com; hkallwe...@gmail.com; 
linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
抄送: guodong...@linaro.org
主题: Re: [PATCH v3] mmc: dw_mmc-k3: add sd support for hi3660

Hi Li,

On 2017년 06월 12일 16:46, liwei wrote:
> Add sd card support for hi3660 soc
> 
> Major changes in v3:
>  - solve review comments from Heiner Kallweit.
>*use the GENMASK and FIELD_PREP macros replace the bit shift operation.
>*use usleep_range() replace udelay() and mdelay().

I had added the some comments about your previous patch.
Refer to below...

https://patchwork.kernel.org/patch/9747495/

> 
> Signed-off-by: Li Wei 
> Signed-off-by: Chen Jun 
> ---

Locate changelog at here.

Best Regards,
Jaehoon Chung

>  drivers/mmc/host/dw_mmc-k3.c | 314 
> +++
>  1 file changed, 314 insertions(+)
> 
> diff --git a/drivers/mmc/host/dw_mmc-k3.c 
> b/drivers/mmc/host/dw_mmc-k3.c index e38fb0020bb1..a6e13bd83b9f 100644
> --- a/drivers/mmc/host/dw_mmc-k3.c
> +++ b/drivers/mmc/host/dw_mmc-k3.c
> @@ -8,6 +8,8 @@
>   * (at your option) any later version.
>   */
>  
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -28,7 +30,40 @@
>  #define AO_SCTRL_SEL18   BIT(10)
>  #define AO_SCTRL_CTRL3   0x40C
>  
> +#define DWMMC_SD_ID   1
> +#define DWMMC_SDIO_ID 2
> +
> +#define SOC_SCTRL_SCPERCTRL5(0x314)
> +#define SDCARD_IO_SEL18 BIT(2)
> +
> +#define GENCLK_DIV (7)
> +
> +#define GPIO_CLK_ENABLE   BIT(16)
> +#define GPIO_CLK_DIV_MASK GENMASK(11, 8)
> +#define GPIO_USE_SAMPLE_DLY_MASK  GENMASK(13, 13)
> +#define UHS_REG_EXT_SAMPLE_PHASE_MASK GENMASK(20, 16)
> +#define UHS_REG_EXT_SAMPLE_DRVPHASE_MASK  GENMASK(25, 21)
> +#define UHS_REG_EXT_SAMPLE_DLY_MASK   GENMASK(30, 26)
> +
> +#define SDMMC_UHS_REG_EXT0x108
> +#define SDMMC_ENABLE_SHIFT   0x110
> +
> +#define TIMING_MODE 3
> +#define TIMING_CFG_NUM 10
> +
> +#define PULL_DOWN BIT(1)
> +#define PULL_UP   BIT(0)
> +
> +#define NUM_PHASES (40)
> +
> +#define ENABLE_SHIFT_MIN_SMPL (4)
> +#define ENABLE_SHIFT_MAX_SMPL (12)
> +#define USE_DLY_MIN_SMPL (11)
> +#define USE_DLY_MAX_SMPL (14)
> +
>  struct k3_priv {
> + u8 ctrl_id;
> + u32 cur_speed;
>   struct regmap   *reg;
>  };
>  
> @@ -38,6 +73,41 @@ static unsigned long dw_mci_hi6220_caps[] = {
>   0
>  };
>  
> +struct hs_timing {
> + int drv_phase;
> + int sam_dly;
> + int sam_phase_max;
> + int sam_phase_min;
> +};
> +
> +struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = {
> + { /* reserved */ },
> + { /* SD */
> + {7, 0, 15, 15,},  /* 0: LEGACY 400k */
> + {6, 0,  4,  4,},  /* 1: MMC_HS */
> + {6, 0,  3,  3,},  /* 2: SD_HS */
> + {6, 0, 15, 15,},  /* 3: SDR12 */
> + {6, 0,  2,  2,},  /* 4: SDR25 */
> + {4, 0, 11,  0,},  /* 5: SDR50 */
> + {6, 4, 15,  0,},  /* 6: SDR104 */
> + {0},  /* 7: DDR50 */
> + {0},  /* 8: DDR52 */
> + {0},  /* 9: HS200 */
> + },
> + { /* SDIO */
> + {7, 0, 15, 15,},  /* 0: LEGACY 400k */
> + {0},  /* 1: MMC_HS */
> + {6, 0, 15, 15,},  /* 2: SD_HS */
> + {6, 0, 15, 15,},  /* 3: SDR12 */
> + {6, 0,  0,  0,},  /* 4: SDR25 */
> + {4, 0, 12,  0,},  /* 5: SDR50 */
> + {5, 4, 15,  0,},  /* 6: SDR104 */
> + {0},  /* 7: DDR50 */
> + {0},  /* 8: DDR52 */
> + {0},  /* 9: HS200 */
> + }
> +};
> +
>  static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios 
> *ios)  {
>   int ret;
> @@ -66,6 +136,10 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host)
>   if (IS_ERR(priv->reg))
>   priv->reg = NULL;
>  
> + priv->ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
> + if (priv->ctrl_id < 0)
> + priv->ctrl_id = 0;
> +
>   host->priv = priv;
>   return 0;
>  }
> @@ -144,7 +218,242 @@ static const struct dw_mci_drv_data hi6220_data = {
>   .execute_tuning = dw_mci_hi6220_execute_tuning,
>  };
>  
> +static void dw_mci_hs_set_timing(struct dw_mci *host, int timing, int 
> +sam_phase) {
> + int drv_phase;
> + int sam_dly;
> + int ctrl_id;
> + int use_sam_dly = 0;
> + int 

[PATCH v2 1/3] staging: rtl8188eu: Remove redundant parenthesis

2017-06-12 Thread Aviya Erenfeld
Remove redundant parenthesis

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index 2ecfb11..c6a7df5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -91,7 +91,7 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
for (i = 0; i < NUM_STA; i++) {
_rtw_init_stainfo(psta);
 
-   INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
+   INIT_LIST_HEAD(>sta_hash[i]);
 
list_add_tail(>list, 
get_list_head(>free_sta_queue));
 
@@ -149,7 +149,7 @@ u32 _rtw_free_sta_priv(struct   sta_priv *pstapriv)
/*  delete all reordering_ctrl_timer*/
spin_lock_bh(>sta_hash_lock);
for (index = 0; index < NUM_STA; index++) {
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -278,19 +278,19 @@ u32   rtw_free_stainfo(struct adapter *padapter, 
struct sta_info *psta)
 
rtw_free_xmitframe_queue(pxmitpriv, >vo_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
+   list_del_init(>vo_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >vi_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
+   list_del_init(>vi_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >bk_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
+   list_del_init(>bk_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >be_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->be_q.tx_pending));
+   list_del_init(>be_q.tx_pending);
 
spin_unlock_bh(>lock);
 
@@ -331,7 +331,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
plist = plist->next;
 
-   list_del_init(&(prframe->list));
+   list_del_init(>list);
 
rtw_free_recvframe(prframe, pfree_recv_queue);
}
@@ -375,7 +375,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
 #endif /*  CONFIG_88EU_AP_MODE */
 
-   spin_lock_bh(&(pfree_sta_queue->lock));
+   spin_lock_bh(_sta_queue->lock);
list_add_tail(>list, get_list_head(pfree_sta_queue));
spin_unlock_bh(_sta_queue->lock);
 
@@ -401,7 +401,7 @@ void rtw_free_all_stainfo(struct adapter *padapter)
spin_lock_bh(>sta_hash_lock);
 
for (index = 0; index < NUM_STA; index++) {
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -438,7 +438,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, 
u8 *hwaddr)
 
spin_lock_bh(>sta_hash_lock);
 
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -497,7 +497,7 @@ u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
struct wlan_acl_pool *pacl_list = >acl_list;
struct __queue *pacl_node_q = _list->acl_node_q;
 
-   spin_lock_bh(&(pacl_node_q->lock));
+   spin_lock_bh(_node_q->lock);
phead = get_list_head(pacl_node_q);
plist = phead->next;
while (phead != plist) {
-- 
2.7.4


[PATCH v2 1/3] staging: rtl8188eu: Remove redundant parenthesis

2017-06-12 Thread Aviya Erenfeld
Remove redundant parenthesis

Signed-off-by: Aviya Erenfeld 
---
 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c 
b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index 2ecfb11..c6a7df5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -91,7 +91,7 @@ u32   _rtw_init_sta_priv(struct   sta_priv *pstapriv)
for (i = 0; i < NUM_STA; i++) {
_rtw_init_stainfo(psta);
 
-   INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
+   INIT_LIST_HEAD(>sta_hash[i]);
 
list_add_tail(>list, 
get_list_head(>free_sta_queue));
 
@@ -149,7 +149,7 @@ u32 _rtw_free_sta_priv(struct   sta_priv *pstapriv)
/*  delete all reordering_ctrl_timer*/
spin_lock_bh(>sta_hash_lock);
for (index = 0; index < NUM_STA; index++) {
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -278,19 +278,19 @@ u32   rtw_free_stainfo(struct adapter *padapter, 
struct sta_info *psta)
 
rtw_free_xmitframe_queue(pxmitpriv, >vo_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
+   list_del_init(>vo_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >vi_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
+   list_del_init(>vi_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >bk_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
+   list_del_init(>bk_q.tx_pending);
 
rtw_free_xmitframe_queue(pxmitpriv, >be_q.sta_pending);
 
-   list_del_init(&(pstaxmitpriv->be_q.tx_pending));
+   list_del_init(>be_q.tx_pending);
 
spin_unlock_bh(>lock);
 
@@ -331,7 +331,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
plist = plist->next;
 
-   list_del_init(&(prframe->list));
+   list_del_init(>list);
 
rtw_free_recvframe(prframe, pfree_recv_queue);
}
@@ -375,7 +375,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct 
sta_info *psta)
 
 #endif /*  CONFIG_88EU_AP_MODE */
 
-   spin_lock_bh(&(pfree_sta_queue->lock));
+   spin_lock_bh(_sta_queue->lock);
list_add_tail(>list, get_list_head(pfree_sta_queue));
spin_unlock_bh(_sta_queue->lock);
 
@@ -401,7 +401,7 @@ void rtw_free_all_stainfo(struct adapter *padapter)
spin_lock_bh(>sta_hash_lock);
 
for (index = 0; index < NUM_STA; index++) {
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -438,7 +438,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, 
u8 *hwaddr)
 
spin_lock_bh(>sta_hash_lock);
 
-   phead = &(pstapriv->sta_hash[index]);
+   phead = >sta_hash[index];
plist = phead->next;
 
while (phead != plist) {
@@ -497,7 +497,7 @@ u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
struct wlan_acl_pool *pacl_list = >acl_list;
struct __queue *pacl_node_q = _list->acl_node_q;
 
-   spin_lock_bh(&(pacl_node_q->lock));
+   spin_lock_bh(_node_q->lock);
phead = get_list_head(pacl_node_q);
plist = phead->next;
while (phead != plist) {
-- 
2.7.4


[PATCH v2 0/3] Fix some style issues

2017-06-12 Thread Aviya Erenfeld
Fix some of the issues that checkpatch complains on like redundant
parenthesis, redundant blank lines and lines over 80 chars.

Aviya Erenfeld (3):
  staging: rtl8188eu: Remove redundant parenthesis
  staging: rtl8188eu: Remove unneeded blank lines
  staging: rtl8188eu: Shorten lines over 80 chars

 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 88 
 1 file changed, 50 insertions(+), 38 deletions(-)

-- 
2.7.4


[PATCH v2 0/3] Fix some style issues

2017-06-12 Thread Aviya Erenfeld
Fix some of the issues that checkpatch complains on like redundant
parenthesis, redundant blank lines and lines over 80 chars.

Aviya Erenfeld (3):
  staging: rtl8188eu: Remove redundant parenthesis
  staging: rtl8188eu: Remove unneeded blank lines
  staging: rtl8188eu: Shorten lines over 80 chars

 drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 88 
 1 file changed, 50 insertions(+), 38 deletions(-)

-- 
2.7.4


Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option

2017-06-12 Thread Schöfegger Stefan
On Monday, June 12, 2017 6:49:24 PM CEST Bjorn Helgaas wrote:
> On Wed, Jun 07, 2017 at 01:36:11PM +0200, Stefan Schoefegger wrote:
> > Link speed must not be limited to gen1 during link test for compliance
> > tests
> > 
> > Signed-off-by: Stefan Schoefegger 
> > ---
> > 
> > Changes since v1:
> >  - pci-imx6.c moved to dwc directory
> >  
> >  drivers/pci/dwc/Kconfig| 10 ++
> >  drivers/pci/dwc/pci-imx6.c | 21 -
> >  2 files changed, 22 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
> > index b7e15526d676..b6e9ced5a45d 100644
> > --- a/drivers/pci/dwc/Kconfig
> > +++ b/drivers/pci/dwc/Kconfig
> > @@ -77,6 +77,16 @@ config PCI_IMX6
> > 
> > select PCIEPORTBUS
> > select PCIE_DW_HOST
> > 
> > +config PCI_IMX6_COMPLIANCE_TEST
> > +   bool "Enable pcie compliance tests on imx6"
> > +   depends on PCI_IMX6
> > +   default n
> > +   help
> > + Enables support for pcie compliance test on FSL iMX SoCs.
> > + The link speed wouldn't be limited to gen1 when enabled.
> > + Enable only during compliance tests, otherwise
> > + link detection will fail on some peripherals.
> 
> I'm puzzled about why we would want to merge this patch.  It looks
> like we're trying to game the system to make the device pass
> compliance testing when it isn't really compliant.  Is this config
> option useful to users, or is it only useful during internal
> development of iMX SoCs?

It's not for passing compliance tests, it is necessary to do the compliance 
tests. Without this patch only gen 1 speed is possible to test. Also i.mx6 is 
not fully gen2 compliant (withour external clk) we should have the option to 
do gen2 tests. Switching from gen1 to gen2 is done with a 100MHz (1ms) clk 
pulse on the receiver. Without this patch link speed is forced to gen1 
afterwards.
Yes it is only useful for board setup, it is comparable to 
CONFIG_USB_EHSET_TEST_FIXTURE for usb (ok, this is more general and not host 
specific).

> 
> >  config PCIE_SPEAR13XX
> >  
> > bool "STMicroelectronics SPEAr PCIe controller"
> > depends on PCI
> > 
> > diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
> > index 19a289b8cc94..b0fbe52e25b0 100644
> > --- a/drivers/pci/dwc/pci-imx6.c
> > +++ b/drivers/pci/dwc/pci-imx6.c
> > @@ -533,15 +533,18 @@ static int imx6_pcie_establish_link(struct imx6_pcie
> > *imx6_pcie)> 
> > u32 tmp;
> > int ret;
> > 
> > -   /*
> > -* Force Gen1 operation when starting the link.  In case the link is
> > -* started in Gen2 mode, there is a possibility the devices on the
> > -* bus will not be detected at all.  This happens with PCIe switches.
> > -*/
> > -   tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > -   tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > -   tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > -   dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > +   if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
> > +   /*
> > +* Force Gen1 operation when starting the link.  In case the
> > +* link is started in Gen2 mode, there is a possibility the
> > +* devices on the bus will not be detected at all.  This
> > +* happens with PCIe switches.
> > +*/
> > +   tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > +   tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > +   tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > +   dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > +   }
> > 
> > /* Start LTSSM. */
> > if (imx6_pcie->variant == IMX7D)



Re: [PATCH v2 1/1] PCI: imx6: Add pcie compliance test option

2017-06-12 Thread Schöfegger Stefan
On Monday, June 12, 2017 6:49:24 PM CEST Bjorn Helgaas wrote:
> On Wed, Jun 07, 2017 at 01:36:11PM +0200, Stefan Schoefegger wrote:
> > Link speed must not be limited to gen1 during link test for compliance
> > tests
> > 
> > Signed-off-by: Stefan Schoefegger 
> > ---
> > 
> > Changes since v1:
> >  - pci-imx6.c moved to dwc directory
> >  
> >  drivers/pci/dwc/Kconfig| 10 ++
> >  drivers/pci/dwc/pci-imx6.c | 21 -
> >  2 files changed, 22 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
> > index b7e15526d676..b6e9ced5a45d 100644
> > --- a/drivers/pci/dwc/Kconfig
> > +++ b/drivers/pci/dwc/Kconfig
> > @@ -77,6 +77,16 @@ config PCI_IMX6
> > 
> > select PCIEPORTBUS
> > select PCIE_DW_HOST
> > 
> > +config PCI_IMX6_COMPLIANCE_TEST
> > +   bool "Enable pcie compliance tests on imx6"
> > +   depends on PCI_IMX6
> > +   default n
> > +   help
> > + Enables support for pcie compliance test on FSL iMX SoCs.
> > + The link speed wouldn't be limited to gen1 when enabled.
> > + Enable only during compliance tests, otherwise
> > + link detection will fail on some peripherals.
> 
> I'm puzzled about why we would want to merge this patch.  It looks
> like we're trying to game the system to make the device pass
> compliance testing when it isn't really compliant.  Is this config
> option useful to users, or is it only useful during internal
> development of iMX SoCs?

It's not for passing compliance tests, it is necessary to do the compliance 
tests. Without this patch only gen 1 speed is possible to test. Also i.mx6 is 
not fully gen2 compliant (withour external clk) we should have the option to 
do gen2 tests. Switching from gen1 to gen2 is done with a 100MHz (1ms) clk 
pulse on the receiver. Without this patch link speed is forced to gen1 
afterwards.
Yes it is only useful for board setup, it is comparable to 
CONFIG_USB_EHSET_TEST_FIXTURE for usb (ok, this is more general and not host 
specific).

> 
> >  config PCIE_SPEAR13XX
> >  
> > bool "STMicroelectronics SPEAr PCIe controller"
> > depends on PCI
> > 
> > diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
> > index 19a289b8cc94..b0fbe52e25b0 100644
> > --- a/drivers/pci/dwc/pci-imx6.c
> > +++ b/drivers/pci/dwc/pci-imx6.c
> > @@ -533,15 +533,18 @@ static int imx6_pcie_establish_link(struct imx6_pcie
> > *imx6_pcie)> 
> > u32 tmp;
> > int ret;
> > 
> > -   /*
> > -* Force Gen1 operation when starting the link.  In case the link is
> > -* started in Gen2 mode, there is a possibility the devices on the
> > -* bus will not be detected at all.  This happens with PCIe switches.
> > -*/
> > -   tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > -   tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > -   tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > -   dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > +   if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
> > +   /*
> > +* Force Gen1 operation when starting the link.  In case the
> > +* link is started in Gen2 mode, there is a possibility the
> > +* devices on the bus will not be detected at all.  This
> > +* happens with PCIe switches.
> > +*/
> > +   tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
> > +   tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
> > +   tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
> > +   dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
> > +   }
> > 
> > /* Start LTSSM. */
> > if (imx6_pcie->variant == IMX7D)



Re: [PATCH v3 1/2] PCI: iproc: Retry request when CRS returned from EP

2017-06-12 Thread Oza Oza
On Tue, Jun 13, 2017 at 9:58 AM, Oza Oza  wrote:
> On Tue, Jun 13, 2017 at 5:00 AM, Bjorn Helgaas  wrote:
>> Please wrap your changelogs to use 75 columns.  "git log" indents the
>> changelog by four spaces, so if your text is 75 wide, it will still
>> fit without wrapping.
>>
>> On Sun, Jun 11, 2017 at 09:35:37AM +0530, Oza Pawandeep wrote:
>>> For Configuration Requests only, following reset
>>> it is possible for a device to terminate the request
>>> but indicate that it is temporarily unable to process
>>> the Request, but will be able to process the Request
>>> in the future – in this case, the Configuration Request
>>> Retry Status 10 (CRS) Completion Status is used
>>
>> How does this relate to the CRS support we already have in the core,
>> e.g., pci_bus_read_dev_vendor_id()?  It looks like your root complex
>> already returns 0x0001 (CFG_RETRY_STATUS) in some cases.
>>
>> Also, per spec (PCIe r3.1, sec 2.3.2), CRS Software Visibility only
>> affects config reads of the Vendor ID, but you call
>> iproc_pcie_cfg_retry() for all config offsets.
>
> Yes, as per Spec, CRS Software Visibility only affects config read of
> the Vendor ID.
> For config write or any other config read the Root must automatically
> re-issue configuration
> request again as a new request, and our PCIe RC fails to do so.
>
>>
>>> SPDK user space NVMe driver reinitializes NVMe which
>>> causes reset, while doing this some configuration requests
>>> get NAKed by Endpoint (NVMe).
>>
>> What's SPDK?  I don't know what "NAK" means in a PCIe context.  If you
>> can use the appropriate PCIe terminology, I think it will make more
>> sense to me.

SPDK supports user space poll mode driver, and along with DPDK
interface with vfio
to directly map PCIe resources to user space.
the reason I mentioned SPDK, because it exposes this bug in our PCIe RC.

>
> when I meant NAK, I meant CRS, will change the description, and will take
> care of using appropriate PCIe terminology.
>
>>
>>> Current iproc PCI driver is agnostic about it.
>>> PAXB will forward the NAKed response in stipulated AXI code.
>>
>> In general a native host bridge driver should not have to deal with
>> the CRS feature because it's supported in the PCI core.  So we need
>> some explanation about why iProc is special in this regard.
>>
>
> For config write or any other config read the Root must automatically
> re-issue configuration
> request again as a new request, iproc based PCIe RC does not adhere to
> this, and also
> our PCI-to-AXI bridge (internal), which returns code 0x0001 to CPU.
>
>>> NVMe spec defines this timeout in 500 ms units, and this
>>> only happens if controller has been in reset, or with new firmware,
>>> or in abrupt shutdown case.
>>> Meanwhile config access could result into retry.
>>
>> I don't understand why NVMe is relevant here.  Is there something
>> special about NVMe and CRS?
>>
>
> You are right, NVMe spec is irrelevant here, but since whole
> exercise was carried out with NVMe and our major use cases are NVMe,
> I ended up mentioning that. I can remove that from description.
>
>>> This patch fixes the problem, and attempts to read again in case
>>> of PAXB forwarding the NAK.
>>>
>>> It implements iproc_pcie_config_read which gets called for Stingray.
>>> Otherwise it falls back to PCI generic APIs.
>>>
>>> Signed-off-by: Oza Pawandeep 
>>> Reviewed-by: Ray Jui 
>>> Reviewed-by: Scott Branden 
>>>
>>> diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
>>> index 0f39bd2..05a3647 100644
>>> --- a/drivers/pci/host/pcie-iproc.c
>>> +++ b/drivers/pci/host/pcie-iproc.c
>>> @@ -68,6 +68,9 @@
>>>  #define APB_ERR_EN_SHIFT 0
>>>  #define APB_ERR_EN   BIT(APB_ERR_EN_SHIFT)
>>>
>>> +#define CFG_RETRY_STATUS 0x0001
>>> +#define CFG_RETRY_STATUS_TIMEOUT_US  50 /* 500 milli-seconds. */
>>> +
>>>  /* derive the enum index of the outbound/inbound mapping registers */
>>>  #define MAP_REG(base_reg, index)  ((base_reg) + (index) * 2)
>>>
>>> @@ -448,6 +451,47 @@ static inline void iproc_pcie_apb_err_disable(struct 
>>> pci_bus *bus,
>>>   }
>>>  }
>>>
>>> +static int iproc_pcie_cfg_retry(void __iomem *cfg_data_p)
>>> +{
>>> + int timeout = CFG_RETRY_STATUS_TIMEOUT_US;
>>> + unsigned int ret;
>>> +
>>> + do {
>>> + ret = readl(cfg_data_p);
>>> + if (ret == CFG_RETRY_STATUS)
>>> + udelay(1);
>>> + else
>>> + return PCIBIOS_SUCCESSFUL;
>>> + } while (timeout--);
>>> +
>>> + return PCIBIOS_DEVICE_NOT_FOUND;
>>> +}
>>> +
>>> +static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie,
>>> +unsigned int busno,
>>> +unsigned int slot,
>>> + 

Re: [PATCH v3 1/2] PCI: iproc: Retry request when CRS returned from EP

2017-06-12 Thread Oza Oza
On Tue, Jun 13, 2017 at 9:58 AM, Oza Oza  wrote:
> On Tue, Jun 13, 2017 at 5:00 AM, Bjorn Helgaas  wrote:
>> Please wrap your changelogs to use 75 columns.  "git log" indents the
>> changelog by four spaces, so if your text is 75 wide, it will still
>> fit without wrapping.
>>
>> On Sun, Jun 11, 2017 at 09:35:37AM +0530, Oza Pawandeep wrote:
>>> For Configuration Requests only, following reset
>>> it is possible for a device to terminate the request
>>> but indicate that it is temporarily unable to process
>>> the Request, but will be able to process the Request
>>> in the future – in this case, the Configuration Request
>>> Retry Status 10 (CRS) Completion Status is used
>>
>> How does this relate to the CRS support we already have in the core,
>> e.g., pci_bus_read_dev_vendor_id()?  It looks like your root complex
>> already returns 0x0001 (CFG_RETRY_STATUS) in some cases.
>>
>> Also, per spec (PCIe r3.1, sec 2.3.2), CRS Software Visibility only
>> affects config reads of the Vendor ID, but you call
>> iproc_pcie_cfg_retry() for all config offsets.
>
> Yes, as per Spec, CRS Software Visibility only affects config read of
> the Vendor ID.
> For config write or any other config read the Root must automatically
> re-issue configuration
> request again as a new request, and our PCIe RC fails to do so.
>
>>
>>> SPDK user space NVMe driver reinitializes NVMe which
>>> causes reset, while doing this some configuration requests
>>> get NAKed by Endpoint (NVMe).
>>
>> What's SPDK?  I don't know what "NAK" means in a PCIe context.  If you
>> can use the appropriate PCIe terminology, I think it will make more
>> sense to me.

SPDK supports user space poll mode driver, and along with DPDK
interface with vfio
to directly map PCIe resources to user space.
the reason I mentioned SPDK, because it exposes this bug in our PCIe RC.

>
> when I meant NAK, I meant CRS, will change the description, and will take
> care of using appropriate PCIe terminology.
>
>>
>>> Current iproc PCI driver is agnostic about it.
>>> PAXB will forward the NAKed response in stipulated AXI code.
>>
>> In general a native host bridge driver should not have to deal with
>> the CRS feature because it's supported in the PCI core.  So we need
>> some explanation about why iProc is special in this regard.
>>
>
> For config write or any other config read the Root must automatically
> re-issue configuration
> request again as a new request, iproc based PCIe RC does not adhere to
> this, and also
> our PCI-to-AXI bridge (internal), which returns code 0x0001 to CPU.
>
>>> NVMe spec defines this timeout in 500 ms units, and this
>>> only happens if controller has been in reset, or with new firmware,
>>> or in abrupt shutdown case.
>>> Meanwhile config access could result into retry.
>>
>> I don't understand why NVMe is relevant here.  Is there something
>> special about NVMe and CRS?
>>
>
> You are right, NVMe spec is irrelevant here, but since whole
> exercise was carried out with NVMe and our major use cases are NVMe,
> I ended up mentioning that. I can remove that from description.
>
>>> This patch fixes the problem, and attempts to read again in case
>>> of PAXB forwarding the NAK.
>>>
>>> It implements iproc_pcie_config_read which gets called for Stingray.
>>> Otherwise it falls back to PCI generic APIs.
>>>
>>> Signed-off-by: Oza Pawandeep 
>>> Reviewed-by: Ray Jui 
>>> Reviewed-by: Scott Branden 
>>>
>>> diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
>>> index 0f39bd2..05a3647 100644
>>> --- a/drivers/pci/host/pcie-iproc.c
>>> +++ b/drivers/pci/host/pcie-iproc.c
>>> @@ -68,6 +68,9 @@
>>>  #define APB_ERR_EN_SHIFT 0
>>>  #define APB_ERR_EN   BIT(APB_ERR_EN_SHIFT)
>>>
>>> +#define CFG_RETRY_STATUS 0x0001
>>> +#define CFG_RETRY_STATUS_TIMEOUT_US  50 /* 500 milli-seconds. */
>>> +
>>>  /* derive the enum index of the outbound/inbound mapping registers */
>>>  #define MAP_REG(base_reg, index)  ((base_reg) + (index) * 2)
>>>
>>> @@ -448,6 +451,47 @@ static inline void iproc_pcie_apb_err_disable(struct 
>>> pci_bus *bus,
>>>   }
>>>  }
>>>
>>> +static int iproc_pcie_cfg_retry(void __iomem *cfg_data_p)
>>> +{
>>> + int timeout = CFG_RETRY_STATUS_TIMEOUT_US;
>>> + unsigned int ret;
>>> +
>>> + do {
>>> + ret = readl(cfg_data_p);
>>> + if (ret == CFG_RETRY_STATUS)
>>> + udelay(1);
>>> + else
>>> + return PCIBIOS_SUCCESSFUL;
>>> + } while (timeout--);
>>> +
>>> + return PCIBIOS_DEVICE_NOT_FOUND;
>>> +}
>>> +
>>> +static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie,
>>> +unsigned int busno,
>>> +unsigned int slot,
>>> +unsigned int fn,
>>> +int where)
>>> +{
>>> + u16 offset;
>>> 

Re: [PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-06-12 Thread Abylay Ospan
Dear Takiguchi,

Roger that.
Thanks for explanation !

2017-06-13 1:35 GMT-04:00 Takiguchi, Yasunari :
> Dear Abylay Ospan
>
> Thank you for your review and proposal.
>
> Unfortunately, we supposed it's difficult to cover CXD2841 functionality by 
> CXD2880 driver.
> CXD2880 is for mobile IC, tuner (RF) and demodulator convined IC.
> On the other hand, CXD2841 is demodulator only IC for stationary use.
> CXD2841 supports terrestrial, cable and satellite broadcasting systems.
> But CXD2880 supports terrestrial broadcasting systems only.
> And as you suggested, the driver supports SPI interface only.
>
> Regards & Thanks a lot
> Takiguchi
>
>
> On 2017/06/12 22:33, Abylay Ospan wrote:
>> Dear Takiguchi,
>>
>> I'm working on 'drivers/media/dvb-frontends/cxd2841er.c' (universal
>> demod) and 'linux/drivers/media/dvb-frontends/helene.c' (universal
>> TERR/CABLE/SAT tuner).
>>
>> How do you think - is your cxd2880 proposed driver have possibilities
>> to cover cxd2841er demod functionality too ?
>>
>> I have quickly checked your cxd2880_top.c and looks like cxd2880 works
>> over SPI (not I2C) ?Also, looks like registers map, sequences
>> is different. Am I right ?
>>
>> How do you think ?
>>
>> Thanks a lot !
>



-- 
Abylay Ospan,
NetUP Inc.
http://www.netup.tv


Re: [PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-06-12 Thread Abylay Ospan
Dear Takiguchi,

Roger that.
Thanks for explanation !

2017-06-13 1:35 GMT-04:00 Takiguchi, Yasunari :
> Dear Abylay Ospan
>
> Thank you for your review and proposal.
>
> Unfortunately, we supposed it's difficult to cover CXD2841 functionality by 
> CXD2880 driver.
> CXD2880 is for mobile IC, tuner (RF) and demodulator convined IC.
> On the other hand, CXD2841 is demodulator only IC for stationary use.
> CXD2841 supports terrestrial, cable and satellite broadcasting systems.
> But CXD2880 supports terrestrial broadcasting systems only.
> And as you suggested, the driver supports SPI interface only.
>
> Regards & Thanks a lot
> Takiguchi
>
>
> On 2017/06/12 22:33, Abylay Ospan wrote:
>> Dear Takiguchi,
>>
>> I'm working on 'drivers/media/dvb-frontends/cxd2841er.c' (universal
>> demod) and 'linux/drivers/media/dvb-frontends/helene.c' (universal
>> TERR/CABLE/SAT tuner).
>>
>> How do you think - is your cxd2880 proposed driver have possibilities
>> to cover cxd2841er demod functionality too ?
>>
>> I have quickly checked your cxd2880_top.c and looks like cxd2880 works
>> over SPI (not I2C) ?Also, looks like registers map, sequences
>> is different. Am I right ?
>>
>> How do you think ?
>>
>> Thanks a lot !
>



-- 
Abylay Ospan,
NetUP Inc.
http://www.netup.tv


Re: [PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-06-12 Thread Takiguchi, Yasunari
Dear Abylay Ospan

Thank you for your review and proposal.

Unfortunately, we supposed it's difficult to cover CXD2841 functionality by 
CXD2880 driver.
CXD2880 is for mobile IC, tuner (RF) and demodulator convined IC.
On the other hand, CXD2841 is demodulator only IC for stationary use.
CXD2841 supports terrestrial, cable and satellite broadcasting systems.
But CXD2880 supports terrestrial broadcasting systems only.
And as you suggested, the driver supports SPI interface only.

Regards & Thanks a lot
Takiguchi


On 2017/06/12 22:33, Abylay Ospan wrote:
> Dear Takiguchi,
> 
> I'm working on 'drivers/media/dvb-frontends/cxd2841er.c' (universal
> demod) and 'linux/drivers/media/dvb-frontends/helene.c' (universal
> TERR/CABLE/SAT tuner).
> 
> How do you think - is your cxd2880 proposed driver have possibilities
> to cover cxd2841er demod functionality too ?
> 
> I have quickly checked your cxd2880_top.c and looks like cxd2880 works
> over SPI (not I2C) ?Also, looks like registers map, sequences
> is different. Am I right ?
> 
> How do you think ?
> 
> Thanks a lot !



Re: [PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-06-12 Thread Takiguchi, Yasunari
Dear Abylay Ospan

Thank you for your review and proposal.

Unfortunately, we supposed it's difficult to cover CXD2841 functionality by 
CXD2880 driver.
CXD2880 is for mobile IC, tuner (RF) and demodulator convined IC.
On the other hand, CXD2841 is demodulator only IC for stationary use.
CXD2841 supports terrestrial, cable and satellite broadcasting systems.
But CXD2880 supports terrestrial broadcasting systems only.
And as you suggested, the driver supports SPI interface only.

Regards & Thanks a lot
Takiguchi


On 2017/06/12 22:33, Abylay Ospan wrote:
> Dear Takiguchi,
> 
> I'm working on 'drivers/media/dvb-frontends/cxd2841er.c' (universal
> demod) and 'linux/drivers/media/dvb-frontends/helene.c' (universal
> TERR/CABLE/SAT tuner).
> 
> How do you think - is your cxd2880 proposed driver have possibilities
> to cover cxd2841er demod functionality too ?
> 
> I have quickly checked your cxd2880_top.c and looks like cxd2880 works
> over SPI (not I2C) ?Also, looks like registers map, sequences
> is different. Am I right ?
> 
> How do you think ?
> 
> Thanks a lot !



Re: [Patch v4 00/12] Add MFC v10.10 support

2017-06-12 Thread Smitha T Murthy
On Fri, 2017-06-09 at 19:36 +0200, Sylwester Nawrocki wrote:
> On 04/06/2017 08:11 AM, Smitha T Murthy wrote:
> > This patch series adds MFC v10.10 support. MFC v10.10 is used in some
> > of Exynos7 variants.
> > 
> > This adds support for following:
> > 
> > * Add support for HEVC encoder and decoder
> > * Add support for VP9 decoder
> > * Update Documentation for control id definitions
> > * Update computation of min scratch buffer size requirement for V8 onwards
> Smitha, do you have any updates on this?  IIRC, there were few things
> which needed corrections but we were rather close to the final version.
> 
> --
> Thanks,
> Sylwester
> 
Hi Sylwester,

Sorry, I am currently held up with some other work. I will try to make
time and work on the next the updated patch series soon.

Regards,
Smitha



Re: [Patch v4 00/12] Add MFC v10.10 support

2017-06-12 Thread Smitha T Murthy
On Fri, 2017-06-09 at 19:36 +0200, Sylwester Nawrocki wrote:
> On 04/06/2017 08:11 AM, Smitha T Murthy wrote:
> > This patch series adds MFC v10.10 support. MFC v10.10 is used in some
> > of Exynos7 variants.
> > 
> > This adds support for following:
> > 
> > * Add support for HEVC encoder and decoder
> > * Add support for VP9 decoder
> > * Update Documentation for control id definitions
> > * Update computation of min scratch buffer size requirement for V8 onwards
> Smitha, do you have any updates on this?  IIRC, there were few things
> which needed corrections but we were rather close to the final version.
> 
> --
> Thanks,
> Sylwester
> 
Hi Sylwester,

Sorry, I am currently held up with some other work. I will try to make
time and work on the next the updated patch series soon.

Regards,
Smitha



[QUESTION] v4.12-rc5 BFQ enabled but unavailable?

2017-06-12 Thread vcaputo
Hello LKML,

Attempted to play with BFQ but after building with CONFIG_IOSCHED_BFQ=y I'm
still not seeing it:
 # cat 
/sys/devices/pci:00/:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda/queue/scheduler
 noop deadline [cfq] 
 # 

Even though:
 # dmesg | grep sched
 [0.514536] io scheduler noop registered
 [0.514537] io scheduler deadline registered
 [0.514577] io scheduler cfq registered (default)
 [0.514613] io scheduler bfq registered
 #

Quick glance at block/elevator.c elv_iosched_show() reveals:
 1125 list_for_each_entry(__e, _list, list) {
 1126 if (elv && !strcmp(elv->elevator_name, 
__e->elevator_name)) {
 1127 len += sprintf(name+len, "[%s] ", 
elv->elevator_name);
 1128 continue;
 1129 }
 1130 if (__e->uses_mq && q->mq_ops && elv_support_iosched(q))
 1131 len += sprintf(name+len, "%s ", 
__e->elevator_name);
 1132 else if (!__e->uses_mq && !q->mq_ops)
 1133 len += sprintf(name+len, "%s ", 
__e->elevator_name);
 1134 }

iosched_bfq_mq.uses_mq is true, so it appears bfq can be silently omitted from
elv_iosched_show() output if !q->mq_ops || !elv_support_iosched(q).

What magic incantation is recommended to get this stuff working and how is a
user like myself expected to discover it without digging through the code?

I glanced through Documentation/block/bfq-iosched.txt, but mq isn't mentioned:
 $ grep -ic mq Documentation/block/bfq-iosched.txt 
 0
 $

There are use_blk_mq parameters for dm_mod and scsi_mod, defaulting to N:
 # cd /sys/module && find -iname '*mq*' -print -exec cat {} \;
 ./dm_mod/parameters/use_blk_mq
 N
 ./dm_mod/parameters/dm_mq_nr_hw_queues
 1
 ./dm_mod/parameters/dm_mq_queue_depth
 2048
 ./scsi_mod/parameters/use_blk_mq
 N
 #

Is one expected to force use_blk_mq manually to make BFQ available?

Any advice appreciated, thanks!

Regards,
Vito Caputo


[QUESTION] v4.12-rc5 BFQ enabled but unavailable?

2017-06-12 Thread vcaputo
Hello LKML,

Attempted to play with BFQ but after building with CONFIG_IOSCHED_BFQ=y I'm
still not seeing it:
 # cat 
/sys/devices/pci:00/:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda/queue/scheduler
 noop deadline [cfq] 
 # 

Even though:
 # dmesg | grep sched
 [0.514536] io scheduler noop registered
 [0.514537] io scheduler deadline registered
 [0.514577] io scheduler cfq registered (default)
 [0.514613] io scheduler bfq registered
 #

Quick glance at block/elevator.c elv_iosched_show() reveals:
 1125 list_for_each_entry(__e, _list, list) {
 1126 if (elv && !strcmp(elv->elevator_name, 
__e->elevator_name)) {
 1127 len += sprintf(name+len, "[%s] ", 
elv->elevator_name);
 1128 continue;
 1129 }
 1130 if (__e->uses_mq && q->mq_ops && elv_support_iosched(q))
 1131 len += sprintf(name+len, "%s ", 
__e->elevator_name);
 1132 else if (!__e->uses_mq && !q->mq_ops)
 1133 len += sprintf(name+len, "%s ", 
__e->elevator_name);
 1134 }

iosched_bfq_mq.uses_mq is true, so it appears bfq can be silently omitted from
elv_iosched_show() output if !q->mq_ops || !elv_support_iosched(q).

What magic incantation is recommended to get this stuff working and how is a
user like myself expected to discover it without digging through the code?

I glanced through Documentation/block/bfq-iosched.txt, but mq isn't mentioned:
 $ grep -ic mq Documentation/block/bfq-iosched.txt 
 0
 $

There are use_blk_mq parameters for dm_mod and scsi_mod, defaulting to N:
 # cd /sys/module && find -iname '*mq*' -print -exec cat {} \;
 ./dm_mod/parameters/use_blk_mq
 N
 ./dm_mod/parameters/dm_mq_nr_hw_queues
 1
 ./dm_mod/parameters/dm_mq_queue_depth
 2048
 ./scsi_mod/parameters/use_blk_mq
 N
 #

Is one expected to force use_blk_mq manually to make BFQ available?

Any advice appreciated, thanks!

Regards,
Vito Caputo


Re: Subject: linux-next: build failure after merge of the sound-current tree

2017-06-12 Thread Takashi Iwai
On Tue, 13 Jun 2017 01:49:45 +0200,
Stephen Rothwell wrote:
> 
> Hi Takashi,
> 
> After merging the sound-current tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
> 
> sound/synth/emux/emux.c: In function 'snd_emux_new':
> sound/synth/emux/emux.c:51:5: error: 'struct snd_emux' has no member named 
> 'oss_synth'

My bad, some devel branch sneaked in to for-linus branch
accidentally.  Now it's backed out.

Something went wrong in my script recently.  I need to tune it again.
Sorry for inconvenience.


Takashi


Re: Subject: linux-next: build failure after merge of the sound-current tree

2017-06-12 Thread Takashi Iwai
On Tue, 13 Jun 2017 01:49:45 +0200,
Stephen Rothwell wrote:
> 
> Hi Takashi,
> 
> After merging the sound-current tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
> 
> sound/synth/emux/emux.c: In function 'snd_emux_new':
> sound/synth/emux/emux.c:51:5: error: 'struct snd_emux' has no member named 
> 'oss_synth'

My bad, some devel branch sneaked in to for-linus branch
accidentally.  Now it's backed out.

Something went wrong in my script recently.  I need to tune it again.
Sorry for inconvenience.


Takashi


Re: [PATCH linux-next v4 2/4] spi: imx: add selection for iMX53 and iMX6 controller

2017-06-12 Thread Jiada Wang

Hello Rob

On 06/13/2017 12:53 AM, Rob Herring wrote:

On Thu, Jun 08, 2017 at 02:16:01PM +0900, Jiada Wang wrote:

ECSPI contorller for iMX53 and iMX6 has few hardware issues
comparing to iMX51.
The change add possibility to detect which controller is used
to apply possible workaround and limitations.

Signed-off-by: Jiada Wang 
---
 .../devicetree/bindings/spi/fsl-imx-cspi.txt   |  1 +
 drivers/spi/spi-imx.c  | 26 --
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt 
b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
index 31b5b21..5bf1396 100644
--- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
+++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
@@ -9,6 +9,7 @@ Required properties:
   - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31
   - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35
   - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51
+  - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and 
later Soc
 - reg : Offset and length of the register set for the device
 - interrupts : Should contain CSPI/eCSPI interrupt
 - cs-gpios : Specifies the gpio pins to be used for chipselects.
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 4469121..8e6f339 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -63,7 +63,8 @@ enum spi_imx_devtype {
IMX27_CSPI,
IMX31_CSPI,
IMX35_CSPI, /* CSPI on all i.mx except above */
-   IMX51_ECSPI,/* ECSPI on i.mx51 and later */
+   IMX51_ECSPI,/* ECSPI on i.mx51 */
+   IMX53_ECSPI,/* ECSPI on i.mx53 and later */


Looks like i.MX51 and i.MX53 are the same. While the DT should have
different compatibles (with fallbacks), the driver should map them to
the same type until there's some difference found.


the difference between i.MX51 and i.MX53 is introduced in the
4th patch "spi: imx: Add support for SPI Slave mode" in this patch set

do you think, I need to merge the two patches into one?

Thanks,
Jiada


Rob



Re: [PATCH linux-next v4 2/4] spi: imx: add selection for iMX53 and iMX6 controller

2017-06-12 Thread Jiada Wang

Hello Rob

On 06/13/2017 12:53 AM, Rob Herring wrote:

On Thu, Jun 08, 2017 at 02:16:01PM +0900, Jiada Wang wrote:

ECSPI contorller for iMX53 and iMX6 has few hardware issues
comparing to iMX51.
The change add possibility to detect which controller is used
to apply possible workaround and limitations.

Signed-off-by: Jiada Wang 
---
 .../devicetree/bindings/spi/fsl-imx-cspi.txt   |  1 +
 drivers/spi/spi-imx.c  | 26 --
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt 
b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
index 31b5b21..5bf1396 100644
--- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
+++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
@@ -9,6 +9,7 @@ Required properties:
   - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31
   - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35
   - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51
+  - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and 
later Soc
 - reg : Offset and length of the register set for the device
 - interrupts : Should contain CSPI/eCSPI interrupt
 - cs-gpios : Specifies the gpio pins to be used for chipselects.
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 4469121..8e6f339 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -63,7 +63,8 @@ enum spi_imx_devtype {
IMX27_CSPI,
IMX31_CSPI,
IMX35_CSPI, /* CSPI on all i.mx except above */
-   IMX51_ECSPI,/* ECSPI on i.mx51 and later */
+   IMX51_ECSPI,/* ECSPI on i.mx51 */
+   IMX53_ECSPI,/* ECSPI on i.mx53 and later */


Looks like i.MX51 and i.MX53 are the same. While the DT should have
different compatibles (with fallbacks), the driver should map them to
the same type until there's some difference found.


the difference between i.MX51 and i.MX53 is introduced in the
4th patch "spi: imx: Add support for SPI Slave mode" in this patch set

do you think, I need to merge the two patches into one?

Thanks,
Jiada


Rob



[PATCH v2 4/4] arm64: dts: rockchip: use cs-gpios for cros_ec_spi

2017-06-12 Thread Jeffy Chen
The cros_ec requires CS line to be active after last message. But the CS
would be toggled when powering off/on rockchip spi, which breaks ec xfer.
Use GPIO CS to prevent that.

Signed-off-by: Jeffy Chen 
---

Changes in v2:
Fix wrong pinconf for spi5_cs0.

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index eb50593..b34a51d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -790,6 +790,8 @@ ap_i2c_audio:  {
  {
status = "okay";
 
+   cs-gpios = < 23 GPIO_ACTIVE_HIGH>;
+
cros_ec: ec@0 {
compatible = "google,cros-ec-spi";
reg = <0>;
@@ -813,6 +815,10 @@ ap_i2c_audio:  {
};
 };
 
+_cs0 {
+   rockchip,pins = ;
+};
+
  {
status = "okay";
 
-- 
2.1.4




[PATCH v2 4/4] arm64: dts: rockchip: use cs-gpios for cros_ec_spi

2017-06-12 Thread Jeffy Chen
The cros_ec requires CS line to be active after last message. But the CS
would be toggled when powering off/on rockchip spi, which breaks ec xfer.
Use GPIO CS to prevent that.

Signed-off-by: Jeffy Chen 
---

Changes in v2:
Fix wrong pinconf for spi5_cs0.

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index eb50593..b34a51d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -790,6 +790,8 @@ ap_i2c_audio:  {
  {
status = "okay";
 
+   cs-gpios = < 23 GPIO_ACTIVE_HIGH>;
+
cros_ec: ec@0 {
compatible = "google,cros-ec-spi";
reg = <0>;
@@ -813,6 +815,10 @@ ap_i2c_audio:  {
};
 };
 
+_cs0 {
+   rockchip,pins = ;
+};
+
  {
status = "okay";
 
-- 
2.1.4




[PATCH v2 3/4] dt-bindings: spi/rockchip: add "cs-gpios" optional property

2017-06-12 Thread Jeffy Chen
Update document devicetree bindings to support "cs-gpios" property.

Signed-off-by: Jeffy Chen 
---

Changes in v2: None

 Documentation/devicetree/bindings/spi/spi-rockchip.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt 
b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
index 83da493..d0be2e6 100644
--- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt
+++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
@@ -25,6 +25,7 @@ Required Properties:
 
 Optional Properties:
 
+- cs-gpios : Specifies the gpio pins to be used for chipselects.
 - dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
 - dma-names: DMA request names should include "tx" and "rx" if present.
@@ -48,6 +49,7 @@ Example:
#address-cells = <1>;
#size-cells = <0>;
interrupts = ;
+   cs-gpios = < 23 GPIO_ACTIVE_HIGH>;
clocks = < SCLK_SPI0>, < PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk";
pinctrl-0 = <_pins>;
-- 
2.1.4




[PATCH v2 2/4] spi: rockchip: add support for "cs-gpios" dts property

2017-06-12 Thread Jeffy Chen
Support using "cs-gpios" property to specify cs gpios.

Signed-off-by: Jeffy Chen 
1/ request cs gpios in probe for better error handling
2/ use gpiod* function
(suggested by Heiko Stuebner)

3/ split dt-binding changes to new patch
(suggested by Shawn Lin & Heiko Stuebner)

---

Changes in v2: None

 drivers/spi/spi-rockchip.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index bab9b13..ad8997b 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -663,6 +663,27 @@ static bool rockchip_spi_can_dma(struct spi_master *master,
return (xfer->len > rs->fifo_len);
 }
 
+static int rockchip_spi_setup_cs_gpios(struct device *dev)
+{
+   struct device_node *np = dev->of_node;
+   struct gpio_desc *cs_gpio;
+   int i, nb;
+
+   if (!np)
+   return 0;
+
+   nb = of_gpio_named_count(np, "cs-gpios");
+   for (i = 0; i < nb; i++) {
+   /* We support both GPIO CS and HW CS */
+   cs_gpio = devm_gpiod_get_index_optional(dev, "cs",
+   i, GPIOD_ASIS);
+   if (IS_ERR(cs_gpio))
+   return PTR_ERR(cs_gpio);
+   }
+
+   return 0;
+}
+
 static int rockchip_spi_probe(struct platform_device *pdev)
 {
int ret = 0;
@@ -749,6 +770,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
master->transfer_one = rockchip_spi_transfer_one;
master->max_transfer_size = rockchip_spi_max_transfer_size;
master->handle_err = rockchip_spi_handle_err;
+   master->flags = SPI_MASTER_GPIO_SS;
 
rs->dma_tx.ch = dma_request_chan(rs->dev, "tx");
if (IS_ERR(rs->dma_tx.ch)) {
@@ -783,6 +805,12 @@ static int rockchip_spi_probe(struct platform_device *pdev)
master->dma_rx = rs->dma_rx.ch;
}
 
+   ret = rockchip_spi_setup_cs_gpios(>dev);
+   if (ret) {
+   dev_err(>dev, "Failed to setup cs gpios\n");
+   goto err_free_dma_rx;
+   }
+
ret = devm_spi_register_master(>dev, master);
if (ret) {
dev_err(>dev, "Failed to register master\n");
-- 
2.1.4




[PATCH v2 3/4] dt-bindings: spi/rockchip: add "cs-gpios" optional property

2017-06-12 Thread Jeffy Chen
Update document devicetree bindings to support "cs-gpios" property.

Signed-off-by: Jeffy Chen 
---

Changes in v2: None

 Documentation/devicetree/bindings/spi/spi-rockchip.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt 
b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
index 83da493..d0be2e6 100644
--- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt
+++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
@@ -25,6 +25,7 @@ Required Properties:
 
 Optional Properties:
 
+- cs-gpios : Specifies the gpio pins to be used for chipselects.
 - dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
 - dma-names: DMA request names should include "tx" and "rx" if present.
@@ -48,6 +49,7 @@ Example:
#address-cells = <1>;
#size-cells = <0>;
interrupts = ;
+   cs-gpios = < 23 GPIO_ACTIVE_HIGH>;
clocks = < SCLK_SPI0>, < PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk";
pinctrl-0 = <_pins>;
-- 
2.1.4




[PATCH v2 2/4] spi: rockchip: add support for "cs-gpios" dts property

2017-06-12 Thread Jeffy Chen
Support using "cs-gpios" property to specify cs gpios.

Signed-off-by: Jeffy Chen 
1/ request cs gpios in probe for better error handling
2/ use gpiod* function
(suggested by Heiko Stuebner)

3/ split dt-binding changes to new patch
(suggested by Shawn Lin & Heiko Stuebner)

---

Changes in v2: None

 drivers/spi/spi-rockchip.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index bab9b13..ad8997b 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -663,6 +663,27 @@ static bool rockchip_spi_can_dma(struct spi_master *master,
return (xfer->len > rs->fifo_len);
 }
 
+static int rockchip_spi_setup_cs_gpios(struct device *dev)
+{
+   struct device_node *np = dev->of_node;
+   struct gpio_desc *cs_gpio;
+   int i, nb;
+
+   if (!np)
+   return 0;
+
+   nb = of_gpio_named_count(np, "cs-gpios");
+   for (i = 0; i < nb; i++) {
+   /* We support both GPIO CS and HW CS */
+   cs_gpio = devm_gpiod_get_index_optional(dev, "cs",
+   i, GPIOD_ASIS);
+   if (IS_ERR(cs_gpio))
+   return PTR_ERR(cs_gpio);
+   }
+
+   return 0;
+}
+
 static int rockchip_spi_probe(struct platform_device *pdev)
 {
int ret = 0;
@@ -749,6 +770,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
master->transfer_one = rockchip_spi_transfer_one;
master->max_transfer_size = rockchip_spi_max_transfer_size;
master->handle_err = rockchip_spi_handle_err;
+   master->flags = SPI_MASTER_GPIO_SS;
 
rs->dma_tx.ch = dma_request_chan(rs->dev, "tx");
if (IS_ERR(rs->dma_tx.ch)) {
@@ -783,6 +805,12 @@ static int rockchip_spi_probe(struct platform_device *pdev)
master->dma_rx = rs->dma_rx.ch;
}
 
+   ret = rockchip_spi_setup_cs_gpios(>dev);
+   if (ret) {
+   dev_err(>dev, "Failed to setup cs gpios\n");
+   goto err_free_dma_rx;
+   }
+
ret = devm_spi_register_master(>dev, master);
if (ret) {
dev_err(>dev, "Failed to register master\n");
-- 
2.1.4




[PATCH v2 1/4] spi: rockchip: fix error handling when probe

2017-06-12 Thread Jeffy Chen
After failed to request dma tx chain, we need to disable pm_runtime.
Also cleanup error labels for better readability.

Signed-off-by: Jeffy Chen 
---

Changes in v2: None

 drivers/spi/spi-rockchip.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index acf31f3..bab9b13 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -684,33 +684,33 @@ static int rockchip_spi_probe(struct platform_device 
*pdev)
rs->regs = devm_ioremap_resource(>dev, mem);
if (IS_ERR(rs->regs)) {
ret =  PTR_ERR(rs->regs);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
rs->apb_pclk = devm_clk_get(>dev, "apb_pclk");
if (IS_ERR(rs->apb_pclk)) {
dev_err(>dev, "Failed to get apb_pclk\n");
ret = PTR_ERR(rs->apb_pclk);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
rs->spiclk = devm_clk_get(>dev, "spiclk");
if (IS_ERR(rs->spiclk)) {
dev_err(>dev, "Failed to get spi_pclk\n");
ret = PTR_ERR(rs->spiclk);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
ret = clk_prepare_enable(rs->apb_pclk);
if (ret) {
dev_err(>dev, "Failed to enable apb_pclk\n");
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
ret = clk_prepare_enable(rs->spiclk);
if (ret) {
dev_err(>dev, "Failed to enable spi_clk\n");
-   goto err_spiclk_enable;
+   goto err_disable_apbclk;
}
 
spi_enable_chip(rs, 0);
@@ -728,7 +728,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
if (!rs->fifo_len) {
dev_err(>dev, "Failed to get fifo length\n");
ret = -EINVAL;
-   goto err_get_fifo_len;
+   goto err_disable_spiclk;
}
 
spin_lock_init(>lock);
@@ -755,7 +755,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
/* Check tx to see if we need defer probing driver */
if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
-   goto err_get_fifo_len;
+   goto err_disable_pm_runtime;
}
dev_warn(rs->dev, "Failed to request TX DMA channel\n");
rs->dma_tx.ch = NULL;
@@ -786,23 +786,24 @@ static int rockchip_spi_probe(struct platform_device 
*pdev)
ret = devm_spi_register_master(>dev, master);
if (ret) {
dev_err(>dev, "Failed to register master\n");
-   goto err_register_master;
+   goto err_free_dma_rx;
}
 
return 0;
 
-err_register_master:
-   pm_runtime_disable(>dev);
+err_free_dma_rx:
if (rs->dma_rx.ch)
dma_release_channel(rs->dma_rx.ch);
 err_free_dma_tx:
if (rs->dma_tx.ch)
dma_release_channel(rs->dma_tx.ch);
-err_get_fifo_len:
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
+err_disable_spiclk:
clk_disable_unprepare(rs->spiclk);
-err_spiclk_enable:
+err_disable_apbclk:
clk_disable_unprepare(rs->apb_pclk);
-err_ioremap_resource:
+err_put_master:
spi_master_put(master);
 
return ret;
-- 
2.1.4




[PATCH v2 1/4] spi: rockchip: fix error handling when probe

2017-06-12 Thread Jeffy Chen
After failed to request dma tx chain, we need to disable pm_runtime.
Also cleanup error labels for better readability.

Signed-off-by: Jeffy Chen 
---

Changes in v2: None

 drivers/spi/spi-rockchip.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index acf31f3..bab9b13 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -684,33 +684,33 @@ static int rockchip_spi_probe(struct platform_device 
*pdev)
rs->regs = devm_ioremap_resource(>dev, mem);
if (IS_ERR(rs->regs)) {
ret =  PTR_ERR(rs->regs);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
rs->apb_pclk = devm_clk_get(>dev, "apb_pclk");
if (IS_ERR(rs->apb_pclk)) {
dev_err(>dev, "Failed to get apb_pclk\n");
ret = PTR_ERR(rs->apb_pclk);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
rs->spiclk = devm_clk_get(>dev, "spiclk");
if (IS_ERR(rs->spiclk)) {
dev_err(>dev, "Failed to get spi_pclk\n");
ret = PTR_ERR(rs->spiclk);
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
ret = clk_prepare_enable(rs->apb_pclk);
if (ret) {
dev_err(>dev, "Failed to enable apb_pclk\n");
-   goto err_ioremap_resource;
+   goto err_put_master;
}
 
ret = clk_prepare_enable(rs->spiclk);
if (ret) {
dev_err(>dev, "Failed to enable spi_clk\n");
-   goto err_spiclk_enable;
+   goto err_disable_apbclk;
}
 
spi_enable_chip(rs, 0);
@@ -728,7 +728,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
if (!rs->fifo_len) {
dev_err(>dev, "Failed to get fifo length\n");
ret = -EINVAL;
-   goto err_get_fifo_len;
+   goto err_disable_spiclk;
}
 
spin_lock_init(>lock);
@@ -755,7 +755,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
/* Check tx to see if we need defer probing driver */
if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
-   goto err_get_fifo_len;
+   goto err_disable_pm_runtime;
}
dev_warn(rs->dev, "Failed to request TX DMA channel\n");
rs->dma_tx.ch = NULL;
@@ -786,23 +786,24 @@ static int rockchip_spi_probe(struct platform_device 
*pdev)
ret = devm_spi_register_master(>dev, master);
if (ret) {
dev_err(>dev, "Failed to register master\n");
-   goto err_register_master;
+   goto err_free_dma_rx;
}
 
return 0;
 
-err_register_master:
-   pm_runtime_disable(>dev);
+err_free_dma_rx:
if (rs->dma_rx.ch)
dma_release_channel(rs->dma_rx.ch);
 err_free_dma_tx:
if (rs->dma_tx.ch)
dma_release_channel(rs->dma_tx.ch);
-err_get_fifo_len:
+err_disable_pm_runtime:
+   pm_runtime_disable(>dev);
+err_disable_spiclk:
clk_disable_unprepare(rs->spiclk);
-err_spiclk_enable:
+err_disable_apbclk:
clk_disable_unprepare(rs->apb_pclk);
-err_ioremap_resource:
+err_put_master:
spi_master_put(master);
 
return ret;
-- 
2.1.4




Re: [PATCH v6 4/6] clk: qcom: Add ipq8074 Global Clock Controller support

2017-06-12 Thread Varadarajan Narayanan

Stephen,

On 6/9/2017 3:11 PM, Varadarajan Narayanan wrote:

From: Abhishek Sahu 

This patch adds support for the global clock controller found on
the ipq8074 based devices. This includes UART, I2C, SPI etc.

Signed-off-by: Abhishek Sahu 
Signed-off-by: Varadarajan Narayanan 
---
  drivers/clk/qcom/Kconfig   |9 +
  drivers/clk/qcom/Makefile  |1 +
  drivers/clk/qcom/gcc-ipq8074.c | 1007 
  3 files changed, 1017 insertions(+)
  create mode 100644 drivers/clk/qcom/gcc-ipq8074.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 5fb8d74..9f6c278 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -82,6 +82,15 @@ config IPQ_LCC_806X
  Say Y if you want to use audio devices such as i2s, pcm,
  S/PDIF, etc.
  
+config IPQ_GCC_8074

+   tristate "IPQ8074 Global Clock Controller"
+   depends on COMMON_CLK_QCOM
+   help
+ Support for global clock controller on ipq8074 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2c, USB, SD/eMMC, etc. Select this for the root clock
+ of ipq8074.
+
  config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1c3e222..3f3aff2 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
  obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
  obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
  obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
+obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
  obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
  obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
  obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
new file mode 100644
index 000..0f735d3
--- /dev/null
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_XO,
+   P_GPLL0,
+   P_GPLL0_DIV2,
+};
+
+static const char * const gcc_xo_gpll0_gpll0_out_main_div2[] = {
+   "xo",
+   "gpll0",
+   "gpll0_out_main_div2",
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 1 },
+   { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_alpha_pll gpll0_main = {
+   .offset = 0x21000,
+   .clkr = {
+   .enable_reg = 0x0b000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gpll0_main",
+   .parent_names = (const char *[]){
+   "xo"
+   },
+   .num_parents = 1,
+   .ops = _alpha_pll_ops,
+   },
+   },
+};
+
+static struct clk_fixed_factor gpll0_out_main_div2 = {
+   .mult = 1,
+   .div = 2,
+   .hw.init = &(struct clk_init_data){
+   .name = "gpll0_out_main_div2",
+   .parent_names = (const char *[]){
+   "gpll0_main"
+   },
+   .num_parents = 1,
+   .ops = _fixed_factor_ops,
+   .flags = CLK_SET_RATE_PARENT,
+   },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+   .offset = 0x21000,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gpll0",
+   .parent_names = (const char *[]){
+   "gpll0_main"
+   },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_ops,
+   },
+};
+
+static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = {
+   F(1920, P_XO, 1, 0, 0),
+   F(5000, P_GPLL0, 16, 0, 0),
+   F(1, P_GPLL0, 8, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+   .cmd_rcgr = 0x27000,
+   .freq_tbl = ftbl_pcnoc_bfdcd_clk_src,
+   .hid_width = 5,
+   .parent_map = 

Re: [PATCH v6 4/6] clk: qcom: Add ipq8074 Global Clock Controller support

2017-06-12 Thread Varadarajan Narayanan

Stephen,

On 6/9/2017 3:11 PM, Varadarajan Narayanan wrote:

From: Abhishek Sahu 

This patch adds support for the global clock controller found on
the ipq8074 based devices. This includes UART, I2C, SPI etc.

Signed-off-by: Abhishek Sahu 
Signed-off-by: Varadarajan Narayanan 
---
  drivers/clk/qcom/Kconfig   |9 +
  drivers/clk/qcom/Makefile  |1 +
  drivers/clk/qcom/gcc-ipq8074.c | 1007 
  3 files changed, 1017 insertions(+)
  create mode 100644 drivers/clk/qcom/gcc-ipq8074.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 5fb8d74..9f6c278 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -82,6 +82,15 @@ config IPQ_LCC_806X
  Say Y if you want to use audio devices such as i2s, pcm,
  S/PDIF, etc.
  
+config IPQ_GCC_8074

+   tristate "IPQ8074 Global Clock Controller"
+   depends on COMMON_CLK_QCOM
+   help
+ Support for global clock controller on ipq8074 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2c, USB, SD/eMMC, etc. Select this for the root clock
+ of ipq8074.
+
  config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1c3e222..3f3aff2 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
  obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
  obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
  obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
+obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
  obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
  obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
  obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
new file mode 100644
index 000..0f735d3
--- /dev/null
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_XO,
+   P_GPLL0,
+   P_GPLL0_DIV2,
+};
+
+static const char * const gcc_xo_gpll0_gpll0_out_main_div2[] = {
+   "xo",
+   "gpll0",
+   "gpll0_out_main_div2",
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 1 },
+   { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_alpha_pll gpll0_main = {
+   .offset = 0x21000,
+   .clkr = {
+   .enable_reg = 0x0b000,
+   .enable_mask = BIT(0),
+   .hw.init = &(struct clk_init_data){
+   .name = "gpll0_main",
+   .parent_names = (const char *[]){
+   "xo"
+   },
+   .num_parents = 1,
+   .ops = _alpha_pll_ops,
+   },
+   },
+};
+
+static struct clk_fixed_factor gpll0_out_main_div2 = {
+   .mult = 1,
+   .div = 2,
+   .hw.init = &(struct clk_init_data){
+   .name = "gpll0_out_main_div2",
+   .parent_names = (const char *[]){
+   "gpll0_main"
+   },
+   .num_parents = 1,
+   .ops = _fixed_factor_ops,
+   .flags = CLK_SET_RATE_PARENT,
+   },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+   .offset = 0x21000,
+   .clkr.hw.init = &(struct clk_init_data){
+   .name = "gpll0",
+   .parent_names = (const char *[]){
+   "gpll0_main"
+   },
+   .num_parents = 1,
+   .ops = _alpha_pll_postdiv_ops,
+   },
+};
+
+static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = {
+   F(1920, P_XO, 1, 0, 0),
+   F(5000, P_GPLL0, 16, 0, 0),
+   F(1, P_GPLL0, 8, 0, 0),
+   { }
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+   .cmd_rcgr = 0x27000,
+   .freq_tbl = ftbl_pcnoc_bfdcd_clk_src,
+   .hid_width = 5,
+   .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+   .clkr.hw.init = &(struct 

Re: [PATCH v6 1/6] pinctrl: qcom: Add ipq8074 pinctrl driver

2017-06-12 Thread Varadarajan Narayanan

Bjorn,

On 6/9/2017 3:11 PM, Varadarajan Narayanan wrote:

Add initial pinctrl driver to support pin configuration with
pinctrl framework for ipq8074.

Acked-by: Rob Herring  (bindings)
Signed-off-by: Manoharan Vijaya Raghavan 
Signed-off-by: Varadarajan Narayanan 
---
  .../bindings/pinctrl/qcom,ipq8074-pinctrl.txt  |  172 
  drivers/pinctrl/qcom/Kconfig   |   10 +
  drivers/pinctrl/qcom/Makefile  |1 +
  drivers/pinctrl/qcom/pinctrl-ipq8074.c | 1076 
  4 files changed, 1259 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
  create mode 100644 drivers/pinctrl/qcom/pinctrl-ipq8074.c

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
new file mode 100644
index 000..407b944
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. IPQ8074 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+IPQ8074 platform.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be "qcom,ipq8074-pinctrl"
+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+   Usage: required
+   Value type: 
+   Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+- gpio-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+   Usage: required
+   Value type: 
+   Definition: List of gpio pins affected by the properties specified in
+   this subnode.  Valid pins are:
+   gpio0-gpio69
+
+- function:
+   Usage: required
+   Value type: 
+   Definition: Specify the alternative function to be configured for the
+   specified pins. Functions are only valid for gpio pins.
+   Valid values are:
+   atest_char, atest_char0, atest_char1, atest_char2,
+   atest_char3, audio_rxbclk, audio_rxd, audio_rxfsync,
+   audio_rxmclk, audio_txbclk, audio_txd, audio_txfsync,
+   audio_txmclk, blsp0_i2c, blsp0_spi, blsp0_uart, blsp1_i2c,
+   blsp1_spi, blsp1_uart, blsp2_i2c, blsp2_spi, blsp2_uart,
+   blsp3_i2c, blsp3_spi, blsp3_spi0, blsp3_spi1, blsp3_spi2,
+   blsp3_spi3, blsp3_uart, blsp4_i2c0, blsp4_i2c1, blsp4_spi0,
+   blsp4_spi1, blsp4_uart0, blsp4_uart1, blsp5_i2c, blsp5_spi,
+   blsp5_uart, burn0, burn1, cri_trng, cri_trng0, cri_trng1,
+   cxc0, cxc1, dbg_out, gcc_plltest, gcc_tlmm, gpio, ldo_en,
+   ldo_update, led0, led1, led2, mac0_sa0, mac0_sa1, mac1_sa0,
+   mac1_sa1, mac1_sa2, mac1_sa3, mac2_sa0, mac2_sa1, mdc,
+   mdio, pcie0_clk, pcie0_rst, pcie0_wake, pcie1_clk,
+

Re: [PATCH v6 1/6] pinctrl: qcom: Add ipq8074 pinctrl driver

2017-06-12 Thread Varadarajan Narayanan

Bjorn,

On 6/9/2017 3:11 PM, Varadarajan Narayanan wrote:

Add initial pinctrl driver to support pin configuration with
pinctrl framework for ipq8074.

Acked-by: Rob Herring  (bindings)
Signed-off-by: Manoharan Vijaya Raghavan 
Signed-off-by: Varadarajan Narayanan 
---
  .../bindings/pinctrl/qcom,ipq8074-pinctrl.txt  |  172 
  drivers/pinctrl/qcom/Kconfig   |   10 +
  drivers/pinctrl/qcom/Makefile  |1 +
  drivers/pinctrl/qcom/pinctrl-ipq8074.c | 1076 
  4 files changed, 1259 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
  create mode 100644 drivers/pinctrl/qcom/pinctrl-ipq8074.c

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
new file mode 100644
index 000..407b944
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.txt
@@ -0,0 +1,172 @@
+Qualcomm Technologies, Inc. IPQ8074 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+IPQ8074 platform.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be "qcom,ipq8074-pinctrl"
+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+   Usage: required
+   Value type: 
+   Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+- gpio-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+   Usage: required
+   Value type: 
+   Definition: List of gpio pins affected by the properties specified in
+   this subnode.  Valid pins are:
+   gpio0-gpio69
+
+- function:
+   Usage: required
+   Value type: 
+   Definition: Specify the alternative function to be configured for the
+   specified pins. Functions are only valid for gpio pins.
+   Valid values are:
+   atest_char, atest_char0, atest_char1, atest_char2,
+   atest_char3, audio_rxbclk, audio_rxd, audio_rxfsync,
+   audio_rxmclk, audio_txbclk, audio_txd, audio_txfsync,
+   audio_txmclk, blsp0_i2c, blsp0_spi, blsp0_uart, blsp1_i2c,
+   blsp1_spi, blsp1_uart, blsp2_i2c, blsp2_spi, blsp2_uart,
+   blsp3_i2c, blsp3_spi, blsp3_spi0, blsp3_spi1, blsp3_spi2,
+   blsp3_spi3, blsp3_uart, blsp4_i2c0, blsp4_i2c1, blsp4_spi0,
+   blsp4_spi1, blsp4_uart0, blsp4_uart1, blsp5_i2c, blsp5_spi,
+   blsp5_uart, burn0, burn1, cri_trng, cri_trng0, cri_trng1,
+   cxc0, cxc1, dbg_out, gcc_plltest, gcc_tlmm, gpio, ldo_en,
+   ldo_update, led0, led1, led2, mac0_sa0, mac0_sa1, mac1_sa0,
+   mac1_sa1, mac1_sa2, mac1_sa3, mac2_sa0, mac2_sa1, mdc,
+   mdio, pcie0_clk, pcie0_rst, pcie0_wake, pcie1_clk,
+   pcie1_rst, pcie1_wake, pcm_drx, pcm_dtx, pcm_fsync,
+ 

Re: posix timer: general protection fault in cleanup_timers

2017-06-12 Thread Dmitry Vyukov
On Tue, Jun 13, 2017 at 4:27 AM,   wrote:
> Update:  got another reproducible KASAN report on commit
> 32c1431eea4881a6b17bd7c639315010aeefa452(4.12-rc5) :

Hi,

If it's reproducible, please provide the reproducer.


> ==
> BUG: KASAN: use-after-free in cleanup_timers_list
> kernel/time/posix-cpu-timers.c:401 [inline]
> BUG: KASAN: use-after-free in cleanup_timers+0x35e/0x430
> kernel/time/posix-cpu-timers.c:415
> Read of size 8 at addr 88006c9229f0 by task syz-executor0/29927
>
> CPU: 2 PID: 29927 Comm: syz-executor0 Not tainted 4.12.0-rc5 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> Ubuntu-1.8.2-1ubuntu1 04/01/2014
> Call Trace:
>  __dump_stack lib/dump_stack.c:16 [inline]
>  dump_stack+0x83/0xbc lib/dump_stack.c:52
>  print_address_description+0x73/0x290 mm/kasan/report.c:252
>  kasan_report_error mm/kasan/report.c:351 [inline]
>  kasan_report+0x22b/0x340 mm/kasan/report.c:408
>  __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:429
>  cleanup_timers_list kernel/time/posix-cpu-timers.c:401 [inline]
>  cleanup_timers+0x35e/0x430 kernel/time/posix-cpu-timers.c:415
>  posix_cpu_timers_exit+0x19/0x20 kernel/time/posix-cpu-timers.c:425
>  __exit_signal kernel/exit.c:103 [inline]
>  release_task+0x1b7/0x12c0 kernel/exit.c:199
>  exit_notify kernel/exit.c:748 [inline]
>  do_exit+0x15ba/0x2c60 kernel/exit.c:900
>  do_group_exit+0xf6/0x340 kernel/exit.c:982
>  get_signal+0x5c2/0x11b0 kernel/signal.c:2318
>  do_signal+0x8d/0x19e0 arch/x86/kernel/signal.c:808
>  exit_to_usermode_loop+0xe5/0x130 arch/x86/entry/common.c:157
>  prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
>  syscall_return_slowpath+0xd6/0x100 arch/x86/entry/common.c:263
>  entry_SYSCALL_64_fastpath+0xa3/0xa5
> RIP: 0033:0x450439
> RSP: 002b:7fd78ca08cf8 EFLAGS: 0246 ORIG_RAX: 00ca
> RAX: fe00 RBX: 00718020 RCX: 00450439
> RDX:  RSI:  RDI: 00718020
> RBP: 00718000 R08:  R09: 
> R10:  R11: 0246 R12: 
> R13: 7ffe2264c6cf R14: 7fd78ca099c0 R15: 
>
> Allocated by task 29927:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x46/0xd0 mm/kasan/kasan.c:513
>  set_track mm/kasan/kasan.c:525 [inline]
>  kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:617
>  kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:555
>  slab_post_alloc_hook mm/slab.h:456 [inline]
>  slab_alloc_node mm/slub.c:2718 [inline]
>  slab_alloc mm/slub.c:2726 [inline]
>  kmem_cache_alloc+0xb9/0x180 mm/slub.c:2731
>  kmem_cache_zalloc include/linux/slab.h:655 [inline]
>  alloc_posix_timer kernel/time/posix-timers.c:551 [inline]
>  SYSC_timer_create kernel/time/posix-timers.c:618 [inline]
>  SyS_timer_create+0x167/0x1020 kernel/time/posix-timers.c:603
>  entry_SYSCALL_64_fastpath+0x1a/0xa5
>
> Freed by task 26611:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x46/0xd0 mm/kasan/kasan.c:513
>  set_track mm/kasan/kasan.c:525 [inline]
>  kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:590
>  slab_free_hook mm/slub.c:1357 [inline]
>  slab_free_freelist_hook mm/slub.c:1379 [inline]
>  slab_free mm/slub.c:2961 [inline]
>  kmem_cache_free+0x72/0x1a0 mm/slub.c:2983
>  k_itimer_rcu_free+0x1d/0x20 kernel/time/posix-timers.c:566
>  __rcu_reclaim kernel/rcu/rcu.h:195 [inline]
>  rcu_do_batch kernel/rcu/tree.c:2800 [inline]
>  invoke_rcu_callbacks kernel/rcu/tree.c:3057 [inline]
>  __rcu_process_callbacks kernel/rcu/tree.c:3024 [inline]
>  rcu_process_callbacks+0x3a4/0x1610 kernel/rcu/tree.c:3041
>  __do_softirq+0x1be/0x59c kernel/softirq.c:284
>
> The buggy address belongs to the object at 88006c922998
>  which belongs to the cache posix_timers_cache of size 216
> The buggy address is located 88 bytes inside of
>  216-byte region [88006c922998, 88006c922a70)
> The buggy address belongs to the page:
> page:ea0001b24800 count:1 mapcount:0 mapping:  (null)
> index:0x88006c920af8 compound_mapcount: 0
> flags: 0x5008100(slab|head)
> raw: 05008100  88006c920af8 0001001d0002
> raw: 88006c9f9850 88006c9f9850 88006d81aac0 
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
>  88006c922880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  88006c922900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>88006c922980: fc fc fc fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ^
>  88006c922a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc
>  88006c922a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ==
> Disabling lock debugging due to kernel taint
> Kernel panic - not syncing: 

Re: posix timer: general protection fault in cleanup_timers

2017-06-12 Thread Dmitry Vyukov
On Tue, Jun 13, 2017 at 4:27 AM,   wrote:
> Update:  got another reproducible KASAN report on commit
> 32c1431eea4881a6b17bd7c639315010aeefa452(4.12-rc5) :

Hi,

If it's reproducible, please provide the reproducer.


> ==
> BUG: KASAN: use-after-free in cleanup_timers_list
> kernel/time/posix-cpu-timers.c:401 [inline]
> BUG: KASAN: use-after-free in cleanup_timers+0x35e/0x430
> kernel/time/posix-cpu-timers.c:415
> Read of size 8 at addr 88006c9229f0 by task syz-executor0/29927
>
> CPU: 2 PID: 29927 Comm: syz-executor0 Not tainted 4.12.0-rc5 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> Ubuntu-1.8.2-1ubuntu1 04/01/2014
> Call Trace:
>  __dump_stack lib/dump_stack.c:16 [inline]
>  dump_stack+0x83/0xbc lib/dump_stack.c:52
>  print_address_description+0x73/0x290 mm/kasan/report.c:252
>  kasan_report_error mm/kasan/report.c:351 [inline]
>  kasan_report+0x22b/0x340 mm/kasan/report.c:408
>  __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:429
>  cleanup_timers_list kernel/time/posix-cpu-timers.c:401 [inline]
>  cleanup_timers+0x35e/0x430 kernel/time/posix-cpu-timers.c:415
>  posix_cpu_timers_exit+0x19/0x20 kernel/time/posix-cpu-timers.c:425
>  __exit_signal kernel/exit.c:103 [inline]
>  release_task+0x1b7/0x12c0 kernel/exit.c:199
>  exit_notify kernel/exit.c:748 [inline]
>  do_exit+0x15ba/0x2c60 kernel/exit.c:900
>  do_group_exit+0xf6/0x340 kernel/exit.c:982
>  get_signal+0x5c2/0x11b0 kernel/signal.c:2318
>  do_signal+0x8d/0x19e0 arch/x86/kernel/signal.c:808
>  exit_to_usermode_loop+0xe5/0x130 arch/x86/entry/common.c:157
>  prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
>  syscall_return_slowpath+0xd6/0x100 arch/x86/entry/common.c:263
>  entry_SYSCALL_64_fastpath+0xa3/0xa5
> RIP: 0033:0x450439
> RSP: 002b:7fd78ca08cf8 EFLAGS: 0246 ORIG_RAX: 00ca
> RAX: fe00 RBX: 00718020 RCX: 00450439
> RDX:  RSI:  RDI: 00718020
> RBP: 00718000 R08:  R09: 
> R10:  R11: 0246 R12: 
> R13: 7ffe2264c6cf R14: 7fd78ca099c0 R15: 
>
> Allocated by task 29927:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x46/0xd0 mm/kasan/kasan.c:513
>  set_track mm/kasan/kasan.c:525 [inline]
>  kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:617
>  kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:555
>  slab_post_alloc_hook mm/slab.h:456 [inline]
>  slab_alloc_node mm/slub.c:2718 [inline]
>  slab_alloc mm/slub.c:2726 [inline]
>  kmem_cache_alloc+0xb9/0x180 mm/slub.c:2731
>  kmem_cache_zalloc include/linux/slab.h:655 [inline]
>  alloc_posix_timer kernel/time/posix-timers.c:551 [inline]
>  SYSC_timer_create kernel/time/posix-timers.c:618 [inline]
>  SyS_timer_create+0x167/0x1020 kernel/time/posix-timers.c:603
>  entry_SYSCALL_64_fastpath+0x1a/0xa5
>
> Freed by task 26611:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x46/0xd0 mm/kasan/kasan.c:513
>  set_track mm/kasan/kasan.c:525 [inline]
>  kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:590
>  slab_free_hook mm/slub.c:1357 [inline]
>  slab_free_freelist_hook mm/slub.c:1379 [inline]
>  slab_free mm/slub.c:2961 [inline]
>  kmem_cache_free+0x72/0x1a0 mm/slub.c:2983
>  k_itimer_rcu_free+0x1d/0x20 kernel/time/posix-timers.c:566
>  __rcu_reclaim kernel/rcu/rcu.h:195 [inline]
>  rcu_do_batch kernel/rcu/tree.c:2800 [inline]
>  invoke_rcu_callbacks kernel/rcu/tree.c:3057 [inline]
>  __rcu_process_callbacks kernel/rcu/tree.c:3024 [inline]
>  rcu_process_callbacks+0x3a4/0x1610 kernel/rcu/tree.c:3041
>  __do_softirq+0x1be/0x59c kernel/softirq.c:284
>
> The buggy address belongs to the object at 88006c922998
>  which belongs to the cache posix_timers_cache of size 216
> The buggy address is located 88 bytes inside of
>  216-byte region [88006c922998, 88006c922a70)
> The buggy address belongs to the page:
> page:ea0001b24800 count:1 mapcount:0 mapping:  (null)
> index:0x88006c920af8 compound_mapcount: 0
> flags: 0x5008100(slab|head)
> raw: 05008100  88006c920af8 0001001d0002
> raw: 88006c9f9850 88006c9f9850 88006d81aac0 
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
>  88006c922880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  88006c922900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>88006c922980: fc fc fc fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ^
>  88006c922a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc
>  88006c922a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ==
> Disabling lock debugging due to kernel taint
> Kernel panic - not syncing: panic_on_warn set 

[PATCH v6 12/18] mtd: nand: denali: use flag instead of register macro for direction

2017-06-12 Thread Masahiro Yamada
It is not a good idea to re-use macros that represent a specific
register bit field for the transfer direction.

It is true that bit 8 indicates the direction for the MAP10 pipeline
operation and the data DMA operation, but this is not valid across
the IP.

Use a simple flag (write: 1, read: 0) for the direction.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Delete unused DENALI_{READ,WRITE}

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 36 +---
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index caf5ce64b185..03b75045d603 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -63,9 +63,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
 #define MAIN_ACCESS0x42
 #define MAIN_SPARE_ACCESS  0x43
 
-#define DENALI_READ0
-#define DENALI_WRITE   0x100
-
 /*
  * this is a helper macro that allows us to
  * format the bank into the proper bits for the controller
@@ -284,7 +281,7 @@ static int denali_dev_ready(struct mtd_info *mtd)
  */
 static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
bool ecc_en, bool transfer_spare,
-   int access_type, int op)
+   int access_type, int write)
 {
int status = PASS;
uint32_t addr, cmd;
@@ -295,17 +292,17 @@ static int denali_send_pipeline_cmd(struct 
denali_nand_info *denali, int page,
 
addr = BANK(denali->flash_bank) | page;
 
-   if (op == DENALI_WRITE && access_type != SPARE_ACCESS) {
+   if (write && access_type != SPARE_ACCESS) {
cmd = MODE_01 | addr;
iowrite32(cmd, denali->flash_mem);
-   } else if (op == DENALI_WRITE && access_type == SPARE_ACCESS) {
+   } else if (write && access_type == SPARE_ACCESS) {
/* read spare area */
cmd = MODE_10 | addr;
index_addr(denali, cmd, access_type);
 
cmd = MODE_01 | addr;
iowrite32(cmd, denali->flash_mem);
-   } else if (op == DENALI_READ) {
+   } else {
/* setup page read request for access type */
cmd = MODE_10 | addr;
index_addr(denali, cmd, access_type);
@@ -367,7 +364,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
int status = 0;
 
if (denali_send_pipeline_cmd(denali, page, false, false, SPARE_ACCESS,
-   DENALI_WRITE) == PASS) {
+   1) == PASS) {
write_data_to_flash_mem(denali, buf, mtd->oobsize);
 
/* wait for operation to complete */
@@ -392,7 +389,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_status, addr, cmd;
 
if (denali_send_pipeline_cmd(denali, page, false, true, SPARE_ACCESS,
-   DENALI_READ) == PASS) {
+   0) == PASS) {
read_data_from_flash_mem(denali, buf, mtd->oobsize);
 
/*
@@ -578,7 +575,7 @@ static void denali_enable_dma(struct denali_nand_info 
*denali, bool en)
 }
 
 static void denali_setup_dma64(struct denali_nand_info *denali,
-  dma_addr_t dma_addr, int page, int op)
+  dma_addr_t dma_addr, int page, int write)
 {
uint32_t mode;
const int page_count = 1;
@@ -591,7 +588,8 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali,
 * 1. setup transfer type, interrupt when complete,
 *burst len = 64 bytes, the number of pages
 */
-   index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count);
+   index_addr(denali, mode,
+  0x01002000 | (64 << 16) | (write << 8) | page_count);
 
/* 2. set memory low address */
index_addr(denali, mode, dma_addr);
@@ -601,7 +599,7 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali,
 }
 
 static void denali_setup_dma32(struct denali_nand_info *denali,
-  dma_addr_t dma_addr, int page, int op)
+  dma_addr_t dma_addr, int page, int write)
 {
uint32_t mode;
const int page_count = 1;
@@ -611,7 +609,7 @@ static void denali_setup_dma32(struct denali_nand_info 
*denali,
/* DMA is a four step process */
 
/* 1. setup transfer type and # of pages */
-   index_addr(denali, mode | page, 0x2000 | op | page_count);
+   index_addr(denali, mode | page, 0x2000 | (write << 8) | page_count);
 
/* 2. set memory high address bits 23:8 */
 

[PATCH v6 10/18] mtd: nand: denali: propagate page to helpers via function argument

2017-06-12 Thread Masahiro Yamada
This driver stores the currently addressed page into denali->page,
which is later read out by helper functions.  While I am tackling on
this driver, I often missed to insert "denali->page = page;" where
needed.  This makes page_read/write callbacks to get access to a
wrong page, which is a bug hard to figure out.

Instead, I'd rather pass the page via function argument because the
compiler's prototype checks will help to detect bugs.

For the same reason, propagate dma_addr to the DMA helpers instead
of denali->buf.dma_buf .

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 58 ---
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 7ae2fa65d601..f2e50c5856f3 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -282,7 +282,7 @@ static int denali_dev_ready(struct mtd_info *mtd)
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
  */
-static int denali_send_pipeline_cmd(struct denali_nand_info *denali,
+static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
bool ecc_en, bool transfer_spare,
int access_type, int op)
 {
@@ -293,7 +293,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info 
*denali,
 
denali_reset_irq(denali);
 
-   addr = BANK(denali->flash_bank) | denali->page;
+   addr = BANK(denali->flash_bank) | page;
 
if (op == DENALI_WRITE && access_type != SPARE_ACCESS) {
cmd = MODE_01 | addr;
@@ -366,9 +366,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_mask = INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL;
int status = 0;
 
-   denali->page = page;
-
-   if (denali_send_pipeline_cmd(denali, false, false, SPARE_ACCESS,
+   if (denali_send_pipeline_cmd(denali, page, false, false, SPARE_ACCESS,
DENALI_WRITE) == PASS) {
write_data_to_flash_mem(denali, buf, mtd->oobsize);
 
@@ -393,9 +391,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_mask = INTR__LOAD_COMP;
uint32_t irq_status, addr, cmd;
 
-   denali->page = page;
-
-   if (denali_send_pipeline_cmd(denali, false, true, SPARE_ACCESS,
+   if (denali_send_pipeline_cmd(denali, page, false, true, SPARE_ACCESS,
DENALI_READ) == PASS) {
read_data_from_flash_mem(denali, buf, mtd->oobsize);
 
@@ -407,8 +403,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
irq_status = denali_wait_for_irq(denali, irq_mask);
 
if (!(irq_status & INTR__LOAD_COMP))
-   dev_err(denali->dev, "page on OOB timeout %d\n",
-   denali->page);
+   dev_err(denali->dev, "page on OOB timeout %d\n", page);
 
/*
 * We set the device back to MAIN_ACCESS here as I observed
@@ -417,7 +412,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
 * is reliable (according to the MTD test infrastructure)
 * if you are in MAIN_ACCESS.
 */
-   addr = BANK(denali->flash_bank) | denali->page;
+   addr = BANK(denali->flash_bank) | page;
cmd = MODE_10 | addr;
index_addr(denali, cmd, MAIN_ACCESS);
}
@@ -582,13 +577,13 @@ static void denali_enable_dma(struct denali_nand_info 
*denali, bool en)
ioread32(denali->flash_reg + DMA_ENABLE);
 }
 
-static void denali_setup_dma64(struct denali_nand_info *denali, int op)
+static void denali_setup_dma64(struct denali_nand_info *denali,
+  dma_addr_t dma_addr, int page, int op)
 {
uint32_t mode;
const int page_count = 1;
-   uint64_t addr = denali->buf.dma_buf;
 
-   mode = MODE_10 | BANK(denali->flash_bank) | denali->page;
+   mode = MODE_10 | BANK(denali->flash_bank) | page;
 
/* DMA is a three step process */
 
@@ -599,41 +594,42 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali, int op)
index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count);
 
/* 2. set memory low address */
-   index_addr(denali, mode, addr);
+   index_addr(denali, mode, dma_addr);
 
/* 3. set memory high address */
-   index_addr(denali, mode, addr >> 32);
+   index_addr(denali, mode, (uint64_t)dma_addr >> 32);
 }
 
-static 

[PATCH v6 12/18] mtd: nand: denali: use flag instead of register macro for direction

2017-06-12 Thread Masahiro Yamada
It is not a good idea to re-use macros that represent a specific
register bit field for the transfer direction.

It is true that bit 8 indicates the direction for the MAP10 pipeline
operation and the data DMA operation, but this is not valid across
the IP.

Use a simple flag (write: 1, read: 0) for the direction.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Delete unused DENALI_{READ,WRITE}

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 36 +---
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index caf5ce64b185..03b75045d603 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -63,9 +63,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
 #define MAIN_ACCESS0x42
 #define MAIN_SPARE_ACCESS  0x43
 
-#define DENALI_READ0
-#define DENALI_WRITE   0x100
-
 /*
  * this is a helper macro that allows us to
  * format the bank into the proper bits for the controller
@@ -284,7 +281,7 @@ static int denali_dev_ready(struct mtd_info *mtd)
  */
 static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
bool ecc_en, bool transfer_spare,
-   int access_type, int op)
+   int access_type, int write)
 {
int status = PASS;
uint32_t addr, cmd;
@@ -295,17 +292,17 @@ static int denali_send_pipeline_cmd(struct 
denali_nand_info *denali, int page,
 
addr = BANK(denali->flash_bank) | page;
 
-   if (op == DENALI_WRITE && access_type != SPARE_ACCESS) {
+   if (write && access_type != SPARE_ACCESS) {
cmd = MODE_01 | addr;
iowrite32(cmd, denali->flash_mem);
-   } else if (op == DENALI_WRITE && access_type == SPARE_ACCESS) {
+   } else if (write && access_type == SPARE_ACCESS) {
/* read spare area */
cmd = MODE_10 | addr;
index_addr(denali, cmd, access_type);
 
cmd = MODE_01 | addr;
iowrite32(cmd, denali->flash_mem);
-   } else if (op == DENALI_READ) {
+   } else {
/* setup page read request for access type */
cmd = MODE_10 | addr;
index_addr(denali, cmd, access_type);
@@ -367,7 +364,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
int status = 0;
 
if (denali_send_pipeline_cmd(denali, page, false, false, SPARE_ACCESS,
-   DENALI_WRITE) == PASS) {
+   1) == PASS) {
write_data_to_flash_mem(denali, buf, mtd->oobsize);
 
/* wait for operation to complete */
@@ -392,7 +389,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_status, addr, cmd;
 
if (denali_send_pipeline_cmd(denali, page, false, true, SPARE_ACCESS,
-   DENALI_READ) == PASS) {
+   0) == PASS) {
read_data_from_flash_mem(denali, buf, mtd->oobsize);
 
/*
@@ -578,7 +575,7 @@ static void denali_enable_dma(struct denali_nand_info 
*denali, bool en)
 }
 
 static void denali_setup_dma64(struct denali_nand_info *denali,
-  dma_addr_t dma_addr, int page, int op)
+  dma_addr_t dma_addr, int page, int write)
 {
uint32_t mode;
const int page_count = 1;
@@ -591,7 +588,8 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali,
 * 1. setup transfer type, interrupt when complete,
 *burst len = 64 bytes, the number of pages
 */
-   index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count);
+   index_addr(denali, mode,
+  0x01002000 | (64 << 16) | (write << 8) | page_count);
 
/* 2. set memory low address */
index_addr(denali, mode, dma_addr);
@@ -601,7 +599,7 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali,
 }
 
 static void denali_setup_dma32(struct denali_nand_info *denali,
-  dma_addr_t dma_addr, int page, int op)
+  dma_addr_t dma_addr, int page, int write)
 {
uint32_t mode;
const int page_count = 1;
@@ -611,7 +609,7 @@ static void denali_setup_dma32(struct denali_nand_info 
*denali,
/* DMA is a four step process */
 
/* 1. setup transfer type and # of pages */
-   index_addr(denali, mode | page, 0x2000 | op | page_count);
+   index_addr(denali, mode | page, 0x2000 | (write << 8) | page_count);
 
/* 2. set memory high address bits 23:8 */
index_addr(denali, mode 

[PATCH v6 10/18] mtd: nand: denali: propagate page to helpers via function argument

2017-06-12 Thread Masahiro Yamada
This driver stores the currently addressed page into denali->page,
which is later read out by helper functions.  While I am tackling on
this driver, I often missed to insert "denali->page = page;" where
needed.  This makes page_read/write callbacks to get access to a
wrong page, which is a bug hard to figure out.

Instead, I'd rather pass the page via function argument because the
compiler's prototype checks will help to detect bugs.

For the same reason, propagate dma_addr to the DMA helpers instead
of denali->buf.dma_buf .

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 58 ---
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 7ae2fa65d601..f2e50c5856f3 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -282,7 +282,7 @@ static int denali_dev_ready(struct mtd_info *mtd)
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
  */
-static int denali_send_pipeline_cmd(struct denali_nand_info *denali,
+static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
bool ecc_en, bool transfer_spare,
int access_type, int op)
 {
@@ -293,7 +293,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info 
*denali,
 
denali_reset_irq(denali);
 
-   addr = BANK(denali->flash_bank) | denali->page;
+   addr = BANK(denali->flash_bank) | page;
 
if (op == DENALI_WRITE && access_type != SPARE_ACCESS) {
cmd = MODE_01 | addr;
@@ -366,9 +366,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_mask = INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL;
int status = 0;
 
-   denali->page = page;
-
-   if (denali_send_pipeline_cmd(denali, false, false, SPARE_ACCESS,
+   if (denali_send_pipeline_cmd(denali, page, false, false, SPARE_ACCESS,
DENALI_WRITE) == PASS) {
write_data_to_flash_mem(denali, buf, mtd->oobsize);
 
@@ -393,9 +391,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
uint32_t irq_mask = INTR__LOAD_COMP;
uint32_t irq_status, addr, cmd;
 
-   denali->page = page;
-
-   if (denali_send_pipeline_cmd(denali, false, true, SPARE_ACCESS,
+   if (denali_send_pipeline_cmd(denali, page, false, true, SPARE_ACCESS,
DENALI_READ) == PASS) {
read_data_from_flash_mem(denali, buf, mtd->oobsize);
 
@@ -407,8 +403,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
irq_status = denali_wait_for_irq(denali, irq_mask);
 
if (!(irq_status & INTR__LOAD_COMP))
-   dev_err(denali->dev, "page on OOB timeout %d\n",
-   denali->page);
+   dev_err(denali->dev, "page on OOB timeout %d\n", page);
 
/*
 * We set the device back to MAIN_ACCESS here as I observed
@@ -417,7 +412,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t 
*buf, int page)
 * is reliable (according to the MTD test infrastructure)
 * if you are in MAIN_ACCESS.
 */
-   addr = BANK(denali->flash_bank) | denali->page;
+   addr = BANK(denali->flash_bank) | page;
cmd = MODE_10 | addr;
index_addr(denali, cmd, MAIN_ACCESS);
}
@@ -582,13 +577,13 @@ static void denali_enable_dma(struct denali_nand_info 
*denali, bool en)
ioread32(denali->flash_reg + DMA_ENABLE);
 }
 
-static void denali_setup_dma64(struct denali_nand_info *denali, int op)
+static void denali_setup_dma64(struct denali_nand_info *denali,
+  dma_addr_t dma_addr, int page, int op)
 {
uint32_t mode;
const int page_count = 1;
-   uint64_t addr = denali->buf.dma_buf;
 
-   mode = MODE_10 | BANK(denali->flash_bank) | denali->page;
+   mode = MODE_10 | BANK(denali->flash_bank) | page;
 
/* DMA is a three step process */
 
@@ -599,41 +594,42 @@ static void denali_setup_dma64(struct denali_nand_info 
*denali, int op)
index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count);
 
/* 2. set memory low address */
-   index_addr(denali, mode, addr);
+   index_addr(denali, mode, dma_addr);
 
/* 3. set memory high address */
-   index_addr(denali, mode, addr >> 32);
+   index_addr(denali, mode, (uint64_t)dma_addr >> 32);
 }
 
-static void denali_setup_dma32(struct 

[PATCH v6 04/18] mtd: nand: denali: rework interrupt handling

2017-06-12 Thread Masahiro Yamada
Simplify the interrupt handling and fix issues:

- The register field view of INTR_EN / INTR_STATUS is different
  among IP versions.  The global macro DENALI_IRQ_ALL is hard-coded
  for Intel platforms.  The interrupt mask should be determined at
  run-time depending on the running platform.

- wait_for_irq() loops do {} while() until interested flags are
  asserted.  The logic can be simplified.

- The spin_lock() guard seems too complex (and suspicious in a race
  condition if wait_for_completion_timeout() bails out by timeout).

- denali->complete is reused again and again, but reinit_completion()
  is missing.  Add it.

Re-work the code to make it more robust and easier to handle.

While we are here, also rename the jump label "failed_req_irq" to
more appropriate "disable_irq".

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 316 +-
 drivers/mtd/nand/denali.h |   1 +
 2 files changed, 116 insertions(+), 201 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index ca2b6b8850ba..d7e7555a3d73 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -31,26 +31,13 @@ MODULE_LICENSE("GPL");
 #define DENALI_NAND_NAME"denali-nand"
 
 /*
- * We define a macro here that combines all interrupts this driver uses into
- * a single constant value, for convenience.
- */
-#define DENALI_IRQ_ALL (INTR__DMA_CMD_COMP | \
-   INTR__ECC_TRANSACTION_DONE | \
-   INTR__ECC_ERR | \
-   INTR__PROGRAM_FAIL | \
-   INTR__LOAD_COMP | \
-   INTR__PROGRAM_COMP | \
-   INTR__TIME_OUT | \
-   INTR__ERASE_FAIL | \
-   INTR__RST_COMP | \
-   INTR__ERASE_COMP)
-
-/*
  * indicates whether or not the internal value for the flash bank is
  * valid or not
  */
 #define CHIP_SELECT_INVALID-1
 
+#define DENALI_NR_BANKS4
+
 /*
  * The bus interface clock, clk_x, is phase aligned with the core clock.  The
  * clk_x is an integral multiple N of the core clk.  The value N is configured
@@ -85,14 +72,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
  */
 #define BANK(x) ((x) << 24)
 
-/* forward declarations */
-static void clear_interrupts(struct denali_nand_info *denali);
-static uint32_t wait_for_irq(struct denali_nand_info *denali,
-   uint32_t irq_mask);
-static void denali_irq_enable(struct denali_nand_info *denali,
-   uint32_t int_mask);
-static uint32_t read_interrupt_status(struct denali_nand_info *denali);
-
 /*
  * Certain operations for the denali NAND controller use an indexed mode to
  * read/write data. The operation is performed by writing the address value
@@ -143,22 +122,6 @@ static void read_status(struct denali_nand_info *denali)
write_byte_to_buf(denali, 0);
 }
 
-/* resets a specific device connected to the core */
-static void reset_bank(struct denali_nand_info *denali)
-{
-   uint32_t irq_status;
-   uint32_t irq_mask = INTR__RST_COMP | INTR__TIME_OUT;
-
-   clear_interrupts(denali);
-
-   iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);
-
-   irq_status = wait_for_irq(denali, irq_mask);
-
-   if (irq_status & INTR__TIME_OUT)
-   dev_err(denali->dev, "reset bank failed.\n");
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -201,169 +164,123 @@ static void detect_max_banks(struct denali_nand_info 
*denali)
denali->max_banks <<= 1;
 }
 
-static void denali_set_intr_modes(struct denali_nand_info *denali,
-   uint16_t INT_ENABLE)
+static void denali_enable_irq(struct denali_nand_info *denali)
 {
-   if (INT_ENABLE)
-   iowrite32(1, denali->flash_reg + GLOBAL_INT_ENABLE);
-   else
-   iowrite32(0, denali->flash_reg + GLOBAL_INT_ENABLE);
-}
+   int i;
 
-/*
- * validation function to verify that the controlling software is making
- * a valid request
- */
-static inline bool is_flash_bank_valid(int flash_bank)
-{
-   return flash_bank >= 0 && flash_bank < 4;
+   for (i = 0; i < DENALI_NR_BANKS; i++)
+   iowrite32(U32_MAX, denali->flash_reg + INTR_EN(i));
+   iowrite32(GLOBAL_INT_EN_FLAG, denali->flash_reg + GLOBAL_INT_ENABLE);
 }
 
-static void denali_irq_init(struct denali_nand_info *denali)
+static void denali_disable_irq(struct denali_nand_info *denali)
 {
-   uint32_t int_mask;
int i;
 
-   /* Disable global interrupts */
-   denali_set_intr_modes(denali, false);
-
-   

[PATCH v6 04/18] mtd: nand: denali: rework interrupt handling

2017-06-12 Thread Masahiro Yamada
Simplify the interrupt handling and fix issues:

- The register field view of INTR_EN / INTR_STATUS is different
  among IP versions.  The global macro DENALI_IRQ_ALL is hard-coded
  for Intel platforms.  The interrupt mask should be determined at
  run-time depending on the running platform.

- wait_for_irq() loops do {} while() until interested flags are
  asserted.  The logic can be simplified.

- The spin_lock() guard seems too complex (and suspicious in a race
  condition if wait_for_completion_timeout() bails out by timeout).

- denali->complete is reused again and again, but reinit_completion()
  is missing.  Add it.

Re-work the code to make it more robust and easier to handle.

While we are here, also rename the jump label "failed_req_irq" to
more appropriate "disable_irq".

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 316 +-
 drivers/mtd/nand/denali.h |   1 +
 2 files changed, 116 insertions(+), 201 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index ca2b6b8850ba..d7e7555a3d73 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -31,26 +31,13 @@ MODULE_LICENSE("GPL");
 #define DENALI_NAND_NAME"denali-nand"
 
 /*
- * We define a macro here that combines all interrupts this driver uses into
- * a single constant value, for convenience.
- */
-#define DENALI_IRQ_ALL (INTR__DMA_CMD_COMP | \
-   INTR__ECC_TRANSACTION_DONE | \
-   INTR__ECC_ERR | \
-   INTR__PROGRAM_FAIL | \
-   INTR__LOAD_COMP | \
-   INTR__PROGRAM_COMP | \
-   INTR__TIME_OUT | \
-   INTR__ERASE_FAIL | \
-   INTR__RST_COMP | \
-   INTR__ERASE_COMP)
-
-/*
  * indicates whether or not the internal value for the flash bank is
  * valid or not
  */
 #define CHIP_SELECT_INVALID-1
 
+#define DENALI_NR_BANKS4
+
 /*
  * The bus interface clock, clk_x, is phase aligned with the core clock.  The
  * clk_x is an integral multiple N of the core clk.  The value N is configured
@@ -85,14 +72,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
  */
 #define BANK(x) ((x) << 24)
 
-/* forward declarations */
-static void clear_interrupts(struct denali_nand_info *denali);
-static uint32_t wait_for_irq(struct denali_nand_info *denali,
-   uint32_t irq_mask);
-static void denali_irq_enable(struct denali_nand_info *denali,
-   uint32_t int_mask);
-static uint32_t read_interrupt_status(struct denali_nand_info *denali);
-
 /*
  * Certain operations for the denali NAND controller use an indexed mode to
  * read/write data. The operation is performed by writing the address value
@@ -143,22 +122,6 @@ static void read_status(struct denali_nand_info *denali)
write_byte_to_buf(denali, 0);
 }
 
-/* resets a specific device connected to the core */
-static void reset_bank(struct denali_nand_info *denali)
-{
-   uint32_t irq_status;
-   uint32_t irq_mask = INTR__RST_COMP | INTR__TIME_OUT;
-
-   clear_interrupts(denali);
-
-   iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);
-
-   irq_status = wait_for_irq(denali, irq_mask);
-
-   if (irq_status & INTR__TIME_OUT)
-   dev_err(denali->dev, "reset bank failed.\n");
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -201,169 +164,123 @@ static void detect_max_banks(struct denali_nand_info 
*denali)
denali->max_banks <<= 1;
 }
 
-static void denali_set_intr_modes(struct denali_nand_info *denali,
-   uint16_t INT_ENABLE)
+static void denali_enable_irq(struct denali_nand_info *denali)
 {
-   if (INT_ENABLE)
-   iowrite32(1, denali->flash_reg + GLOBAL_INT_ENABLE);
-   else
-   iowrite32(0, denali->flash_reg + GLOBAL_INT_ENABLE);
-}
+   int i;
 
-/*
- * validation function to verify that the controlling software is making
- * a valid request
- */
-static inline bool is_flash_bank_valid(int flash_bank)
-{
-   return flash_bank >= 0 && flash_bank < 4;
+   for (i = 0; i < DENALI_NR_BANKS; i++)
+   iowrite32(U32_MAX, denali->flash_reg + INTR_EN(i));
+   iowrite32(GLOBAL_INT_EN_FLAG, denali->flash_reg + GLOBAL_INT_ENABLE);
 }
 
-static void denali_irq_init(struct denali_nand_info *denali)
+static void denali_disable_irq(struct denali_nand_info *denali)
 {
-   uint32_t int_mask;
int i;
 
-   /* Disable global interrupts */
-   denali_set_intr_modes(denali, false);
-
-   int_mask = DENALI_IRQ_ALL;
-
-   

[PATCH] power: supply: constify psy_tcd_ops.

2017-06-12 Thread Arvind Yadav
File size before:
textdatabss dec   hex filename
4240 200 80 4520 11a8 drivers/power/supply/power_supply_core.o

File size After adding 'const':
textdatabss dec   hex filename
4296 136 80 4512 11a0 drivers/power/supply/power_supply_core.o

Signed-off-by: Arvind Yadav 
---
 drivers/power/supply/power_supply_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/power_supply_core.c 
b/drivers/power/supply/power_supply_core.c
index 7ec7c7c..2cc64b8 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -669,7 +669,7 @@ static int ps_set_cur_charge_cntl_limit(struct 
thermal_cooling_device *tcd,
return ret;
 }
 
-static struct thermal_cooling_device_ops psy_tcd_ops = {
+static const struct thermal_cooling_device_ops psy_tcd_ops = {
.get_max_state = ps_get_max_charge_cntl_limit,
.get_cur_state = ps_get_cur_chrage_cntl_limit,
.set_cur_state = ps_set_cur_charge_cntl_limit,
-- 
1.9.1



Re: [PATCH v1 1/2] dt-binding: ptp: add bindings document for dte based ptp clock

2017-06-12 Thread Richard Cochran
On Mon, Jun 12, 2017 at 01:26:00PM -0700, Arun Parameswaran wrote:
> +Example:
> +
> +ptp_dte: ptp_dte@180af650 {
> + compatible = "brcm,ptp-dte";
> + reg = <0x180af650 0x10>;
> + status = "okay";
> +};

This patch set looks okay, as far as it goes, but how does one
actually use the clock?

How does one connect this node to an Ethernet MAC, for example?

Thanks,
Richard


[PATCH] power: supply: constify psy_tcd_ops.

2017-06-12 Thread Arvind Yadav
File size before:
textdatabss dec   hex filename
4240 200 80 4520 11a8 drivers/power/supply/power_supply_core.o

File size After adding 'const':
textdatabss dec   hex filename
4296 136 80 4512 11a0 drivers/power/supply/power_supply_core.o

Signed-off-by: Arvind Yadav 
---
 drivers/power/supply/power_supply_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/power_supply_core.c 
b/drivers/power/supply/power_supply_core.c
index 7ec7c7c..2cc64b8 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -669,7 +669,7 @@ static int ps_set_cur_charge_cntl_limit(struct 
thermal_cooling_device *tcd,
return ret;
 }
 
-static struct thermal_cooling_device_ops psy_tcd_ops = {
+static const struct thermal_cooling_device_ops psy_tcd_ops = {
.get_max_state = ps_get_max_charge_cntl_limit,
.get_cur_state = ps_get_cur_chrage_cntl_limit,
.set_cur_state = ps_set_cur_charge_cntl_limit,
-- 
1.9.1



Re: [PATCH v1 1/2] dt-binding: ptp: add bindings document for dte based ptp clock

2017-06-12 Thread Richard Cochran
On Mon, Jun 12, 2017 at 01:26:00PM -0700, Arun Parameswaran wrote:
> +Example:
> +
> +ptp_dte: ptp_dte@180af650 {
> + compatible = "brcm,ptp-dte";
> + reg = <0x180af650 0x10>;
> + status = "okay";
> +};

This patch set looks okay, as far as it goes, but how does one
actually use the clock?

How does one connect this node to an Ethernet MAC, for example?

Thanks,
Richard


[PATCH v6 07/18] mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc

2017-06-12 Thread Masahiro Yamada
The NAND_CMD_SET_FEATURES support is missing from denali_cmdfunc().

Besides, we see /* TODO: Read OOB data */ comment line.

It would be possible to add more commands along with the current
implementation, but having ->cmd_ctrl() seems a better approach from
the discussion with Boris [1].

Rely on the default ->cmdfunc() from the framework and implement the
driver's own ->cmd_ctrl().

Also add ->write_byte(), which is needed for write direction commands.

Then, we can drop nand_onfi_get_set_features_notsupp from this driver.

[1] https://lkml.org/lkml/2017/3/15/97

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Remove nand_onfi_get_set_features_notsupp()

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 106 +++---
 1 file changed, 52 insertions(+), 54 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 2325a97aa54a..09a14fafa967 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -230,20 +230,16 @@ static uint32_t denali_wait_for_irq(struct 
denali_nand_info *denali,
return denali->irq_status;
 }
 
-/* resets a specific device connected to the core */
-static void reset_bank(struct denali_nand_info *denali)
+static uint32_t denali_check_irq(struct denali_nand_info *denali)
 {
+   unsigned long flags;
uint32_t irq_status;
 
-   denali_reset_irq(denali);
-
-   iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);
-
-   irq_status = denali_wait_for_irq(denali,
-INTR__RST_COMP | INTR__TIME_OUT);
+   spin_lock_irqsave(>irq_lock, flags);
+   irq_status = denali->irq_status;
+   spin_unlock_irqrestore(>irq_lock, flags);
 
-   if (!(irq_status & INTR__RST_COMP))
-   dev_err(denali->dev, "reset bank failed.\n");
+   return irq_status;
 }
 
 /*
@@ -273,6 +269,42 @@ static uint8_t denali_read_byte(struct mtd_info *mtd)
return ioread32(denali->flash_mem + 0x10);
 }
 
+static void denali_write_byte(struct mtd_info *mtd, uint8_t byte)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | 2, byte);
+}
+
+static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   uint32_t type;
+
+   if (ctrl & NAND_CLE)
+   type = 0;
+   else if (ctrl & NAND_ALE)
+   type = 1;
+   else
+   return;
+
+   /*
+* Some commands are followed by chip->dev_ready or chip->waitfunc.
+* irq_status must be cleared here to catch the R/B# interrupt later.
+*/
+   if (ctrl & NAND_CTRL_CHANGE)
+   denali_reset_irq(denali);
+
+   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | type, dat);
+}
+
+static int denali_dev_ready(struct mtd_info *mtd)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   return !!(denali_check_irq(denali) & INTR__INT_ACT);
+}
+
 /*
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
@@ -824,7 +856,13 @@ static void denali_select_chip(struct mtd_info *mtd, int 
chip)
 
 static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
 {
-   return 0;
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   uint32_t irq_status;
+
+   /* R/B# pin transitioned from low to high? */
+   irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
+
+   return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
 }
 
 static int denali_erase(struct mtd_info *mtd, int page)
@@ -845,46 +883,6 @@ static int denali_erase(struct mtd_info *mtd, int page)
return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
 }
 
-static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
-  int page)
-{
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t addr, irq_status;
-   int wait_ready = 0;
-
-   switch (cmd) {
-   case NAND_CMD_PARAM:
-   wait_ready = 1;
-   break;
-   case NAND_CMD_STATUS:
-   case NAND_CMD_READID:
-   break;
-   case NAND_CMD_RESET:
-   reset_bank(denali);
-   break;
-   case NAND_CMD_READOOB:
-   /* TODO: Read OOB data */
-   return;
-   default:
-   pr_err(": unsupported command received 0x%x\n", cmd);
-   return;
-   }
-
-   denali_reset_irq(denali);
-
-   addr = MODE_11 | BANK(denali->flash_bank);
-   index_addr(denali, addr | 0, cmd);
-   if (col != -1)
-   index_addr(denali, addr | 1, col);
-
-   if (!wait_ready)
-   

[PATCH v6 07/18] mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc

2017-06-12 Thread Masahiro Yamada
The NAND_CMD_SET_FEATURES support is missing from denali_cmdfunc().

Besides, we see /* TODO: Read OOB data */ comment line.

It would be possible to add more commands along with the current
implementation, but having ->cmd_ctrl() seems a better approach from
the discussion with Boris [1].

Rely on the default ->cmdfunc() from the framework and implement the
driver's own ->cmd_ctrl().

Also add ->write_byte(), which is needed for write direction commands.

Then, we can drop nand_onfi_get_set_features_notsupp from this driver.

[1] https://lkml.org/lkml/2017/3/15/97

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Remove nand_onfi_get_set_features_notsupp()

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 106 +++---
 1 file changed, 52 insertions(+), 54 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 2325a97aa54a..09a14fafa967 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -230,20 +230,16 @@ static uint32_t denali_wait_for_irq(struct 
denali_nand_info *denali,
return denali->irq_status;
 }
 
-/* resets a specific device connected to the core */
-static void reset_bank(struct denali_nand_info *denali)
+static uint32_t denali_check_irq(struct denali_nand_info *denali)
 {
+   unsigned long flags;
uint32_t irq_status;
 
-   denali_reset_irq(denali);
-
-   iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);
-
-   irq_status = denali_wait_for_irq(denali,
-INTR__RST_COMP | INTR__TIME_OUT);
+   spin_lock_irqsave(>irq_lock, flags);
+   irq_status = denali->irq_status;
+   spin_unlock_irqrestore(>irq_lock, flags);
 
-   if (!(irq_status & INTR__RST_COMP))
-   dev_err(denali->dev, "reset bank failed.\n");
+   return irq_status;
 }
 
 /*
@@ -273,6 +269,42 @@ static uint8_t denali_read_byte(struct mtd_info *mtd)
return ioread32(denali->flash_mem + 0x10);
 }
 
+static void denali_write_byte(struct mtd_info *mtd, uint8_t byte)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | 2, byte);
+}
+
+static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   uint32_t type;
+
+   if (ctrl & NAND_CLE)
+   type = 0;
+   else if (ctrl & NAND_ALE)
+   type = 1;
+   else
+   return;
+
+   /*
+* Some commands are followed by chip->dev_ready or chip->waitfunc.
+* irq_status must be cleared here to catch the R/B# interrupt later.
+*/
+   if (ctrl & NAND_CTRL_CHANGE)
+   denali_reset_irq(denali);
+
+   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | type, dat);
+}
+
+static int denali_dev_ready(struct mtd_info *mtd)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   return !!(denali_check_irq(denali) & INTR__INT_ACT);
+}
+
 /*
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
@@ -824,7 +856,13 @@ static void denali_select_chip(struct mtd_info *mtd, int 
chip)
 
 static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
 {
-   return 0;
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+   uint32_t irq_status;
+
+   /* R/B# pin transitioned from low to high? */
+   irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
+
+   return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
 }
 
 static int denali_erase(struct mtd_info *mtd, int page)
@@ -845,46 +883,6 @@ static int denali_erase(struct mtd_info *mtd, int page)
return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
 }
 
-static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
-  int page)
-{
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t addr, irq_status;
-   int wait_ready = 0;
-
-   switch (cmd) {
-   case NAND_CMD_PARAM:
-   wait_ready = 1;
-   break;
-   case NAND_CMD_STATUS:
-   case NAND_CMD_READID:
-   break;
-   case NAND_CMD_RESET:
-   reset_bank(denali);
-   break;
-   case NAND_CMD_READOOB:
-   /* TODO: Read OOB data */
-   return;
-   default:
-   pr_err(": unsupported command received 0x%x\n", cmd);
-   return;
-   }
-
-   denali_reset_irq(denali);
-
-   addr = MODE_11 | BANK(denali->flash_bank);
-   index_addr(denali, addr | 0, cmd);
-   if (col != -1)
-   index_addr(denali, addr | 1, col);
-
-   if (!wait_ready)
-   return;
-
-   irq_status = 

[PATCH v6 09/18] mtd: nand: denali: use interrupt instead of polling for bank reset

2017-06-12 Thread Masahiro Yamada
The current bank reset implementation polls the INTR_STATUS register
until interested bits are set.  This is not good because:

- polling simply wastes time-slice of the thread

- The while() loop may continue eternally if no bit is set, for
  example, due to the controller problem.  The denali_wait_for_irq()
  uses wait_for_completion_timeout(), which is safer.

We can use interrupt by moving the denali_reset_bank() call below
the interrupt setup.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 61a2ee9fb367..7ae2fa65d601 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -973,24 +973,25 @@ static int denali_setup_data_interface(struct mtd_info 
*mtd, int chipnr,
 
 static void denali_reset_banks(struct denali_nand_info *denali)
 {
+   u32 irq_status;
int i;
 
-   denali_clear_irq_all(denali);
-
for (i = 0; i < denali->max_banks; i++) {
-   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
-   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   (INTR__RST_COMP | INTR__TIME_OUT)))
-   cpu_relax();
-   if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
- INTR__INT_ACT))
+   denali->flash_bank = i;
+
+   denali_reset_irq(denali);
+
+   iowrite32(DEVICE_RESET__BANK(i),
+ denali->flash_reg + DEVICE_RESET);
+
+   irq_status = denali_wait_for_irq(denali,
+   INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
+   if (!(irq_status & INTR__INT_ACT))
break;
}
 
dev_dbg(denali->dev, "%d chips connected\n", i);
denali->max_banks = i;
-
-   denali_clear_irq_all(denali);
 }
 
 static void denali_hw_init(struct denali_nand_info *denali)
@@ -1012,7 +1013,6 @@ static void denali_hw_init(struct denali_nand_info 
*denali)
denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali);
-   denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE);
@@ -1130,9 +1130,6 @@ static void denali_drv_init(struct denali_nand_info 
*denali)
 * element that might be access shared data (interrupt status)
 */
spin_lock_init(>irq_lock);
-
-   /* indicate that MTD has not selected a valid bank yet */
-   denali->flash_bank = CHIP_SELECT_INVALID;
 }
 
 static int denali_multidev_fixup(struct denali_nand_info *denali)
@@ -1207,6 +1204,9 @@ int denali_init(struct denali_nand_info *denali)
}
 
denali_enable_irq(denali);
+   denali_reset_banks(denali);
+
+   denali->flash_bank = CHIP_SELECT_INVALID;
 
nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */
-- 
2.7.4



[PATCH v6 09/18] mtd: nand: denali: use interrupt instead of polling for bank reset

2017-06-12 Thread Masahiro Yamada
The current bank reset implementation polls the INTR_STATUS register
until interested bits are set.  This is not good because:

- polling simply wastes time-slice of the thread

- The while() loop may continue eternally if no bit is set, for
  example, due to the controller problem.  The denali_wait_for_irq()
  uses wait_for_completion_timeout(), which is safer.

We can use interrupt by moving the denali_reset_bank() call below
the interrupt setup.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 61a2ee9fb367..7ae2fa65d601 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -973,24 +973,25 @@ static int denali_setup_data_interface(struct mtd_info 
*mtd, int chipnr,
 
 static void denali_reset_banks(struct denali_nand_info *denali)
 {
+   u32 irq_status;
int i;
 
-   denali_clear_irq_all(denali);
-
for (i = 0; i < denali->max_banks; i++) {
-   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
-   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   (INTR__RST_COMP | INTR__TIME_OUT)))
-   cpu_relax();
-   if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
- INTR__INT_ACT))
+   denali->flash_bank = i;
+
+   denali_reset_irq(denali);
+
+   iowrite32(DEVICE_RESET__BANK(i),
+ denali->flash_reg + DEVICE_RESET);
+
+   irq_status = denali_wait_for_irq(denali,
+   INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
+   if (!(irq_status & INTR__INT_ACT))
break;
}
 
dev_dbg(denali->dev, "%d chips connected\n", i);
denali->max_banks = i;
-
-   denali_clear_irq_all(denali);
 }
 
 static void denali_hw_init(struct denali_nand_info *denali)
@@ -1012,7 +1013,6 @@ static void denali_hw_init(struct denali_nand_info 
*denali)
denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali);
-   denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE);
@@ -1130,9 +1130,6 @@ static void denali_drv_init(struct denali_nand_info 
*denali)
 * element that might be access shared data (interrupt status)
 */
spin_lock_init(>irq_lock);
-
-   /* indicate that MTD has not selected a valid bank yet */
-   denali->flash_bank = CHIP_SELECT_INVALID;
 }
 
 static int denali_multidev_fixup(struct denali_nand_info *denali)
@@ -1207,6 +1204,9 @@ int denali_init(struct denali_nand_info *denali)
}
 
denali_enable_irq(denali);
+   denali_reset_banks(denali);
+
+   denali->flash_bank = CHIP_SELECT_INVALID;
 
nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */
-- 
2.7.4



[PATCH v6 03/18] mtd: nand: denali: handle timing parameters by setup_data_interface()

2017-06-12 Thread Masahiro Yamada
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4.  Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.

Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.

While I am working on this, I found even more issues in the current
code, so fixed the following as well:

- In recent IP versions, WE_2_RE and TWHR2 share the same register.
  Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB.  When
  updating one, the other must be masked.  Otherwise, the other will
  be set to 0, then timing settings will be broken.

- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
  This register is related to tADL.  As commit 74a332e78e8f ("mtd:
  nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
  ONFi 4.0 increased the minimum of tADL to 400 nsec.  This may not
  fit in the 6-bit ADDR_2_DATA in older versions.  Check the IP
  revision and handle this correctly, otherwise the register value
  would wrap around.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Rebase on commit 104e442a67cfba4d0cc982384761befb917fb6a1
(mtd: nand: Pass the CS line to ->setup_data_interface() )

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 345 +++---
 drivers/mtd/nand/denali.h |  26 ++--
 drivers/mtd/nand/denali_dt.c  |   3 +-
 drivers/mtd/nand/denali_pci.c |   6 +-
 4 files changed, 139 insertions(+), 241 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 122df4c6126d..ca2b6b8850ba 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -28,17 +28,6 @@
 
 MODULE_LICENSE("GPL");
 
-/*
- * We define a module parameter that allows the user to override
- * the hardware and decide what timing mode should be used.
- */
-#define NAND_DEFAULT_TIMINGS   -1
-
-static int onfi_timing_mode = NAND_DEFAULT_TIMINGS;
-module_param(onfi_timing_mode, int, S_IRUGO);
-MODULE_PARM_DESC(onfi_timing_mode,
-  "Overrides default ONFI setting. -1 indicates use default timings");
-
 #define DENALI_NAND_NAME"denali-nand"
 
 /*
@@ -63,10 +52,12 @@ MODULE_PARM_DESC(onfi_timing_mode,
 #define CHIP_SELECT_INVALID-1
 
 /*
- * This macro divides two integers and rounds fractional values up
- * to the nearest integer value.
+ * The bus interface clock, clk_x, is phase aligned with the core clock.  The
+ * clk_x is an integral multiple N of the core clk.  The value N is configured
+ * at IP delivery time, and its available value is 4, 5, or 6.  We need to 
align
+ * to the largest value to make it work with any possible configuration.
  */
-#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
+#define DENALI_CLK_X_MULT  6
 
 /*
  * this macro allows us to convert from an MTD structure to our own
@@ -196,148 +187,6 @@ static uint16_t denali_nand_reset(struct denali_nand_info 
*denali)
 }
 
 /*
- * this routine calculates the ONFI timing values for a given mode and
- * programs the clocking register accordingly. The mode is determined by
- * the get_onfi_nand_para routine.
- */
-static void nand_onfi_timing_set(struct denali_nand_info *denali,
-   uint16_t mode)
-{
-   uint16_t Trea[6] = {40, 30, 25, 20, 20, 16};
-   uint16_t Trp[6] = {50, 25, 17, 15, 12, 10};
-   uint16_t Treh[6] = {30, 15, 15, 10, 10, 7};
-   uint16_t Trc[6] = {100, 50, 35, 30, 25, 20};
-   uint16_t Trhoh[6] = {0, 15, 15, 15, 15, 15};
-   uint16_t Trloh[6] = {0, 0, 0, 0, 5, 5};
-   uint16_t Tcea[6] = {100, 45, 30, 25, 25, 25};
-   uint16_t Tadl[6] = {200, 100, 100, 100, 70, 70};
-   uint16_t Trhw[6] = {200, 100, 100, 100, 100, 100};
-   uint16_t Trhz[6] = {200, 100, 100, 100, 100, 100};
-   uint16_t Twhr[6] = {120, 80, 80, 60, 60, 60};
-   uint16_t Tcs[6] = {70, 35, 25, 25, 20, 15};
-
-   uint16_t data_invalid_rhoh, data_invalid_rloh, data_invalid;
-   uint16_t dv_window = 0;
-   uint16_t en_lo, en_hi;
-   uint16_t acc_clks;
-   uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
-
-   en_lo = CEIL_DIV(Trp[mode], CLK_X);
-   en_hi = CEIL_DIV(Treh[mode], CLK_X);
-#if ONFI_BLOOM_TIME
-   if ((en_hi * CLK_X) < (Treh[mode] + 2))
-   en_hi++;
-#endif
-
-   if ((en_lo + en_hi) * CLK_X < Trc[mode])
-   en_lo += CEIL_DIV((Trc[mode] - (en_lo + en_hi) * CLK_X), CLK_X);
-
-   if ((en_lo + en_hi) < CLK_MULTI)
-   en_lo += CLK_MULTI - en_lo - en_hi;
-
-   while (dv_window < 8) {
-   data_invalid_rhoh = en_lo * CLK_X + Trhoh[mode];
-
-   data_invalid_rloh = 

[PATCH v6 03/18] mtd: nand: denali: handle timing parameters by setup_data_interface()

2017-06-12 Thread Masahiro Yamada
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4.  Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.

Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.

While I am working on this, I found even more issues in the current
code, so fixed the following as well:

- In recent IP versions, WE_2_RE and TWHR2 share the same register.
  Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB.  When
  updating one, the other must be masked.  Otherwise, the other will
  be set to 0, then timing settings will be broken.

- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
  This register is related to tADL.  As commit 74a332e78e8f ("mtd:
  nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
  ONFi 4.0 increased the minimum of tADL to 400 nsec.  This may not
  fit in the 6-bit ADDR_2_DATA in older versions.  Check the IP
  revision and handle this correctly, otherwise the register value
  would wrap around.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Rebase on commit 104e442a67cfba4d0cc982384761befb917fb6a1
(mtd: nand: Pass the CS line to ->setup_data_interface() )

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 345 +++---
 drivers/mtd/nand/denali.h |  26 ++--
 drivers/mtd/nand/denali_dt.c  |   3 +-
 drivers/mtd/nand/denali_pci.c |   6 +-
 4 files changed, 139 insertions(+), 241 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 122df4c6126d..ca2b6b8850ba 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -28,17 +28,6 @@
 
 MODULE_LICENSE("GPL");
 
-/*
- * We define a module parameter that allows the user to override
- * the hardware and decide what timing mode should be used.
- */
-#define NAND_DEFAULT_TIMINGS   -1
-
-static int onfi_timing_mode = NAND_DEFAULT_TIMINGS;
-module_param(onfi_timing_mode, int, S_IRUGO);
-MODULE_PARM_DESC(onfi_timing_mode,
-  "Overrides default ONFI setting. -1 indicates use default timings");
-
 #define DENALI_NAND_NAME"denali-nand"
 
 /*
@@ -63,10 +52,12 @@ MODULE_PARM_DESC(onfi_timing_mode,
 #define CHIP_SELECT_INVALID-1
 
 /*
- * This macro divides two integers and rounds fractional values up
- * to the nearest integer value.
+ * The bus interface clock, clk_x, is phase aligned with the core clock.  The
+ * clk_x is an integral multiple N of the core clk.  The value N is configured
+ * at IP delivery time, and its available value is 4, 5, or 6.  We need to 
align
+ * to the largest value to make it work with any possible configuration.
  */
-#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
+#define DENALI_CLK_X_MULT  6
 
 /*
  * this macro allows us to convert from an MTD structure to our own
@@ -196,148 +187,6 @@ static uint16_t denali_nand_reset(struct denali_nand_info 
*denali)
 }
 
 /*
- * this routine calculates the ONFI timing values for a given mode and
- * programs the clocking register accordingly. The mode is determined by
- * the get_onfi_nand_para routine.
- */
-static void nand_onfi_timing_set(struct denali_nand_info *denali,
-   uint16_t mode)
-{
-   uint16_t Trea[6] = {40, 30, 25, 20, 20, 16};
-   uint16_t Trp[6] = {50, 25, 17, 15, 12, 10};
-   uint16_t Treh[6] = {30, 15, 15, 10, 10, 7};
-   uint16_t Trc[6] = {100, 50, 35, 30, 25, 20};
-   uint16_t Trhoh[6] = {0, 15, 15, 15, 15, 15};
-   uint16_t Trloh[6] = {0, 0, 0, 0, 5, 5};
-   uint16_t Tcea[6] = {100, 45, 30, 25, 25, 25};
-   uint16_t Tadl[6] = {200, 100, 100, 100, 70, 70};
-   uint16_t Trhw[6] = {200, 100, 100, 100, 100, 100};
-   uint16_t Trhz[6] = {200, 100, 100, 100, 100, 100};
-   uint16_t Twhr[6] = {120, 80, 80, 60, 60, 60};
-   uint16_t Tcs[6] = {70, 35, 25, 25, 20, 15};
-
-   uint16_t data_invalid_rhoh, data_invalid_rloh, data_invalid;
-   uint16_t dv_window = 0;
-   uint16_t en_lo, en_hi;
-   uint16_t acc_clks;
-   uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
-
-   en_lo = CEIL_DIV(Trp[mode], CLK_X);
-   en_hi = CEIL_DIV(Treh[mode], CLK_X);
-#if ONFI_BLOOM_TIME
-   if ((en_hi * CLK_X) < (Treh[mode] + 2))
-   en_hi++;
-#endif
-
-   if ((en_lo + en_hi) * CLK_X < Trc[mode])
-   en_lo += CEIL_DIV((Trc[mode] - (en_lo + en_hi) * CLK_X), CLK_X);
-
-   if ((en_lo + en_hi) < CLK_MULTI)
-   en_lo += CLK_MULTI - en_lo - en_hi;
-
-   while (dv_window < 8) {
-   data_invalid_rhoh = en_lo * CLK_X + Trhoh[mode];
-
-   data_invalid_rloh = (en_lo + en_hi) * CLK_X + 

[PATCH v6 02/18] mtd: nand: denali: remove unneeded find_valid_banks()

2017-06-12 Thread Masahiro Yamada
The function find_valid_banks() issues the Read ID (0x90) command,
then compares the first byte (Manufacturer ID) of each bank with
the one of bank0.

This is equivalent to what nand_scan_ident() does.  The number of
chips is detected there, so this is unneeded.

What is worse for find_valid_banks() is that, if multiple chips are
connected to INTEL_CE4100 platform, it crashes the kernel by BUG().
This is what we should avoid.  This function is just harmful and
unneeded.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 47 ---
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 48 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 7133a33b4ad3..122df4c6126d 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -338,51 +338,6 @@ static void get_samsung_nand_para(struct denali_nand_info 
*denali,
 }
 
 /*
- * determines how many NAND chips are connected to the controller. Note for
- * Intel CE4100 devices we don't support more than one device.
- */
-static void find_valid_banks(struct denali_nand_info *denali)
-{
-   uint32_t id[denali->max_banks];
-   int i;
-
-   denali->total_used_banks = 1;
-   for (i = 0; i < denali->max_banks; i++) {
-   index_addr(denali, MODE_11 | (i << 24) | 0, 0x90);
-   index_addr(denali, MODE_11 | (i << 24) | 1, 0);
-   index_addr_read_data(denali, MODE_11 | (i << 24) | 2, [i]);
-
-   dev_dbg(denali->dev,
-   "Return 1st ID for bank[%d]: %x\n", i, id[i]);
-
-   if (i == 0) {
-   if (!(id[i] & 0x0ff))
-   break; /* WTF? */
-   } else {
-   if ((id[i] & 0x0ff) == (id[0] & 0x0ff))
-   denali->total_used_banks++;
-   else
-   break;
-   }
-   }
-
-   if (denali->platform == INTEL_CE4100) {
-   /*
-* Platform limitations of the CE4100 device limit
-* users to a single chip solution for NAND.
-* Multichip support is not enabled.
-*/
-   if (denali->total_used_banks != 1) {
-   dev_err(denali->dev,
-   "Sorry, Intel CE4100 only supports a single 
NAND device.\n");
-   BUG();
-   }
-   }
-   dev_dbg(denali->dev,
-   "denali->total_used_banks: %d\n", denali->total_used_banks);
-}
-
-/*
  * Use the configuration feature register to determine the maximum number of
  * banks that the hardware supports.
  */
@@ -439,8 +394,6 @@ static uint16_t denali_nand_timing_set(struct 
denali_nand_info *denali)
ioread32(denali->flash_reg + RDWR_EN_HI_CNT),
ioread32(denali->flash_reg + CS_SETUP_CNT));
 
-   find_valid_banks(denali);
-
/*
 * If the user specified to override the default timings
 * with a specific ONFI mode, we apply those changes here.
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index 352d8328b94a..0e4a8965f6f1 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -326,7 +326,6 @@ struct denali_nand_info {
int platform;
struct nand_buf buf;
struct device *dev;
-   int total_used_banks;
int page;
void __iomem *flash_reg;/* Register Interface */
void __iomem *flash_mem;/* Host Data/Command Interface */
-- 
2.7.4



[PATCH v6 02/18] mtd: nand: denali: remove unneeded find_valid_banks()

2017-06-12 Thread Masahiro Yamada
The function find_valid_banks() issues the Read ID (0x90) command,
then compares the first byte (Manufacturer ID) of each bank with
the one of bank0.

This is equivalent to what nand_scan_ident() does.  The number of
chips is detected there, so this is unneeded.

What is worse for find_valid_banks() is that, if multiple chips are
connected to INTEL_CE4100 platform, it crashes the kernel by BUG().
This is what we should avoid.  This function is just harmful and
unneeded.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 47 ---
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 48 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 7133a33b4ad3..122df4c6126d 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -338,51 +338,6 @@ static void get_samsung_nand_para(struct denali_nand_info 
*denali,
 }
 
 /*
- * determines how many NAND chips are connected to the controller. Note for
- * Intel CE4100 devices we don't support more than one device.
- */
-static void find_valid_banks(struct denali_nand_info *denali)
-{
-   uint32_t id[denali->max_banks];
-   int i;
-
-   denali->total_used_banks = 1;
-   for (i = 0; i < denali->max_banks; i++) {
-   index_addr(denali, MODE_11 | (i << 24) | 0, 0x90);
-   index_addr(denali, MODE_11 | (i << 24) | 1, 0);
-   index_addr_read_data(denali, MODE_11 | (i << 24) | 2, [i]);
-
-   dev_dbg(denali->dev,
-   "Return 1st ID for bank[%d]: %x\n", i, id[i]);
-
-   if (i == 0) {
-   if (!(id[i] & 0x0ff))
-   break; /* WTF? */
-   } else {
-   if ((id[i] & 0x0ff) == (id[0] & 0x0ff))
-   denali->total_used_banks++;
-   else
-   break;
-   }
-   }
-
-   if (denali->platform == INTEL_CE4100) {
-   /*
-* Platform limitations of the CE4100 device limit
-* users to a single chip solution for NAND.
-* Multichip support is not enabled.
-*/
-   if (denali->total_used_banks != 1) {
-   dev_err(denali->dev,
-   "Sorry, Intel CE4100 only supports a single 
NAND device.\n");
-   BUG();
-   }
-   }
-   dev_dbg(denali->dev,
-   "denali->total_used_banks: %d\n", denali->total_used_banks);
-}
-
-/*
  * Use the configuration feature register to determine the maximum number of
  * banks that the hardware supports.
  */
@@ -439,8 +394,6 @@ static uint16_t denali_nand_timing_set(struct 
denali_nand_info *denali)
ioread32(denali->flash_reg + RDWR_EN_HI_CNT),
ioread32(denali->flash_reg + CS_SETUP_CNT));
 
-   find_valid_banks(denali);
-
/*
 * If the user specified to override the default timings
 * with a specific ONFI mode, we apply those changes here.
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index 352d8328b94a..0e4a8965f6f1 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -326,7 +326,6 @@ struct denali_nand_info {
int platform;
struct nand_buf buf;
struct device *dev;
-   int total_used_banks;
int page;
void __iomem *flash_reg;/* Register Interface */
void __iomem *flash_mem;/* Host Data/Command Interface */
-- 
2.7.4



[PATCH v6 06/18] mtd: nand: denali: fix NAND_CMD_PARAM handling

2017-06-12 Thread Masahiro Yamada
NAND_CMD_PARAM is not working at all due to multiple bugs.

[1] The command 0x90 issued instead of 0xec

The command code 0x90 is hard-code as
   index_addr(denali, addr | 0, 0x90)
So, Read ID (0x90) command is sent to the device instead of Read
Parameter Page (0xec).

[2] only first 8 bytes are read

Even if [1] is fixed, the current implementation is problematic.
The only first 8 bytes are read by MAP11 command, and put into the
temporal buffer:

for (i = 0; i < 8; i++) {
index_addr_read_data(denali, addr | 2, );
write_byte_to_buf(denali, id);
}

Obviously, this is not sufficient for NAND_CMD_PARAM; the ONFi
parameters are 256-byte long.  This is still insufficient.
As you see in nand_flash_detect_onfi() reads out (256 * 3) bytes
at maximum (Redundant Parameter Pages).  However, changing the loop
to for (i = 0; i < 768; i++) is a crazy idea.  At the point of the
chip->cmdfunc() call, we cannot know how many times chip->read_byte()
will be called.  So, pre-reading enough number of bytes in the
chip->cmdfunc() is a design mistake.

[3] no wait for R/B#

The current code handles NAND_CMD_READID and NAND_CMD_PARAM in the
same way, but this is also wrong.  The difference between them is
that Read ID command does not toggle R/B# whereas the Read Parameter
Page command requires R/B#.  Without the wait for R/B# interrupt,
wrong data are retrieved.

In order to fix those problems, data read cycle of the MAP11 command
has been moved to chip->read_byte().  Data are read out as needed.
Another good thing is early temporal buffer is not needed any more.
The ugly devm_kzalloc()/devm_kfree() dance has been killed.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 95 +++
 drivers/mtd/nand/denali.h |  2 -
 2 files changed, 30 insertions(+), 67 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 4bf93232ca30..2325a97aa54a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -85,28 +85,6 @@ static void index_addr(struct denali_nand_info *denali,
iowrite32(data, denali->flash_mem + 0x10);
 }
 
-/* Perform an indexed read of the device */
-static void index_addr_read_data(struct denali_nand_info *denali,
-uint32_t address, uint32_t *pdata)
-{
-   iowrite32(address, denali->flash_mem);
-   *pdata = ioread32(denali->flash_mem + 0x10);
-}
-
-/*
- * We need to buffer some data for some of the NAND core routines.
- * The operations manage buffering that data.
- */
-static void reset_buf(struct denali_nand_info *denali)
-{
-   denali->buf.head = denali->buf.tail = 0;
-}
-
-static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte)
-{
-   denali->buf.buf[denali->buf.tail++] = byte;
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -286,6 +264,15 @@ static void setup_ecc_for_xfer(struct denali_nand_info 
*denali, bool ecc_en,
iowrite32(transfer_spare_flag, denali->flash_reg + TRANSFER_SPARE_REG);
 }
 
+static uint8_t denali_read_byte(struct mtd_info *mtd)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   iowrite32(MODE_11 | BANK(denali->flash_bank) | 2, denali->flash_mem);
+
+   return ioread32(denali->flash_mem + 0x10);
+}
+
 /*
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
@@ -828,17 +815,6 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
return 0;
 }
 
-static uint8_t denali_read_byte(struct mtd_info *mtd)
-{
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint8_t result = 0xff;
-
-   if (denali->buf.head < denali->buf.tail)
-   result = denali->buf.buf[denali->buf.head++];
-
-   return result;
-}
-
 static void denali_select_chip(struct mtd_info *mtd, int chip)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -873,43 +849,40 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
   int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t addr, id;
-   int i;
+   uint32_t addr, irq_status;
+   int wait_ready = 0;
 
switch (cmd) {
-   case NAND_CMD_STATUS:
-   reset_buf(denali);
-   addr = MODE_11 | BANK(denali->flash_bank);
-   index_addr(denali, addr | 0, cmd);
-   index_addr_read_data(denali, addr | 2, );
-   write_byte_to_buf(denali, id);
+   case NAND_CMD_PARAM:
+   wait_ready = 1;
break;
+   case NAND_CMD_STATUS:
case NAND_CMD_READID:
-   case 

[PATCH v6 06/18] mtd: nand: denali: fix NAND_CMD_PARAM handling

2017-06-12 Thread Masahiro Yamada
NAND_CMD_PARAM is not working at all due to multiple bugs.

[1] The command 0x90 issued instead of 0xec

The command code 0x90 is hard-code as
   index_addr(denali, addr | 0, 0x90)
So, Read ID (0x90) command is sent to the device instead of Read
Parameter Page (0xec).

[2] only first 8 bytes are read

Even if [1] is fixed, the current implementation is problematic.
The only first 8 bytes are read by MAP11 command, and put into the
temporal buffer:

for (i = 0; i < 8; i++) {
index_addr_read_data(denali, addr | 2, );
write_byte_to_buf(denali, id);
}

Obviously, this is not sufficient for NAND_CMD_PARAM; the ONFi
parameters are 256-byte long.  This is still insufficient.
As you see in nand_flash_detect_onfi() reads out (256 * 3) bytes
at maximum (Redundant Parameter Pages).  However, changing the loop
to for (i = 0; i < 768; i++) is a crazy idea.  At the point of the
chip->cmdfunc() call, we cannot know how many times chip->read_byte()
will be called.  So, pre-reading enough number of bytes in the
chip->cmdfunc() is a design mistake.

[3] no wait for R/B#

The current code handles NAND_CMD_READID and NAND_CMD_PARAM in the
same way, but this is also wrong.  The difference between them is
that Read ID command does not toggle R/B# whereas the Read Parameter
Page command requires R/B#.  Without the wait for R/B# interrupt,
wrong data are retrieved.

In order to fix those problems, data read cycle of the MAP11 command
has been moved to chip->read_byte().  Data are read out as needed.
Another good thing is early temporal buffer is not needed any more.
The ugly devm_kzalloc()/devm_kfree() dance has been killed.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 95 +++
 drivers/mtd/nand/denali.h |  2 -
 2 files changed, 30 insertions(+), 67 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 4bf93232ca30..2325a97aa54a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -85,28 +85,6 @@ static void index_addr(struct denali_nand_info *denali,
iowrite32(data, denali->flash_mem + 0x10);
 }
 
-/* Perform an indexed read of the device */
-static void index_addr_read_data(struct denali_nand_info *denali,
-uint32_t address, uint32_t *pdata)
-{
-   iowrite32(address, denali->flash_mem);
-   *pdata = ioread32(denali->flash_mem + 0x10);
-}
-
-/*
- * We need to buffer some data for some of the NAND core routines.
- * The operations manage buffering that data.
- */
-static void reset_buf(struct denali_nand_info *denali)
-{
-   denali->buf.head = denali->buf.tail = 0;
-}
-
-static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte)
-{
-   denali->buf.buf[denali->buf.tail++] = byte;
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -286,6 +264,15 @@ static void setup_ecc_for_xfer(struct denali_nand_info 
*denali, bool ecc_en,
iowrite32(transfer_spare_flag, denali->flash_reg + TRANSFER_SPARE_REG);
 }
 
+static uint8_t denali_read_byte(struct mtd_info *mtd)
+{
+   struct denali_nand_info *denali = mtd_to_denali(mtd);
+
+   iowrite32(MODE_11 | BANK(denali->flash_bank) | 2, denali->flash_mem);
+
+   return ioread32(denali->flash_mem + 0x10);
+}
+
 /*
  * sends a pipeline command operation to the controller. See the Denali NAND
  * controller's user guide for more information (section 4.2.3.6).
@@ -828,17 +815,6 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
return 0;
 }
 
-static uint8_t denali_read_byte(struct mtd_info *mtd)
-{
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint8_t result = 0xff;
-
-   if (denali->buf.head < denali->buf.tail)
-   result = denali->buf.buf[denali->buf.head++];
-
-   return result;
-}
-
 static void denali_select_chip(struct mtd_info *mtd, int chip)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -873,43 +849,40 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
   int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t addr, id;
-   int i;
+   uint32_t addr, irq_status;
+   int wait_ready = 0;
 
switch (cmd) {
-   case NAND_CMD_STATUS:
-   reset_buf(denali);
-   addr = MODE_11 | BANK(denali->flash_bank);
-   index_addr(denali, addr | 0, cmd);
-   index_addr_read_data(denali, addr | 2, );
-   write_byte_to_buf(denali, id);
+   case NAND_CMD_PARAM:
+   wait_ready = 1;
break;
+   case NAND_CMD_STATUS:
case NAND_CMD_READID:
-   case NAND_CMD_PARAM:
-   

[PATCH v6 18/18] mtd: nand: denali: avoid magic numbers and rename for clarification

2017-06-12 Thread Masahiro Yamada
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.

- We see '| 2' in several places.  This means Data Cycle in MAP11 mode.
  The Denali User's Guide says bit[1:0] of MAP11 is like follows:

  b'00 = Command Cycle
  b'01 = Address Cycle
  b'10 = Data Cycle

  So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.

- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
  magic number.  Actually, this accesses the data port of the Host
  Data/Command Interface.  So, this commit added DENALI_HOST_DATA.
  On the other hand, 'denali->flash_mem' gets access to the address
  port, so DENALI_HOST_ADDR was also added.

- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
  is a magic number.  0x1 means the erase operation.  Replace 0x1
  with DENALI_ERASE.

- Rename index_addr() to denali_host_write() for clarification and
  add denali_host_read() as a helper.

- Denali User's Guide says MAP{00,01,10,11} for access mode.  Match
  the macros with terminology in the IP document.

- Rename struct members as follows:
  flash_bank   -> active_bank(currently selected bank)
  flash_reg-> reg(base address of registers)
  flash_mem-> host   (base address of host interface)
  devnum   -> devs_per_cs(devices connected in parallel)
  bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Newly added

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/denali.c | 259 ++
 drivers/mtd/nand/denali.h |  15 +--
 drivers/mtd/nand/denali_dt.c  |  12 +-
 drivers/mtd/nand/denali_pci.c |  16 +--
 4 files changed, 153 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 3bcc886579c8..6aa78ca2439b 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -31,12 +31,26 @@ MODULE_LICENSE("GPL");
 
 #define DENALI_NAND_NAME"denali-nand"
 
-/*
- * indicates whether or not the internal value for the flash bank is
- * valid or not
- */
-#define CHIP_SELECT_INVALID-1
+/* Host Data/Command Interface */
+#define DENALI_HOST_ADDR   0x00
+#define DENALI_HOST_DATA   0x10
+
+#define DENALI_MAP00   (0 << 26)   /* direct access to buffer */
+#define DENALI_MAP01   (1 << 26)   /* read/write pages in PIO */
+#define DENALI_MAP10   (2 << 26)   /* higher-level control plane */
+#define DENALI_MAP11   (3 << 26)   /* direct controller access */
+
+/* MAP11 access cycle type */
+#define DENALI_MAP11_CMD   ((DENALI_MAP11) | 0)/* command cycle */
+#define DENALI_MAP11_ADDR  ((DENALI_MAP11) | 1)/* address cycle */
+#define DENALI_MAP11_DATA  ((DENALI_MAP11) | 2)/* data cycle */
 
+/* MAP11 commands */
+#define DENALI_ERASE   0x01
+
+#define DENALI_BANK(denali)((denali)->active_bank << 24)
+
+#define DENALI_INVALID_BANK-1
 #define DENALI_NR_BANKS4
 
 /*
@@ -56,23 +70,17 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
 }
 
-/*
- * this is a helper macro that allows us to
- * format the bank into the proper bits for the controller
- */
-#define BANK(x) ((x) << 24)
+static uint32_t denali_host_read(struct denali_nand_info *denali, uint32_t 
addr)
+{
+   iowrite32(addr, denali->host + DENALI_HOST_ADDR);
+   return ioread32(denali->host + DENALI_HOST_DATA);
+}
 
-/*
- * Certain operations for the denali NAND controller use an indexed mode to
- * read/write data. The operation is performed by writing the address value
- * of the command to the device memory followed by the data. This function
- * abstracts this common operation.
- */
-static void index_addr(struct denali_nand_info *denali,
-   uint32_t address, uint32_t data)
+static void denali_host_write(struct denali_nand_info *denali,
+ uint32_t addr, uint32_t data)
 {
-   iowrite32(address, denali->flash_mem);
-   iowrite32(data, denali->flash_mem + 0x10);
+   iowrite32(addr, denali->host + DENALI_HOST_ADDR);
+   iowrite32(data, denali->host + DENALI_HOST_DATA);
 }
 
 /*
@@ -81,7 +89,7 @@ static void index_addr(struct denali_nand_info *denali,
  */
 static void detect_max_banks(struct denali_nand_info *denali)
 {
-   uint32_t features = ioread32(denali->flash_reg + FEATURES);
+   uint32_t features = ioread32(denali->reg + FEATURES);
 
denali->max_banks = 1 << (features & FEATURES__N_BANKS);
 
@@ -95,8 +103,8 @@ static void denali_enable_irq(struct denali_nand_info 
*denali)
int i;
 
for (i = 0; i < DENALI_NR_BANKS; i++)
-   iowrite32(U32_MAX, denali->flash_reg + INTR_EN(i));
-   

[PATCH v6 14/18] mtd: nand: denali: support hardware-assisted erased page detection

2017-06-12 Thread Masahiro Yamada
Recent versions of this IP support automatic erased page detection.
If an erased page is detected on reads, the controller does not set
INTR__ECC_UNCOR_ERR, but INTR__ERASED_PAGE.

The detection of erased pages is based on the number of zeros in a
page; if the number of zeros is less than the value in the field
ERASED_THRESHOLD, the page is assumed as erased.

Please note ERASED_THRESHOLD specifies the number of zeros in a _page_
instead of an ECC chunk.  Moreover, the controller does not provide a
way to know the actual number of bitflips.

Actually, an erased page (all 0xff) is not an ECC correctable pattern
on the Denali ECC engine.  In other words, there may be overlap between
the following two:

[1] a bit pattern reachable from a valid payload + ECC pattern within
ecc.strength bitflips
[2] a bit pattern reachable from an erased state (all 0xff) within
ecc.strength bitflips

So, this feature may intercept ECC correctable patterns, then replace
[1] with [2].

After all, this feature can work safely only when ECC_THRESHOLD == 1,
i.e. detect erased pages without any bitflips.  This should be the
case most of the time.  If there is a bitflip or more, the driver will
fallback to the software method by using nand_check_erased_ecc_chunk().

Strangely enough, the driver still has to fill the buffer with 0xff
in case of INTR__ERASED_PAGE because the ECC correction engine has
already manipulated the data in the buffer before it judges erased
pages.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - memset(buf, 0xff, size) is necessary even if the page is completely
erased (all 0xff), strangely.

Changes in v5:
  - Set ECC_THRESHOLD to 1

Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 9 -
 drivers/mtd/nand/denali.h | 5 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d58ea17c0a69..1ded7cc00b1a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -552,6 +552,9 @@ static int denali_pio_read(struct denali_nand_info *denali, 
void *buf,
if (!(irq_status & INTR__PAGE_XFER_INC))
return -EIO;
 
+   if (irq_status & INTR__ERASED_PAGE)
+   memset(buf, 0xff, size);
+
return irq_status & ecc_err_mask ? -EBADMSG : 0;
 }
 
@@ -627,6 +630,9 @@ static int denali_dma_xfer(struct denali_nand_info *denali, 
void *buf,
denali_enable_dma(denali, false);
dma_sync_single_for_cpu(denali->dev, dma_addr, size, dir);
 
+   if (irq_status & INTR__ERASED_PAGE)
+   memset(buf, 0xff, size);
+
return ret;
 }
 
@@ -1397,7 +1403,8 @@ int denali_init(struct denali_nand_info *denali)
"chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
 
-   iowrite32(chip->ecc.strength, denali->flash_reg + ECC_CORRECTION);
+   iowrite32(MAKE_ECC_CORRECTION(chip->ecc.strength, 1),
+ denali->flash_reg + ECC_CORRECTION);
iowrite32(mtd->erasesize / mtd->writesize,
  denali->flash_reg + PAGES_PER_BLOCK);
iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index f5da52f09e34..657a794af695 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -110,6 +110,10 @@
 
 #define ECC_CORRECTION 0x1b0
 #define ECC_CORRECTION__VALUE  GENMASK(4, 0)
+#define ECC_CORRECTION__ERASE_THRESHOLDGENMASK(31, 16)
+#define MAKE_ECC_CORRECTION(val, thresh)   \
+   (((val) & (ECC_CORRECTION__VALUE)) | \
+   (((thresh) << 16) & (ECC_CORRECTION__ERASE_THRESHOLD)))
 
 #define READ_MODE  0x1c0
 #define READ_MODE__VALUE   GENMASK(3, 0)
@@ -233,6 +237,7 @@
 #define INTR__RST_COMP BIT(13)
 #define INTR__PIPE_CMD_ERR BIT(14)
 #define INTR__PAGE_XFER_INCBIT(15)
+#define INTR__ERASED_PAGE  BIT(16)
 
 #define PAGE_CNT(bank) (0x430 + (bank) * 0x50)
 #define ERR_PAGE_ADDR(bank)(0x440 + (bank) * 0x50)
-- 
2.7.4



[PATCH v6 14/18] mtd: nand: denali: support hardware-assisted erased page detection

2017-06-12 Thread Masahiro Yamada
Recent versions of this IP support automatic erased page detection.
If an erased page is detected on reads, the controller does not set
INTR__ECC_UNCOR_ERR, but INTR__ERASED_PAGE.

The detection of erased pages is based on the number of zeros in a
page; if the number of zeros is less than the value in the field
ERASED_THRESHOLD, the page is assumed as erased.

Please note ERASED_THRESHOLD specifies the number of zeros in a _page_
instead of an ECC chunk.  Moreover, the controller does not provide a
way to know the actual number of bitflips.

Actually, an erased page (all 0xff) is not an ECC correctable pattern
on the Denali ECC engine.  In other words, there may be overlap between
the following two:

[1] a bit pattern reachable from a valid payload + ECC pattern within
ecc.strength bitflips
[2] a bit pattern reachable from an erased state (all 0xff) within
ecc.strength bitflips

So, this feature may intercept ECC correctable patterns, then replace
[1] with [2].

After all, this feature can work safely only when ECC_THRESHOLD == 1,
i.e. detect erased pages without any bitflips.  This should be the
case most of the time.  If there is a bitflip or more, the driver will
fallback to the software method by using nand_check_erased_ecc_chunk().

Strangely enough, the driver still has to fill the buffer with 0xff
in case of INTR__ERASED_PAGE because the ECC correction engine has
already manipulated the data in the buffer before it judges erased
pages.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - memset(buf, 0xff, size) is necessary even if the page is completely
erased (all 0xff), strangely.

Changes in v5:
  - Set ECC_THRESHOLD to 1

Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 9 -
 drivers/mtd/nand/denali.h | 5 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d58ea17c0a69..1ded7cc00b1a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -552,6 +552,9 @@ static int denali_pio_read(struct denali_nand_info *denali, 
void *buf,
if (!(irq_status & INTR__PAGE_XFER_INC))
return -EIO;
 
+   if (irq_status & INTR__ERASED_PAGE)
+   memset(buf, 0xff, size);
+
return irq_status & ecc_err_mask ? -EBADMSG : 0;
 }
 
@@ -627,6 +630,9 @@ static int denali_dma_xfer(struct denali_nand_info *denali, 
void *buf,
denali_enable_dma(denali, false);
dma_sync_single_for_cpu(denali->dev, dma_addr, size, dir);
 
+   if (irq_status & INTR__ERASED_PAGE)
+   memset(buf, 0xff, size);
+
return ret;
 }
 
@@ -1397,7 +1403,8 @@ int denali_init(struct denali_nand_info *denali)
"chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
 
-   iowrite32(chip->ecc.strength, denali->flash_reg + ECC_CORRECTION);
+   iowrite32(MAKE_ECC_CORRECTION(chip->ecc.strength, 1),
+ denali->flash_reg + ECC_CORRECTION);
iowrite32(mtd->erasesize / mtd->writesize,
  denali->flash_reg + PAGES_PER_BLOCK);
iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index f5da52f09e34..657a794af695 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -110,6 +110,10 @@
 
 #define ECC_CORRECTION 0x1b0
 #define ECC_CORRECTION__VALUE  GENMASK(4, 0)
+#define ECC_CORRECTION__ERASE_THRESHOLDGENMASK(31, 16)
+#define MAKE_ECC_CORRECTION(val, thresh)   \
+   (((val) & (ECC_CORRECTION__VALUE)) | \
+   (((thresh) << 16) & (ECC_CORRECTION__ERASE_THRESHOLD)))
 
 #define READ_MODE  0x1c0
 #define READ_MODE__VALUE   GENMASK(3, 0)
@@ -233,6 +237,7 @@
 #define INTR__RST_COMP BIT(13)
 #define INTR__PIPE_CMD_ERR BIT(14)
 #define INTR__PAGE_XFER_INCBIT(15)
+#define INTR__ERASED_PAGE  BIT(16)
 
 #define PAGE_CNT(bank) (0x430 + (bank) * 0x50)
 #define ERR_PAGE_ADDR(bank)(0x440 + (bank) * 0x50)
-- 
2.7.4



[PATCH v6 18/18] mtd: nand: denali: avoid magic numbers and rename for clarification

2017-06-12 Thread Masahiro Yamada
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.

- We see '| 2' in several places.  This means Data Cycle in MAP11 mode.
  The Denali User's Guide says bit[1:0] of MAP11 is like follows:

  b'00 = Command Cycle
  b'01 = Address Cycle
  b'10 = Data Cycle

  So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.

- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
  magic number.  Actually, this accesses the data port of the Host
  Data/Command Interface.  So, this commit added DENALI_HOST_DATA.
  On the other hand, 'denali->flash_mem' gets access to the address
  port, so DENALI_HOST_ADDR was also added.

- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
  is a magic number.  0x1 means the erase operation.  Replace 0x1
  with DENALI_ERASE.

- Rename index_addr() to denali_host_write() for clarification and
  add denali_host_read() as a helper.

- Denali User's Guide says MAP{00,01,10,11} for access mode.  Match
  the macros with terminology in the IP document.

- Rename struct members as follows:
  flash_bank   -> active_bank(currently selected bank)
  flash_reg-> reg(base address of registers)
  flash_mem-> host   (base address of host interface)
  devnum   -> devs_per_cs(devices connected in parallel)
  bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Newly added

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/denali.c | 259 ++
 drivers/mtd/nand/denali.h |  15 +--
 drivers/mtd/nand/denali_dt.c  |  12 +-
 drivers/mtd/nand/denali_pci.c |  16 +--
 4 files changed, 153 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 3bcc886579c8..6aa78ca2439b 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -31,12 +31,26 @@ MODULE_LICENSE("GPL");
 
 #define DENALI_NAND_NAME"denali-nand"
 
-/*
- * indicates whether or not the internal value for the flash bank is
- * valid or not
- */
-#define CHIP_SELECT_INVALID-1
+/* Host Data/Command Interface */
+#define DENALI_HOST_ADDR   0x00
+#define DENALI_HOST_DATA   0x10
+
+#define DENALI_MAP00   (0 << 26)   /* direct access to buffer */
+#define DENALI_MAP01   (1 << 26)   /* read/write pages in PIO */
+#define DENALI_MAP10   (2 << 26)   /* higher-level control plane */
+#define DENALI_MAP11   (3 << 26)   /* direct controller access */
+
+/* MAP11 access cycle type */
+#define DENALI_MAP11_CMD   ((DENALI_MAP11) | 0)/* command cycle */
+#define DENALI_MAP11_ADDR  ((DENALI_MAP11) | 1)/* address cycle */
+#define DENALI_MAP11_DATA  ((DENALI_MAP11) | 2)/* data cycle */
 
+/* MAP11 commands */
+#define DENALI_ERASE   0x01
+
+#define DENALI_BANK(denali)((denali)->active_bank << 24)
+
+#define DENALI_INVALID_BANK-1
 #define DENALI_NR_BANKS4
 
 /*
@@ -56,23 +70,17 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
 }
 
-/*
- * this is a helper macro that allows us to
- * format the bank into the proper bits for the controller
- */
-#define BANK(x) ((x) << 24)
+static uint32_t denali_host_read(struct denali_nand_info *denali, uint32_t 
addr)
+{
+   iowrite32(addr, denali->host + DENALI_HOST_ADDR);
+   return ioread32(denali->host + DENALI_HOST_DATA);
+}
 
-/*
- * Certain operations for the denali NAND controller use an indexed mode to
- * read/write data. The operation is performed by writing the address value
- * of the command to the device memory followed by the data. This function
- * abstracts this common operation.
- */
-static void index_addr(struct denali_nand_info *denali,
-   uint32_t address, uint32_t data)
+static void denali_host_write(struct denali_nand_info *denali,
+ uint32_t addr, uint32_t data)
 {
-   iowrite32(address, denali->flash_mem);
-   iowrite32(data, denali->flash_mem + 0x10);
+   iowrite32(addr, denali->host + DENALI_HOST_ADDR);
+   iowrite32(data, denali->host + DENALI_HOST_DATA);
 }
 
 /*
@@ -81,7 +89,7 @@ static void index_addr(struct denali_nand_info *denali,
  */
 static void detect_max_banks(struct denali_nand_info *denali)
 {
-   uint32_t features = ioread32(denali->flash_reg + FEATURES);
+   uint32_t features = ioread32(denali->reg + FEATURES);
 
denali->max_banks = 1 << (features & FEATURES__N_BANKS);
 
@@ -95,8 +103,8 @@ static void denali_enable_irq(struct denali_nand_info 
*denali)
int i;
 
for (i = 0; i < DENALI_NR_BANKS; i++)
-   iowrite32(U32_MAX, denali->flash_reg + INTR_EN(i));
-   iowrite32(GLOBAL_INT_EN_FLAG, 

[PATCH v6 16/18] mtd: nand: denali: use non-managed kmalloc() for DMA buffer

2017-06-12 Thread Masahiro Yamada
As Russell and Lars stated in the discussion [1], using
devm_k*alloc() with DMA is not a good idea.

Let's use kmalloc (not kzalloc because no need for zero-out).
Also, allocate the buffer as late as possible because it must be
freed for any error that follows.

[1] https://lkml.org/lkml/2017/3/8/693

Signed-off-by: Masahiro Yamada 
Cc: Russell King 
Cc: Lars-Peter Clausen 
Acked-by: Robin Murphy 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 918b9b9bbe53..d37fb82f39ed 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "denali.h"
 
@@ -1343,13 +1344,6 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
-   denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize,
-  GFP_KERNEL);
-   if (!denali->buf) {
-   ret = -ENOMEM;
-   goto disable_irq;
-   }
-
if (ioread32(denali->flash_reg + FEATURES) & FEATURES__DMA)
denali->dma_avail = 1;
 
@@ -1434,17 +1428,30 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
+   /*
+* This buffer is DMA-mapped by denali_{read,write}_page_raw.  Do not
+* use devm_kmalloc() because the memory allocated by devm_ does not
+* guarantee DMA-safe alignment.
+*/
+   denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+   if (!denali->buf) {
+   ret = -ENOMEM;
+   goto disable_irq;
+   }
+
ret = nand_scan_tail(mtd);
if (ret)
-   goto disable_irq;
+   goto free_buf;
 
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
-   goto disable_irq;
+   goto free_buf;
}
return 0;
 
+free_buf:
+   kfree(denali->buf);
 disable_irq:
denali_disable_irq(denali);
 
@@ -1458,6 +1465,7 @@ void denali_remove(struct denali_nand_info *denali)
struct mtd_info *mtd = nand_to_mtd(>nand);
 
nand_release(mtd);
+   kfree(denali->buf);
denali_disable_irq(denali);
 }
 EXPORT_SYMBOL(denali_remove);
-- 
2.7.4



[PATCH v6 16/18] mtd: nand: denali: use non-managed kmalloc() for DMA buffer

2017-06-12 Thread Masahiro Yamada
As Russell and Lars stated in the discussion [1], using
devm_k*alloc() with DMA is not a good idea.

Let's use kmalloc (not kzalloc because no need for zero-out).
Also, allocate the buffer as late as possible because it must be
freed for any error that follows.

[1] https://lkml.org/lkml/2017/3/8/693

Signed-off-by: Masahiro Yamada 
Cc: Russell King 
Cc: Lars-Peter Clausen 
Acked-by: Robin Murphy 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 918b9b9bbe53..d37fb82f39ed 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "denali.h"
 
@@ -1343,13 +1344,6 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
-   denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize,
-  GFP_KERNEL);
-   if (!denali->buf) {
-   ret = -ENOMEM;
-   goto disable_irq;
-   }
-
if (ioread32(denali->flash_reg + FEATURES) & FEATURES__DMA)
denali->dma_avail = 1;
 
@@ -1434,17 +1428,30 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
+   /*
+* This buffer is DMA-mapped by denali_{read,write}_page_raw.  Do not
+* use devm_kmalloc() because the memory allocated by devm_ does not
+* guarantee DMA-safe alignment.
+*/
+   denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+   if (!denali->buf) {
+   ret = -ENOMEM;
+   goto disable_irq;
+   }
+
ret = nand_scan_tail(mtd);
if (ret)
-   goto disable_irq;
+   goto free_buf;
 
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
-   goto disable_irq;
+   goto free_buf;
}
return 0;
 
+free_buf:
+   kfree(denali->buf);
 disable_irq:
denali_disable_irq(denali);
 
@@ -1458,6 +1465,7 @@ void denali_remove(struct denali_nand_info *denali)
struct mtd_info *mtd = nand_to_mtd(>nand);
 
nand_release(mtd);
+   kfree(denali->buf);
denali_disable_irq(denali);
 }
 EXPORT_SYMBOL(denali_remove);
-- 
2.7.4



[PATCH v6 08/18] mtd: nand: denali: fix bank reset function to detect the number of chips

2017-06-12 Thread Masahiro Yamada
The nand_scan_ident() iterates over maxchips, and calls nand_reset()
for each.  This driver currently passes the maximum number of banks
(=chip selects) supported by the controller as maxchips.  So, maxchips
is typically 4 or 8.  Usually, less number of NAND chips are connected
to the controller.

This can be a problem for ONFi devices.  Now, this driver implements
->setup_data_interface() hook, so nand_setup_data_interface() issues
Set Features (0xEF) command, which waits until the chip returns R/B#
response.  If no chip there, we know it never happens, but the driver
still ends up with waiting for a long time.  It will finally bail-out
with timeout error and the driver will work with existing chips, but
unnecessary wait will give a bad user experience.

The denali_nand_reset() polls the INTR__RST_COMP and INTR__TIME_OUT
bits, but they are always set even if not NAND chip is connected to
that bank.  To know the chip existence, INTR__INT_ACT bit must be
checked; this flag is set only when R/B# is toggled.  Since the Reset
(0xFF) command toggles the R/B# pin, this can be used to know the
actual number of chips, and update denali->max_banks.

Signed-off-by: Masahiro Yamada 
---

Boris mentioned this information can be retrieved from DT
(http://patchwork.ozlabs.org/patch/745118/), but I'd like to
take time for controller/chip decoupling.  I am tackling on
that, but not completed yet.

I believe this commit stands for denali_pci, at least I do not
know how to get the number of chips from PCI.


Changes in v6: None
Changes in v5: None
Changes in v4:
  - Reword commit-log

Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 52 +--
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 09a14fafa967..61a2ee9fb367 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -85,33 +85,6 @@ static void index_addr(struct denali_nand_info *denali,
iowrite32(data, denali->flash_mem + 0x10);
 }
 
-/* Reset the flash controller */
-static uint16_t denali_nand_reset(struct denali_nand_info *denali)
-{
-   int i;
-
-   for (i = 0; i < denali->max_banks; i++)
-   iowrite32(INTR__RST_COMP | INTR__TIME_OUT,
-   denali->flash_reg + INTR_STATUS(i));
-
-   for (i = 0; i < denali->max_banks; i++) {
-   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
-   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   (INTR__RST_COMP | INTR__TIME_OUT)))
-   cpu_relax();
-   if (ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   INTR__TIME_OUT)
-   dev_dbg(denali->dev,
-   "NAND Reset operation timed out on bank %d\n", i);
-   }
-
-   for (i = 0; i < denali->max_banks; i++)
-   iowrite32(INTR__RST_COMP | INTR__TIME_OUT,
- denali->flash_reg + INTR_STATUS(i));
-
-   return PASS;
-}
-
 /*
  * Use the configuration feature register to determine the maximum number of
  * banks that the hardware supports.
@@ -998,7 +971,28 @@ static int denali_setup_data_interface(struct mtd_info 
*mtd, int chipnr,
return 0;
 }
 
-/* Initialization code to bring the device up to a known good state */
+static void denali_reset_banks(struct denali_nand_info *denali)
+{
+   int i;
+
+   denali_clear_irq_all(denali);
+
+   for (i = 0; i < denali->max_banks; i++) {
+   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
+   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
+   (INTR__RST_COMP | INTR__TIME_OUT)))
+   cpu_relax();
+   if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
+ INTR__INT_ACT))
+   break;
+   }
+
+   dev_dbg(denali->dev, "%d chips connected\n", i);
+   denali->max_banks = i;
+
+   denali_clear_irq_all(denali);
+}
+
 static void denali_hw_init(struct denali_nand_info *denali)
 {
/*
@@ -1018,7 +1012,7 @@ static void denali_hw_init(struct denali_nand_info 
*denali)
denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali);
-   denali_nand_reset(denali);
+   denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE);
-- 
2.7.4



[PATCH v6 00/18] mtd: nand: denali: Denali NAND IP patch bomb

2017-06-12 Thread Masahiro Yamada

This patch series intends to solve various problems.

[1] The driver just retrieves the OOB area as-is
whereas the controller uses syndrome page layout.
[2] ONFi devices are not working
[3] It can not read Bad Block Marker

Outstanding changes are:
 - Fix raw/oob callbacks for syndrome page layout
 - Implement setup_data_interface() callback
 - Fix/implement more commands for ONFi devices
 - Allow to skip the driver internal bounce buffer
 - Support PIO in case DMA is not supported
 - Switch from ->cmdfunc over to ->cmd_ctrl

18 patches were merged by v2.
11 patches were merged by v3.
2 patches were merged by v4.
5 patches were merged by v5.
Here is the rest of the series.

v1: https://lkml.org/lkml/2016/11/26/144
v2: https://lkml.org/lkml/2017/3/22/804
v3: https://lkml.org/lkml/2017/3/30/90
v4: https://lkml.org/lkml/2017/6/5/1005

Masahiro Yamada (18):
  mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS
  mtd: nand: denali: remove unneeded find_valid_banks()
  mtd: nand: denali: handle timing parameters by setup_data_interface()
  mtd: nand: denali: rework interrupt handling
  mtd: nand: denali: fix NAND_CMD_STATUS handling
  mtd: nand: denali: fix NAND_CMD_PARAM handling
  mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc
  mtd: nand: denali: fix bank reset function to detect the number of
chips
  mtd: nand: denali: use interrupt instead of polling for bank reset
  mtd: nand: denali: propagate page to helpers via function argument
  mtd: nand: denali: merge struct nand_buf into struct denali_nand_info
  mtd: nand: denali: use flag instead of register macro for direction
  mtd: nand: denali: fix raw and oob accessors for syndrome page layout
  mtd: nand: denali: support hardware-assisted erased page detection
  mtd: nand: denali: skip driver internal bounce buffer when possible
  mtd: nand: denali: use non-managed kmalloc() for DMA buffer
  mtd: nand: denali: enable bad block table scan
  mtd: nand: denali: avoid magic numbers and rename for clarification

 drivers/mtd/nand/denali.c | 1715 ++---
 drivers/mtd/nand/denali.h |   63 +-
 drivers/mtd/nand/denali_dt.c  |   15 +-
 drivers/mtd/nand/denali_pci.c |   22 +-
 4 files changed, 800 insertions(+), 1015 deletions(-)

-- 
2.7.4



[PATCH v6 15/18] mtd: nand: denali: skip driver internal bounce buffer when possible

2017-06-12 Thread Masahiro Yamada
For ecc->read_page() and ecc->write_page(), it is possible to call
dma_map_single() against the given buffer.  This bypasses the driver
internal bounce buffer and save the memcpy().

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
  - Remove dma_unmap_single() from denali_remove()

Changes in v3:
  - Set chip->buf_align to 16

Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 38 --
 1 file changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 1ded7cc00b1a..918b9b9bbe53 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -592,12 +592,16 @@ static int denali_pio_xfer(struct denali_nand_info 
*denali, void *buf,
 static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
   size_t size, int page, int raw, int write)
 {
-   dma_addr_t dma_addr = denali->dma_addr;
+   dma_addr_t dma_addr;
uint32_t irq_mask, irq_status, ecc_err_mask;
enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
int ret = 0;
 
-   dma_sync_single_for_device(denali->dev, dma_addr, size, dir);
+   dma_addr = dma_map_single(denali->dev, buf, size, dir);
+   if (dma_mapping_error(denali->dev, dma_addr)) {
+   dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
+   return denali_pio_xfer(denali, buf, size, page, raw, write);
+   }
 
if (write) {
/*
@@ -628,7 +632,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, 
void *buf,
ret = -EBADMSG;
 
denali_enable_dma(denali, false);
-   dma_sync_single_for_cpu(denali->dev, dma_addr, size, dir);
+   dma_unmap_single(denali->dev, dma_addr, size, dir);
 
if (irq_status & INTR__ERASED_PAGE)
memset(buf, 0xff, size);
@@ -814,12 +818,10 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
int stat = 0;
int ret;
 
-   ret = denali_data_xfer(denali, denali->buf, mtd->writesize, page, 0, 0);
+   ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
if (ret && ret != -EBADMSG)
return ret;
 
-   memcpy(buf, denali->buf, mtd->writesize);
-
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
stat = denali_hw_ecc_fixup(mtd, denali, _ecc_flags);
else if (ret == -EBADMSG)
@@ -923,10 +925,8 @@ static int denali_write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
 
-   memcpy(denali->buf, buf, mtd->writesize);
-
-   return denali_data_xfer(denali, denali->buf, mtd->writesize, page,
-   0, 1);
+   return denali_data_xfer(denali, (void *)buf, mtd->writesize,
+   page, 0, 1);
 }
 
 static void denali_select_chip(struct mtd_info *mtd, int chip)
@@ -1365,14 +1365,8 @@ int denali_init(struct denali_nand_info *denali)
}
 
if (denali->dma_avail) {
-   denali->dma_addr = dma_map_single(denali->dev, denali->buf,
- mtd->writesize + mtd->oobsize,
- DMA_BIDIRECTIONAL);
-   if (dma_mapping_error(denali->dev, denali->dma_addr)) {
-   dev_info(denali->dev,
-"Failed to map DMA buffer. Disabling DMA.\n");
-   denali->dma_avail = 0;
-   };
+   chip->options |= NAND_USE_BOUNCE_BUFFER;
+   chip->buf_align = 16;
}
 
/*
@@ -1462,16 +1456,8 @@ EXPORT_SYMBOL(denali_init);
 void denali_remove(struct denali_nand_info *denali)
 {
struct mtd_info *mtd = nand_to_mtd(>nand);
-   /*
-* Pre-compute DMA buffer size to avoid any problems in case
-* nand_release() ever changes in a way that mtd->writesize and
-* mtd->oobsize are not reliable after this call.
-*/
-   int bufsize = mtd->writesize + mtd->oobsize;
 
nand_release(mtd);
denali_disable_irq(denali);
-   dma_unmap_single(denali->dev, denali->dma_addr, bufsize,
-DMA_BIDIRECTIONAL);
 }
 EXPORT_SYMBOL(denali_remove);
-- 
2.7.4



[PATCH v6 05/18] mtd: nand: denali: fix NAND_CMD_STATUS handling

2017-06-12 Thread Masahiro Yamada
The current NAND_CMD_STATUS handling is weird; it just reads the
WRITE_PROTECT register, and returns NAND_STATUS_WP if it is set.

It does not send Read Status (0x70) command, so it is not helpful
for checking the current device status.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d7e7555a3d73..4bf93232ca30 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -107,21 +107,6 @@ static void write_byte_to_buf(struct denali_nand_info 
*denali, uint8_t byte)
denali->buf.buf[denali->buf.tail++] = byte;
 }
 
-/* reads the status of the device */
-static void read_status(struct denali_nand_info *denali)
-{
-   uint32_t cmd;
-
-   /* initialize the data buffer to store status */
-   reset_buf(denali);
-
-   cmd = ioread32(denali->flash_reg + WRITE_PROTECT);
-   if (cmd)
-   write_byte_to_buf(denali, NAND_STATUS_WP);
-   else
-   write_byte_to_buf(denali, 0);
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -893,7 +878,11 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
 
switch (cmd) {
case NAND_CMD_STATUS:
-   read_status(denali);
+   reset_buf(denali);
+   addr = MODE_11 | BANK(denali->flash_bank);
+   index_addr(denali, addr | 0, cmd);
+   index_addr_read_data(denali, addr | 2, );
+   write_byte_to_buf(denali, id);
break;
case NAND_CMD_READID:
case NAND_CMD_PARAM:
-- 
2.7.4



[PATCH v6 01/18] mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS

2017-06-12 Thread Masahiro Yamada
The denali_cmdfunc() actually does nothing valuable for
NAND_CMD_{PAGEPROG,READ0,SEQIN}.

For NAND_CMD_{READ0,SEQIN}, it copies "page" to "denali->page", then
denali_read_page(_raw) compares them just for the sanity check.
(Inconsistently, this check is missing from denali_write_page(_raw).)

The Denali controller is equipped with high level read/write interface,
so let's skip unneeded call of cmdfunc().

If NAND_ECC_CUSTOM_PAGE_ACCESS is set, nand_write_page() will not
call ->waitfunc hook.  So, ->write_page(_raw) hooks should directly
return -EIO on failure.  The error handling of page writes will be
much simpler.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Squash two commits to adjust to commit 41145649f4ac
(mtd: nand: Wait for PAGEPROG to finish in drivers setting 
NAND_ECC_CUSTOM_PAGE_ACCESS)

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 41 -
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 2b4618bb8d72..7133a33b4ad3 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -998,13 +998,16 @@ static void denali_setup_dma(struct denali_nand_info 
*denali, int op)
  * configuration details.
  */
 static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
-   const uint8_t *buf, bool raw_xfer)
+   const uint8_t *buf, int page, bool raw_xfer)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
dma_addr_t addr = denali->buf.dma_buf;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
+   int ret = 0;
+
+   denali->page = page;
 
/*
 * if it is a raw xfer, we want to disable ecc and send the spare area.
@@ -1036,13 +1039,13 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
if (irq_status == 0) {
dev_err(denali->dev, "timeout on write_page (type = %d)\n",
raw_xfer);
-   denali->status = NAND_STATUS_FAIL;
+   ret = -EIO;
}
 
denali_enable_dma(denali, false);
dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);
 
-   return 0;
+   return ret;
 }
 
 /* NAND core entry points */
@@ -1059,7 +1062,7 @@ static int denali_write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 * for regular page writes, we let HW handle all the ECC
 * data written to the device.
 */
-   return write_page(mtd, chip, buf, false);
+   return write_page(mtd, chip, buf, page, false);
 }
 
 /*
@@ -1075,7 +1078,7 @@ static int denali_write_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
 * for raw page writes, we want to disable ECC and simply write
 * whatever data is in the buffer.
 */
-   return write_page(mtd, chip, buf, true);
+   return write_page(mtd, chip, buf, page, true);
 }
 
 static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
@@ -1105,12 +1108,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
unsigned long uncor_ecc_flags = 0;
int stat = 0;
 
-   if (page != denali->page) {
-   dev_err(denali->dev,
-   "IN %s: page %d is not equal to denali->page %d",
-   __func__, page, denali->page);
-   BUG();
-   }
+   denali->page = page;
 
setup_ecc_for_xfer(denali, true, false);
 
@@ -1154,12 +1152,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_mask = INTR__DMA_CMD_COMP;
 
-   if (page != denali->page) {
-   dev_err(denali->dev,
-   "IN %s: page %d is not equal to denali->page %d",
-   __func__, page, denali->page);
-   BUG();
-   }
+   denali->page = page;
 
setup_ecc_for_xfer(denali, false, true);
denali_enable_dma(denali, true);
@@ -1204,12 +1197,7 @@ static void denali_select_chip(struct mtd_info *mtd, int 
chip)
 
 static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
 {
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   int status = denali->status;
-
-   denali->status = 0;
-
-   return status;
+   return 0;
 }
 
 static int denali_erase(struct mtd_info *mtd, int page)
@@ -1238,8 +1226,6 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
int i;
 
switch (cmd) {
-   case NAND_CMD_PAGEPROG:
-   break;
case NAND_CMD_STATUS:
read_status(denali);
break;

[PATCH v6 08/18] mtd: nand: denali: fix bank reset function to detect the number of chips

2017-06-12 Thread Masahiro Yamada
The nand_scan_ident() iterates over maxchips, and calls nand_reset()
for each.  This driver currently passes the maximum number of banks
(=chip selects) supported by the controller as maxchips.  So, maxchips
is typically 4 or 8.  Usually, less number of NAND chips are connected
to the controller.

This can be a problem for ONFi devices.  Now, this driver implements
->setup_data_interface() hook, so nand_setup_data_interface() issues
Set Features (0xEF) command, which waits until the chip returns R/B#
response.  If no chip there, we know it never happens, but the driver
still ends up with waiting for a long time.  It will finally bail-out
with timeout error and the driver will work with existing chips, but
unnecessary wait will give a bad user experience.

The denali_nand_reset() polls the INTR__RST_COMP and INTR__TIME_OUT
bits, but they are always set even if not NAND chip is connected to
that bank.  To know the chip existence, INTR__INT_ACT bit must be
checked; this flag is set only when R/B# is toggled.  Since the Reset
(0xFF) command toggles the R/B# pin, this can be used to know the
actual number of chips, and update denali->max_banks.

Signed-off-by: Masahiro Yamada 
---

Boris mentioned this information can be retrieved from DT
(http://patchwork.ozlabs.org/patch/745118/), but I'd like to
take time for controller/chip decoupling.  I am tackling on
that, but not completed yet.

I believe this commit stands for denali_pci, at least I do not
know how to get the number of chips from PCI.


Changes in v6: None
Changes in v5: None
Changes in v4:
  - Reword commit-log

Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 52 +--
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 09a14fafa967..61a2ee9fb367 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -85,33 +85,6 @@ static void index_addr(struct denali_nand_info *denali,
iowrite32(data, denali->flash_mem + 0x10);
 }
 
-/* Reset the flash controller */
-static uint16_t denali_nand_reset(struct denali_nand_info *denali)
-{
-   int i;
-
-   for (i = 0; i < denali->max_banks; i++)
-   iowrite32(INTR__RST_COMP | INTR__TIME_OUT,
-   denali->flash_reg + INTR_STATUS(i));
-
-   for (i = 0; i < denali->max_banks; i++) {
-   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
-   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   (INTR__RST_COMP | INTR__TIME_OUT)))
-   cpu_relax();
-   if (ioread32(denali->flash_reg + INTR_STATUS(i)) &
-   INTR__TIME_OUT)
-   dev_dbg(denali->dev,
-   "NAND Reset operation timed out on bank %d\n", i);
-   }
-
-   for (i = 0; i < denali->max_banks; i++)
-   iowrite32(INTR__RST_COMP | INTR__TIME_OUT,
- denali->flash_reg + INTR_STATUS(i));
-
-   return PASS;
-}
-
 /*
  * Use the configuration feature register to determine the maximum number of
  * banks that the hardware supports.
@@ -998,7 +971,28 @@ static int denali_setup_data_interface(struct mtd_info 
*mtd, int chipnr,
return 0;
 }
 
-/* Initialization code to bring the device up to a known good state */
+static void denali_reset_banks(struct denali_nand_info *denali)
+{
+   int i;
+
+   denali_clear_irq_all(denali);
+
+   for (i = 0; i < denali->max_banks; i++) {
+   iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
+   while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
+   (INTR__RST_COMP | INTR__TIME_OUT)))
+   cpu_relax();
+   if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
+ INTR__INT_ACT))
+   break;
+   }
+
+   dev_dbg(denali->dev, "%d chips connected\n", i);
+   denali->max_banks = i;
+
+   denali_clear_irq_all(denali);
+}
+
 static void denali_hw_init(struct denali_nand_info *denali)
 {
/*
@@ -1018,7 +1012,7 @@ static void denali_hw_init(struct denali_nand_info 
*denali)
denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali);
-   denali_nand_reset(denali);
+   denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE);
-- 
2.7.4



[PATCH v6 00/18] mtd: nand: denali: Denali NAND IP patch bomb

2017-06-12 Thread Masahiro Yamada

This patch series intends to solve various problems.

[1] The driver just retrieves the OOB area as-is
whereas the controller uses syndrome page layout.
[2] ONFi devices are not working
[3] It can not read Bad Block Marker

Outstanding changes are:
 - Fix raw/oob callbacks for syndrome page layout
 - Implement setup_data_interface() callback
 - Fix/implement more commands for ONFi devices
 - Allow to skip the driver internal bounce buffer
 - Support PIO in case DMA is not supported
 - Switch from ->cmdfunc over to ->cmd_ctrl

18 patches were merged by v2.
11 patches were merged by v3.
2 patches were merged by v4.
5 patches were merged by v5.
Here is the rest of the series.

v1: https://lkml.org/lkml/2016/11/26/144
v2: https://lkml.org/lkml/2017/3/22/804
v3: https://lkml.org/lkml/2017/3/30/90
v4: https://lkml.org/lkml/2017/6/5/1005

Masahiro Yamada (18):
  mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS
  mtd: nand: denali: remove unneeded find_valid_banks()
  mtd: nand: denali: handle timing parameters by setup_data_interface()
  mtd: nand: denali: rework interrupt handling
  mtd: nand: denali: fix NAND_CMD_STATUS handling
  mtd: nand: denali: fix NAND_CMD_PARAM handling
  mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc
  mtd: nand: denali: fix bank reset function to detect the number of
chips
  mtd: nand: denali: use interrupt instead of polling for bank reset
  mtd: nand: denali: propagate page to helpers via function argument
  mtd: nand: denali: merge struct nand_buf into struct denali_nand_info
  mtd: nand: denali: use flag instead of register macro for direction
  mtd: nand: denali: fix raw and oob accessors for syndrome page layout
  mtd: nand: denali: support hardware-assisted erased page detection
  mtd: nand: denali: skip driver internal bounce buffer when possible
  mtd: nand: denali: use non-managed kmalloc() for DMA buffer
  mtd: nand: denali: enable bad block table scan
  mtd: nand: denali: avoid magic numbers and rename for clarification

 drivers/mtd/nand/denali.c | 1715 ++---
 drivers/mtd/nand/denali.h |   63 +-
 drivers/mtd/nand/denali_dt.c  |   15 +-
 drivers/mtd/nand/denali_pci.c |   22 +-
 4 files changed, 800 insertions(+), 1015 deletions(-)

-- 
2.7.4



[PATCH v6 15/18] mtd: nand: denali: skip driver internal bounce buffer when possible

2017-06-12 Thread Masahiro Yamada
For ecc->read_page() and ecc->write_page(), it is possible to call
dma_map_single() against the given buffer.  This bypasses the driver
internal bounce buffer and save the memcpy().

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
  - Remove dma_unmap_single() from denali_remove()

Changes in v3:
  - Set chip->buf_align to 16

Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 38 --
 1 file changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 1ded7cc00b1a..918b9b9bbe53 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -592,12 +592,16 @@ static int denali_pio_xfer(struct denali_nand_info 
*denali, void *buf,
 static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
   size_t size, int page, int raw, int write)
 {
-   dma_addr_t dma_addr = denali->dma_addr;
+   dma_addr_t dma_addr;
uint32_t irq_mask, irq_status, ecc_err_mask;
enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
int ret = 0;
 
-   dma_sync_single_for_device(denali->dev, dma_addr, size, dir);
+   dma_addr = dma_map_single(denali->dev, buf, size, dir);
+   if (dma_mapping_error(denali->dev, dma_addr)) {
+   dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
+   return denali_pio_xfer(denali, buf, size, page, raw, write);
+   }
 
if (write) {
/*
@@ -628,7 +632,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, 
void *buf,
ret = -EBADMSG;
 
denali_enable_dma(denali, false);
-   dma_sync_single_for_cpu(denali->dev, dma_addr, size, dir);
+   dma_unmap_single(denali->dev, dma_addr, size, dir);
 
if (irq_status & INTR__ERASED_PAGE)
memset(buf, 0xff, size);
@@ -814,12 +818,10 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
int stat = 0;
int ret;
 
-   ret = denali_data_xfer(denali, denali->buf, mtd->writesize, page, 0, 0);
+   ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
if (ret && ret != -EBADMSG)
return ret;
 
-   memcpy(buf, denali->buf, mtd->writesize);
-
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
stat = denali_hw_ecc_fixup(mtd, denali, _ecc_flags);
else if (ret == -EBADMSG)
@@ -923,10 +925,8 @@ static int denali_write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
 
-   memcpy(denali->buf, buf, mtd->writesize);
-
-   return denali_data_xfer(denali, denali->buf, mtd->writesize, page,
-   0, 1);
+   return denali_data_xfer(denali, (void *)buf, mtd->writesize,
+   page, 0, 1);
 }
 
 static void denali_select_chip(struct mtd_info *mtd, int chip)
@@ -1365,14 +1365,8 @@ int denali_init(struct denali_nand_info *denali)
}
 
if (denali->dma_avail) {
-   denali->dma_addr = dma_map_single(denali->dev, denali->buf,
- mtd->writesize + mtd->oobsize,
- DMA_BIDIRECTIONAL);
-   if (dma_mapping_error(denali->dev, denali->dma_addr)) {
-   dev_info(denali->dev,
-"Failed to map DMA buffer. Disabling DMA.\n");
-   denali->dma_avail = 0;
-   };
+   chip->options |= NAND_USE_BOUNCE_BUFFER;
+   chip->buf_align = 16;
}
 
/*
@@ -1462,16 +1456,8 @@ EXPORT_SYMBOL(denali_init);
 void denali_remove(struct denali_nand_info *denali)
 {
struct mtd_info *mtd = nand_to_mtd(>nand);
-   /*
-* Pre-compute DMA buffer size to avoid any problems in case
-* nand_release() ever changes in a way that mtd->writesize and
-* mtd->oobsize are not reliable after this call.
-*/
-   int bufsize = mtd->writesize + mtd->oobsize;
 
nand_release(mtd);
denali_disable_irq(denali);
-   dma_unmap_single(denali->dev, denali->dma_addr, bufsize,
-DMA_BIDIRECTIONAL);
 }
 EXPORT_SYMBOL(denali_remove);
-- 
2.7.4



[PATCH v6 05/18] mtd: nand: denali: fix NAND_CMD_STATUS handling

2017-06-12 Thread Masahiro Yamada
The current NAND_CMD_STATUS handling is weird; it just reads the
WRITE_PROTECT register, and returns NAND_STATUS_WP if it is set.

It does not send Read Status (0x70) command, so it is not helpful
for checking the current device status.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d7e7555a3d73..4bf93232ca30 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -107,21 +107,6 @@ static void write_byte_to_buf(struct denali_nand_info 
*denali, uint8_t byte)
denali->buf.buf[denali->buf.tail++] = byte;
 }
 
-/* reads the status of the device */
-static void read_status(struct denali_nand_info *denali)
-{
-   uint32_t cmd;
-
-   /* initialize the data buffer to store status */
-   reset_buf(denali);
-
-   cmd = ioread32(denali->flash_reg + WRITE_PROTECT);
-   if (cmd)
-   write_byte_to_buf(denali, NAND_STATUS_WP);
-   else
-   write_byte_to_buf(denali, 0);
-}
-
 /* Reset the flash controller */
 static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
@@ -893,7 +878,11 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
 
switch (cmd) {
case NAND_CMD_STATUS:
-   read_status(denali);
+   reset_buf(denali);
+   addr = MODE_11 | BANK(denali->flash_bank);
+   index_addr(denali, addr | 0, cmd);
+   index_addr_read_data(denali, addr | 2, );
+   write_byte_to_buf(denali, id);
break;
case NAND_CMD_READID:
case NAND_CMD_PARAM:
-- 
2.7.4



[PATCH v6 01/18] mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS

2017-06-12 Thread Masahiro Yamada
The denali_cmdfunc() actually does nothing valuable for
NAND_CMD_{PAGEPROG,READ0,SEQIN}.

For NAND_CMD_{READ0,SEQIN}, it copies "page" to "denali->page", then
denali_read_page(_raw) compares them just for the sanity check.
(Inconsistently, this check is missing from denali_write_page(_raw).)

The Denali controller is equipped with high level read/write interface,
so let's skip unneeded call of cmdfunc().

If NAND_ECC_CUSTOM_PAGE_ACCESS is set, nand_write_page() will not
call ->waitfunc hook.  So, ->write_page(_raw) hooks should directly
return -EIO on failure.  The error handling of page writes will be
much simpler.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Squash two commits to adjust to commit 41145649f4ac
(mtd: nand: Wait for PAGEPROG to finish in drivers setting 
NAND_ECC_CUSTOM_PAGE_ACCESS)

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 41 -
 drivers/mtd/nand/denali.h |  1 -
 2 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 2b4618bb8d72..7133a33b4ad3 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -998,13 +998,16 @@ static void denali_setup_dma(struct denali_nand_info 
*denali, int op)
  * configuration details.
  */
 static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
-   const uint8_t *buf, bool raw_xfer)
+   const uint8_t *buf, int page, bool raw_xfer)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
dma_addr_t addr = denali->buf.dma_buf;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
+   int ret = 0;
+
+   denali->page = page;
 
/*
 * if it is a raw xfer, we want to disable ecc and send the spare area.
@@ -1036,13 +1039,13 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
if (irq_status == 0) {
dev_err(denali->dev, "timeout on write_page (type = %d)\n",
raw_xfer);
-   denali->status = NAND_STATUS_FAIL;
+   ret = -EIO;
}
 
denali_enable_dma(denali, false);
dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);
 
-   return 0;
+   return ret;
 }
 
 /* NAND core entry points */
@@ -1059,7 +1062,7 @@ static int denali_write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 * for regular page writes, we let HW handle all the ECC
 * data written to the device.
 */
-   return write_page(mtd, chip, buf, false);
+   return write_page(mtd, chip, buf, page, false);
 }
 
 /*
@@ -1075,7 +1078,7 @@ static int denali_write_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
 * for raw page writes, we want to disable ECC and simply write
 * whatever data is in the buffer.
 */
-   return write_page(mtd, chip, buf, true);
+   return write_page(mtd, chip, buf, page, true);
 }
 
 static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
@@ -1105,12 +1108,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
unsigned long uncor_ecc_flags = 0;
int stat = 0;
 
-   if (page != denali->page) {
-   dev_err(denali->dev,
-   "IN %s: page %d is not equal to denali->page %d",
-   __func__, page, denali->page);
-   BUG();
-   }
+   denali->page = page;
 
setup_ecc_for_xfer(denali, true, false);
 
@@ -1154,12 +1152,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_mask = INTR__DMA_CMD_COMP;
 
-   if (page != denali->page) {
-   dev_err(denali->dev,
-   "IN %s: page %d is not equal to denali->page %d",
-   __func__, page, denali->page);
-   BUG();
-   }
+   denali->page = page;
 
setup_ecc_for_xfer(denali, false, true);
denali_enable_dma(denali, true);
@@ -1204,12 +1197,7 @@ static void denali_select_chip(struct mtd_info *mtd, int 
chip)
 
 static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
 {
-   struct denali_nand_info *denali = mtd_to_denali(mtd);
-   int status = denali->status;
-
-   denali->status = 0;
-
-   return status;
+   return 0;
 }
 
 static int denali_erase(struct mtd_info *mtd, int page)
@@ -1238,8 +1226,6 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned 
int cmd, int col,
int i;
 
switch (cmd) {
-   case NAND_CMD_PAGEPROG:
-   break;
case NAND_CMD_STATUS:
read_status(denali);
break;
@@ -1259,10 +1245,6 @@ static 

[PATCH v6 13/18] mtd: nand: denali: fix raw and oob accessors for syndrome page layout

2017-06-12 Thread Masahiro Yamada
The Denali IP adopts the syndrome page layout; payload and ECC are
interleaved, with BBM area always placed at the beginning of OOB.

The figure below shows the page organization for ecc->steps == 2:

  |||---|
  |||   |
  |||   |
  |Payload0||   |
  |||   |
  |||   |
  |||   |
  |||  in-band  |
  |  ECC0  ||   area|
  |||   |
  |||   |
  |||   |
  |Payload1||   |
  |||   |
  |||   |
  |||---|
  |  BBM   ||   |
  |||   |
  |Payload1 (cont.)||   |
  |||out-of-band|
  |  ECC1  ||area   |
  |||   |
  |OOB free||   |
  |||---|

The current raw / oob accessors do not take that into consideration,
so in-band and out-of-band data are transferred as stored in the
device.  In the case above,

  in-band:  Payload0 + ECC0 + Payload1(partial)
  out-of-band:  BBM + Payload1(cont.) + ECC1 + OOB-free

This is wrong.  As the comment block of struct nand_ecc_ctrl says,
driver callbacks must hide the specific layout used by the hardware
and always return contiguous in-band and out-of-band data.

The current implementation is completely screwed-up, so read/write
callbacks must be re-worked.

Also, it is reasonable to support PIO transfer in case DMA may not
work for some reasons.  Actually, the Data DMA may not be equipped
depending on the configuration of the RTL.  This can be checked by
reading the bit 4 of the FEATURES register.  Even if the controller
has the DMA support, dma_set_mask() and dma_map_single() could fail.
In either case, the driver can fall back to the PIO transfer.  Slower
access would be better than giving up.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Minor cleanup to deprecate {write,read}_data_{to,from}_flash_mem
  - Remove unnecessary MAP10 command for MAIN_(SPARE_)ACCESS

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 650 +++---
 drivers/mtd/nand/denali.h |   3 +-
 2 files changed, 391 insertions(+), 262 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 03b75045d603..d58ea17c0a69 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -56,14 +56,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
 }
 
 /*
- * These constants are defined by the driver to enable common driver
- * configuration options.
- */
-#define SPARE_ACCESS   0x41
-#define MAIN_ACCESS0x42
-#define MAIN_SPARE_ACCESS  0x43
-
-/*
  * this is a helper macro that allows us to
  * format the bank into the proper bits for the controller
  */
@@ -246,173 +238,80 @@ static void denali_write_byte(struct mtd_info *mtd, 
uint8_t byte)
index_addr(denali, MODE_11 | BANK(denali->flash_bank) | 2, byte);
 }
 
-static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+static void denali_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t type;
-
-   if (ctrl & NAND_CLE)
-   type = 0;
-   else if (ctrl & NAND_ALE)
-   type = 1;
-   else
-   return;
+   int i;
 
-   /*
-* Some commands are followed by chip->dev_ready or chip->waitfunc.
-* irq_status must be cleared here to catch the R/B# interrupt later.
-*/
-   if (ctrl & NAND_CTRL_CHANGE)
-   denali_reset_irq(denali);
+   iowrite32(MODE_11 | BANK(denali->flash_bank) | 2, denali->flash_mem);
 
-   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | type, dat);
+   for (i = 0; i < len; i++)
+   buf[i] = ioread32(denali->flash_mem + 0x10);
 }
 
-static int denali_dev_ready(struct mtd_info *mtd)
+static void denali_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
+   int i;
 
-   return !!(denali_check_irq(denali) & INTR__INT_ACT);
-}
-
-/*
- * sends a pipeline command operation to the controller. See the Denali NAND
- * controller's user guide for more information (section 4.2.3.6).
- */
-static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
-   bool ecc_en, bool transfer_spare,
-   int access_type, int write)
-{
-   int status = PASS;
-   uint32_t 

[PATCH v6 11/18] mtd: nand: denali: merge struct nand_buf into struct denali_nand_info

2017-06-12 Thread Masahiro Yamada
Now struct nand_buf has only two members, so I see no reason for the
separation.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 29 ++---
 drivers/mtd/nand/denali.h |  8 ++--
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index f2e50c5856f3..caf5ce64b185 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -640,7 +640,7 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
const uint8_t *buf, int page, bool raw_xfer)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
@@ -654,11 +654,11 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
setup_ecc_for_xfer(denali, !raw_xfer, raw_xfer);
 
/* copy buffer into DMA buffer */
-   memcpy(denali->buf.buf, buf, mtd->writesize);
+   memcpy(denali->buf, buf, mtd->writesize);
 
if (raw_xfer) {
/* transfer the data to the spare area */
-   memcpy(denali->buf.buf + mtd->writesize,
+   memcpy(denali->buf + mtd->writesize,
chip->oob_poi,
mtd->oobsize);
}
@@ -735,7 +735,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
uint8_t *buf, int oob_required, int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = denali->caps & DENALI_CAP_HW_ECC_FIXUP ?
@@ -757,7 +757,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 
dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);
 
-   memcpy(buf, denali->buf.buf, mtd->writesize);
+   memcpy(buf, denali->buf, mtd->writesize);
 
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
stat = denali_hw_ecc_fixup(mtd, denali, _ecc_flags);
@@ -782,7 +782,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_mask = INTR__DMA_CMD_COMP;
uint32_t irq_status;
@@ -804,8 +804,8 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
 
denali_enable_dma(denali, false);
 
-   memcpy(buf, denali->buf.buf, mtd->writesize);
-   memcpy(chip->oob_poi, denali->buf.buf + mtd->writesize, mtd->oobsize);
+   memcpy(buf, denali->buf, mtd->writesize);
+   memcpy(chip->oob_poi, denali->buf + mtd->writesize, mtd->oobsize);
 
return 0;
 }
@@ -1224,10 +1224,9 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
-   denali->buf.buf = devm_kzalloc(denali->dev,
-mtd->writesize + mtd->oobsize,
-GFP_KERNEL);
-   if (!denali->buf.buf) {
+   denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize,
+  GFP_KERNEL);
+   if (!denali->buf) {
ret = -ENOMEM;
goto disable_irq;
}
@@ -1240,10 +1239,10 @@ int denali_init(struct denali_nand_info *denali)
goto disable_irq;
}
 
-   denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
+   denali->dma_addr = dma_map_single(denali->dev, denali->buf,
 mtd->writesize + mtd->oobsize,
 DMA_BIDIRECTIONAL);
-   if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
+   if (dma_mapping_error(denali->dev, denali->dma_addr)) {
dev_err(denali->dev, "Failed to map DMA buffer\n");
ret = -EIO;
goto disable_irq;
@@ -1337,7 +1336,7 @@ void denali_remove(struct denali_nand_info *denali)
 
nand_release(mtd);
denali_disable_irq(denali);
-   dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize,
+   dma_unmap_single(denali->dev, denali->dma_addr, bufsize,
 DMA_BIDIRECTIONAL);
 }
 EXPORT_SYMBOL(denali_remove);
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index 

[PATCH v6 17/18] mtd: nand: denali: enable bad block table scan

2017-06-12 Thread Masahiro Yamada
Now this driver is ready to remove NAND_SKIP_BBTSCAN.

The BBT descriptors in denali.c are equivalent to the ones in
nand_bbt.c.  There is no need to duplicate the equivalent structures.
The with-oob decriptors do not work for this driver anyway.

The bbt_pattern (offs = 8) and the version (veroffs = 12) area
overlaps the ECC area.  Set NAND_BBT_NO_OOB flag to use the no_oob
variant of the BBT descriptors.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 31 ++-
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d37fb82f39ed..3bcc886579c8 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1203,29 +1203,6 @@ static const struct mtd_ooblayout_ops 
denali_ooblayout_ops = {
.free = denali_ooblayout_free,
 };
 
-static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
-static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-   .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-   | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-   .offs = 8,
-   .len = 4,
-   .veroffs = 12,
-   .maxblocks = 4,
-   .pattern = bbt_pattern,
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-   .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-   | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-   .offs = 8,
-   .len = 4,
-   .veroffs = 12,
-   .maxblocks = 4,
-   .pattern = mirror_pattern,
-};
-
 /* initialize driver data structures */
 static void denali_drv_init(struct denali_nand_info *denali)
 {
@@ -1369,13 +1346,9 @@ int denali_init(struct denali_nand_info *denali)
 * bad block management.
 */
 
-   /* Bad block management */
-   chip->bbt_td = _main_descr;
-   chip->bbt_md = _mirror_descr;
-
-   /* skip the scan for now until we have OOB read and write support */
chip->bbt_options |= NAND_BBT_USE_FLASH;
-   chip->options |= NAND_SKIP_BBTSCAN;
+   chip->bbt_options |= NAND_BBT_NO_OOB;
+
chip->ecc.mode = NAND_ECC_HW_SYNDROME;
 
/* no subpage writes on denali */
-- 
2.7.4



[PATCH v6 11/18] mtd: nand: denali: merge struct nand_buf into struct denali_nand_info

2017-06-12 Thread Masahiro Yamada
Now struct nand_buf has only two members, so I see no reason for the
separation.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 29 ++---
 drivers/mtd/nand/denali.h |  8 ++--
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index f2e50c5856f3..caf5ce64b185 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -640,7 +640,7 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
const uint8_t *buf, int page, bool raw_xfer)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
@@ -654,11 +654,11 @@ static int write_page(struct mtd_info *mtd, struct 
nand_chip *chip,
setup_ecc_for_xfer(denali, !raw_xfer, raw_xfer);
 
/* copy buffer into DMA buffer */
-   memcpy(denali->buf.buf, buf, mtd->writesize);
+   memcpy(denali->buf, buf, mtd->writesize);
 
if (raw_xfer) {
/* transfer the data to the spare area */
-   memcpy(denali->buf.buf + mtd->writesize,
+   memcpy(denali->buf + mtd->writesize,
chip->oob_poi,
mtd->oobsize);
}
@@ -735,7 +735,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
uint8_t *buf, int oob_required, int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status;
uint32_t irq_mask = denali->caps & DENALI_CAP_HW_ECC_FIXUP ?
@@ -757,7 +757,7 @@ static int denali_read_page(struct mtd_info *mtd, struct 
nand_chip *chip,
 
dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);
 
-   memcpy(buf, denali->buf.buf, mtd->writesize);
+   memcpy(buf, denali->buf, mtd->writesize);
 
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
stat = denali_hw_ecc_fixup(mtd, denali, _ecc_flags);
@@ -782,7 +782,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   dma_addr_t addr = denali->buf.dma_buf;
+   dma_addr_t addr = denali->dma_addr;
size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_mask = INTR__DMA_CMD_COMP;
uint32_t irq_status;
@@ -804,8 +804,8 @@ static int denali_read_page_raw(struct mtd_info *mtd, 
struct nand_chip *chip,
 
denali_enable_dma(denali, false);
 
-   memcpy(buf, denali->buf.buf, mtd->writesize);
-   memcpy(chip->oob_poi, denali->buf.buf + mtd->writesize, mtd->oobsize);
+   memcpy(buf, denali->buf, mtd->writesize);
+   memcpy(chip->oob_poi, denali->buf + mtd->writesize, mtd->oobsize);
 
return 0;
 }
@@ -1224,10 +1224,9 @@ int denali_init(struct denali_nand_info *denali)
if (ret)
goto disable_irq;
 
-   denali->buf.buf = devm_kzalloc(denali->dev,
-mtd->writesize + mtd->oobsize,
-GFP_KERNEL);
-   if (!denali->buf.buf) {
+   denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize,
+  GFP_KERNEL);
+   if (!denali->buf) {
ret = -ENOMEM;
goto disable_irq;
}
@@ -1240,10 +1239,10 @@ int denali_init(struct denali_nand_info *denali)
goto disable_irq;
}
 
-   denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
+   denali->dma_addr = dma_map_single(denali->dev, denali->buf,
 mtd->writesize + mtd->oobsize,
 DMA_BIDIRECTIONAL);
-   if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
+   if (dma_mapping_error(denali->dev, denali->dma_addr)) {
dev_err(denali->dev, "Failed to map DMA buffer\n");
ret = -EIO;
goto disable_irq;
@@ -1337,7 +1336,7 @@ void denali_remove(struct denali_nand_info *denali)
 
nand_release(mtd);
denali_disable_irq(denali);
-   dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize,
+   dma_unmap_single(denali->dev, denali->dma_addr, bufsize,
 DMA_BIDIRECTIONAL);
 }
 EXPORT_SYMBOL(denali_remove);
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index ad2223d179d0..1b991d3016f8 100644
--- 

[PATCH v6 17/18] mtd: nand: denali: enable bad block table scan

2017-06-12 Thread Masahiro Yamada
Now this driver is ready to remove NAND_SKIP_BBTSCAN.

The BBT descriptors in denali.c are equivalent to the ones in
nand_bbt.c.  There is no need to duplicate the equivalent structures.
The with-oob decriptors do not work for this driver anyway.

The bbt_pattern (offs = 8) and the version (veroffs = 12) area
overlaps the ECC area.  Set NAND_BBT_NO_OOB flag to use the no_oob
variant of the BBT descriptors.

Signed-off-by: Masahiro Yamada 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 31 ++-
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index d37fb82f39ed..3bcc886579c8 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1203,29 +1203,6 @@ static const struct mtd_ooblayout_ops 
denali_ooblayout_ops = {
.free = denali_ooblayout_free,
 };
 
-static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
-static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-   .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-   | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-   .offs = 8,
-   .len = 4,
-   .veroffs = 12,
-   .maxblocks = 4,
-   .pattern = bbt_pattern,
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-   .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-   | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-   .offs = 8,
-   .len = 4,
-   .veroffs = 12,
-   .maxblocks = 4,
-   .pattern = mirror_pattern,
-};
-
 /* initialize driver data structures */
 static void denali_drv_init(struct denali_nand_info *denali)
 {
@@ -1369,13 +1346,9 @@ int denali_init(struct denali_nand_info *denali)
 * bad block management.
 */
 
-   /* Bad block management */
-   chip->bbt_td = _main_descr;
-   chip->bbt_md = _mirror_descr;
-
-   /* skip the scan for now until we have OOB read and write support */
chip->bbt_options |= NAND_BBT_USE_FLASH;
-   chip->options |= NAND_SKIP_BBTSCAN;
+   chip->bbt_options |= NAND_BBT_NO_OOB;
+
chip->ecc.mode = NAND_ECC_HW_SYNDROME;
 
/* no subpage writes on denali */
-- 
2.7.4



[PATCH v6 13/18] mtd: nand: denali: fix raw and oob accessors for syndrome page layout

2017-06-12 Thread Masahiro Yamada
The Denali IP adopts the syndrome page layout; payload and ECC are
interleaved, with BBM area always placed at the beginning of OOB.

The figure below shows the page organization for ecc->steps == 2:

  |||---|
  |||   |
  |||   |
  |Payload0||   |
  |||   |
  |||   |
  |||   |
  |||  in-band  |
  |  ECC0  ||   area|
  |||   |
  |||   |
  |||   |
  |Payload1||   |
  |||   |
  |||   |
  |||---|
  |  BBM   ||   |
  |||   |
  |Payload1 (cont.)||   |
  |||out-of-band|
  |  ECC1  ||area   |
  |||   |
  |OOB free||   |
  |||---|

The current raw / oob accessors do not take that into consideration,
so in-band and out-of-band data are transferred as stored in the
device.  In the case above,

  in-band:  Payload0 + ECC0 + Payload1(partial)
  out-of-band:  BBM + Payload1(cont.) + ECC1 + OOB-free

This is wrong.  As the comment block of struct nand_ecc_ctrl says,
driver callbacks must hide the specific layout used by the hardware
and always return contiguous in-band and out-of-band data.

The current implementation is completely screwed-up, so read/write
callbacks must be re-worked.

Also, it is reasonable to support PIO transfer in case DMA may not
work for some reasons.  Actually, the Data DMA may not be equipped
depending on the configuration of the RTL.  This can be checked by
reading the bit 4 of the FEATURES register.  Even if the controller
has the DMA support, dma_set_mask() and dma_map_single() could fail.
In either case, the driver can fall back to the PIO transfer.  Slower
access would be better than giving up.

Signed-off-by: Masahiro Yamada 
---

Changes in v6:
  - Minor cleanup to deprecate {write,read}_data_{to,from}_flash_mem
  - Remove unnecessary MAP10 command for MAIN_(SPARE_)ACCESS

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
  - Newly added

 drivers/mtd/nand/denali.c | 650 +++---
 drivers/mtd/nand/denali.h |   3 +-
 2 files changed, 391 insertions(+), 262 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 03b75045d603..d58ea17c0a69 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -56,14 +56,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct 
mtd_info *mtd)
 }
 
 /*
- * These constants are defined by the driver to enable common driver
- * configuration options.
- */
-#define SPARE_ACCESS   0x41
-#define MAIN_ACCESS0x42
-#define MAIN_SPARE_ACCESS  0x43
-
-/*
  * this is a helper macro that allows us to
  * format the bank into the proper bits for the controller
  */
@@ -246,173 +238,80 @@ static void denali_write_byte(struct mtd_info *mtd, 
uint8_t byte)
index_addr(denali, MODE_11 | BANK(denali->flash_bank) | 2, byte);
 }
 
-static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+static void denali_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
-   uint32_t type;
-
-   if (ctrl & NAND_CLE)
-   type = 0;
-   else if (ctrl & NAND_ALE)
-   type = 1;
-   else
-   return;
+   int i;
 
-   /*
-* Some commands are followed by chip->dev_ready or chip->waitfunc.
-* irq_status must be cleared here to catch the R/B# interrupt later.
-*/
-   if (ctrl & NAND_CTRL_CHANGE)
-   denali_reset_irq(denali);
+   iowrite32(MODE_11 | BANK(denali->flash_bank) | 2, denali->flash_mem);
 
-   index_addr(denali, MODE_11 | BANK(denali->flash_bank) | type, dat);
+   for (i = 0; i < len; i++)
+   buf[i] = ioread32(denali->flash_mem + 0x10);
 }
 
-static int denali_dev_ready(struct mtd_info *mtd)
+static void denali_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
struct denali_nand_info *denali = mtd_to_denali(mtd);
+   int i;
 
-   return !!(denali_check_irq(denali) & INTR__INT_ACT);
-}
-
-/*
- * sends a pipeline command operation to the controller. See the Denali NAND
- * controller's user guide for more information (section 4.2.3.6).
- */
-static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page,
-   bool ecc_en, bool transfer_spare,
-   int access_type, int write)
-{
-   int status = PASS;
-   uint32_t addr, cmd;
-
-   

[PATCH V2] i2c: ismt: fix wrong device address when unmap the data buffer

2017-06-12 Thread Song liwei
From: Liwei Song 

Fix the following kernel bug:

kernel BUG at drivers/iommu/intel-iommu.c:3260!
invalid opcode:  [#5] PREEMPT SMP
Hardware name: Intel Corp. Harcuvar/Server, BIOS 
HAVLCRB0.X64.0013.D39.1608311820 08/31/2016
task: 880175389950 ti: 880176bec000 task.ti: 880176bec000
RIP: 0010:[]  [] intel_unmap+0x25b/0x260
RSP: 0018:880176bef5e8  EFLAGS: 00010296
RAX: 0024 RBX: 8800773c7c88 RCX: ce04
RDX: 8000 RSI:  RDI: 0009
RBP: 880176bef638 R08: 0010 R09: 0004
R10: 880175389c78 R11: 0a4f R12: 8800773c7868
R13: ac88 R14: 8800773c7818 R15: 0001
FS:  7fef21258700() GS:88017b5c() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 0066d6d8 CR3: 7118c000 CR4: 003406e0
Stack:
 ac88 8199867f 880176bef5f8 88010030
 880176bef668 8800773c7c88 880178288098 8800772c0010
 8800773c7818 0001 880176bef648 8150a86e
Call Trace:
 [] ? printk+0x46/0x48
 [] intel_unmap_page+0xe/0x10
 [] ismt_access+0x27b/0x8fa [i2c_ismt]
 [] ? __pm_runtime_suspend+0xa0/0xa0
 [] ? pm_suspend_timer_fn+0x80/0x80
 [] ? __pm_runtime_suspend+0xa0/0xa0
 [] ? pm_suspend_timer_fn+0x80/0x80
 [] ? pci_bus_read_dev_vendor_id+0xf0/0xf0
 [] i2c_smbus_xfer+0xec/0x4b0
 [] ? vprintk_emit+0x345/0x530
 [] i2cdev_ioctl_smbus+0x12b/0x240 [i2c_dev]
 [] ? vprintk_default+0x29/0x40
 [] i2cdev_ioctl+0x63/0x1ec [i2c_dev]
 [] do_vfs_ioctl+0x328/0x5d0
 [] ? vfs_write+0x11c/0x190
 [] ? rt_up_read+0x19/0x20
 [] SyS_ioctl+0x81/0xa0
 [] system_call_fastpath+0x16/0x6e

This happen When run "i2cdetect -y 0" detect SMBus iSMT adapter.

After finished I2C block read/write, when unmap the data buffer,
a wrong device address was pass to dma_unmap_single().

To fix this, give dma_unmap_single() the "dev" parameter, just like
what dma_map_single() does, then unmap can find the right devices.

Fixes: 13f35ac14cd0 ("i2c: Adding support for Intel iSMT SMBus 2.0 host 
controller")
Signed-off-by: Liwei Song 
---
 drivers/i2c/busses/i2c-ismt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index f573448..e98e44e 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -584,7 +584,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
 
/* unmap the data buffer */
if (dma_size != 0)
-   dma_unmap_single(>dev, dma_addr, dma_size, dma_direction);
+   dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
 
if (unlikely(!time_left)) {
dev_err(dev, "completion wait timed out\n");
-- 
2.7.4



[PATCH V2] i2c: ismt: fix wrong device address when unmap the data buffer

2017-06-12 Thread Song liwei
From: Liwei Song 

Fix the following kernel bug:

kernel BUG at drivers/iommu/intel-iommu.c:3260!
invalid opcode:  [#5] PREEMPT SMP
Hardware name: Intel Corp. Harcuvar/Server, BIOS 
HAVLCRB0.X64.0013.D39.1608311820 08/31/2016
task: 880175389950 ti: 880176bec000 task.ti: 880176bec000
RIP: 0010:[]  [] intel_unmap+0x25b/0x260
RSP: 0018:880176bef5e8  EFLAGS: 00010296
RAX: 0024 RBX: 8800773c7c88 RCX: ce04
RDX: 8000 RSI:  RDI: 0009
RBP: 880176bef638 R08: 0010 R09: 0004
R10: 880175389c78 R11: 0a4f R12: 8800773c7868
R13: ac88 R14: 8800773c7818 R15: 0001
FS:  7fef21258700() GS:88017b5c() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 0066d6d8 CR3: 7118c000 CR4: 003406e0
Stack:
 ac88 8199867f 880176bef5f8 88010030
 880176bef668 8800773c7c88 880178288098 8800772c0010
 8800773c7818 0001 880176bef648 8150a86e
Call Trace:
 [] ? printk+0x46/0x48
 [] intel_unmap_page+0xe/0x10
 [] ismt_access+0x27b/0x8fa [i2c_ismt]
 [] ? __pm_runtime_suspend+0xa0/0xa0
 [] ? pm_suspend_timer_fn+0x80/0x80
 [] ? __pm_runtime_suspend+0xa0/0xa0
 [] ? pm_suspend_timer_fn+0x80/0x80
 [] ? pci_bus_read_dev_vendor_id+0xf0/0xf0
 [] i2c_smbus_xfer+0xec/0x4b0
 [] ? vprintk_emit+0x345/0x530
 [] i2cdev_ioctl_smbus+0x12b/0x240 [i2c_dev]
 [] ? vprintk_default+0x29/0x40
 [] i2cdev_ioctl+0x63/0x1ec [i2c_dev]
 [] do_vfs_ioctl+0x328/0x5d0
 [] ? vfs_write+0x11c/0x190
 [] ? rt_up_read+0x19/0x20
 [] SyS_ioctl+0x81/0xa0
 [] system_call_fastpath+0x16/0x6e

This happen When run "i2cdetect -y 0" detect SMBus iSMT adapter.

After finished I2C block read/write, when unmap the data buffer,
a wrong device address was pass to dma_unmap_single().

To fix this, give dma_unmap_single() the "dev" parameter, just like
what dma_map_single() does, then unmap can find the right devices.

Fixes: 13f35ac14cd0 ("i2c: Adding support for Intel iSMT SMBus 2.0 host 
controller")
Signed-off-by: Liwei Song 
---
 drivers/i2c/busses/i2c-ismt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index f573448..e98e44e 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -584,7 +584,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
 
/* unmap the data buffer */
if (dma_size != 0)
-   dma_unmap_single(>dev, dma_addr, dma_size, dma_direction);
+   dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
 
if (unlikely(!time_left)) {
dev_err(dev, "completion wait timed out\n");
-- 
2.7.4



[PATCH v5] mfd: lp87565: Add lp87565 PMIC support

2017-06-12 Thread Keerthy
The LP87565 chip is a power management IC for Portable Navigation Systems
and Tablet Computing devices. It contains the following components:

- Configurable Bucks(Single and multi-phase).
- Configurable General Purpose Output Signals (GPO).

The LP87565-Q1 variant device uses two 2-phase outputs configuration,
Buck0 is master for Buck0/1 output and Buck2 is master for Buck2/3
output.

Signed-off-by: Keerthy 
Acked-by: Rob Herring 
---

The other patches are already pulled by Mark. Hence posting
the remaining patch.

Changes in v5:

  * Re-introduced i2c_device_id table and probe function instead of probe_new.
  * Added Rob's Ack.

Changes in v4:

  * Fixed device tree comments from Rob on the pmic node name.
  * removed regulators from properties list as it is a node.
 
Changes in v3:

  * Fixed License to GPL v2.
  * Fixed an indentation issue.

Changes in v2:

  * Fixed a bunch of whitespace errors.
  * Changed the License to short form.
  * Added the generic compatible lp87565
  * Removed i2c_device_id table.
  * Introduced probe_new function in place of probe.

 Documentation/devicetree/bindings/mfd/lp87565.txt |  43 
 drivers/mfd/Kconfig   |  14 ++
 drivers/mfd/Makefile  |   1 +
 drivers/mfd/lp87565.c | 100 
 include/linux/mfd/lp87565.h   | 270 ++
 5 files changed, 428 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/lp87565.txt
 create mode 100644 drivers/mfd/lp87565.c
 create mode 100644 include/linux/mfd/lp87565.h

diff --git a/Documentation/devicetree/bindings/mfd/lp87565.txt 
b/Documentation/devicetree/bindings/mfd/lp87565.txt
new file mode 100644
index 000..a48df7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp87565.txt
@@ -0,0 +1,43 @@
+TI LP87565 PMIC MFD driver
+
+Required properties:
+  - compatible:"ti,lp87565", "ti,lp87565-q1"
+  - reg:   I2C slave address.
+  - gpio-controller:   Marks the device node as a GPIO Controller.
+  - #gpio-cells:   Should be two.  The first cell is the pin number and
+   the second cell is used to specify flags.
+   See ../gpio/gpio.txt for more information.
+  - xxx-in-supply: Phandle to parent supply node of each regulator
+   populated under regulators node. xxx should match
+   the supply_name populated in driver.
+Example:
+
+lp87565_pmic: pmic@60 {
+   compatible = "ti,lp87565-q1";
+   reg = <0x60>;
+   gpio-controller;
+   #gpio-cells = <2>;
+
+   buck10-in-supply = <_3v3>;
+   buck23-in-supply = <_3v3>;
+
+   regulators: regulators {
+   buck10_reg: buck10 {
+   /* VDD_MPU */
+   regulator-name = "buck10";
+   regulator-min-microvolt = <85>;
+   regulator-max-microvolt = <125>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
+
+   buck23_reg: buck23 {
+   /* VDD_GPU */
+   regulator-name = "buck23";
+   regulator-min-microvolt = <85>;
+   regulator-max-microvolt = <125>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+   };
+};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c6df644..e0da25e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1249,6 +1249,20 @@ config MFD_TI_LP873X
  This driver can also be built as a module. If so, the module
  will be called lp873x.
 
+config MFD_TI_LP87565
+   tristate "TI LP87565 Power Management IC"
+   depends on I2C && OF
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ If you say yes here then you get support for the LP87565 series of
+ Power Management Integrated Circuits (PMIC).
+ These include voltage regulators, thermal protection, configurable
+ General Purpose Outputs (GPO) that are used in portable devices.
+
+ This driver can also be built as a module. If so, the module
+ will be called lp87565.
+
 config MFD_TPS65218
tristate "TI TPS65218 Power Management chips"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 9834e66..58b4ffe 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_HTC_PASIC3)  += htc-pasic3.o
 obj-$(CONFIG_HTC_I2CPLD)   += htc-i2cpld.o
 
 obj-$(CONFIG_MFD_TI_LP873X)+= lp873x.o
+obj-$(CONFIG_MFD_TI_LP87565)   += lp87565.o
 
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c
new file mode 

[PATCH v5] mfd: lp87565: Add lp87565 PMIC support

2017-06-12 Thread Keerthy
The LP87565 chip is a power management IC for Portable Navigation Systems
and Tablet Computing devices. It contains the following components:

- Configurable Bucks(Single and multi-phase).
- Configurable General Purpose Output Signals (GPO).

The LP87565-Q1 variant device uses two 2-phase outputs configuration,
Buck0 is master for Buck0/1 output and Buck2 is master for Buck2/3
output.

Signed-off-by: Keerthy 
Acked-by: Rob Herring 
---

The other patches are already pulled by Mark. Hence posting
the remaining patch.

Changes in v5:

  * Re-introduced i2c_device_id table and probe function instead of probe_new.
  * Added Rob's Ack.

Changes in v4:

  * Fixed device tree comments from Rob on the pmic node name.
  * removed regulators from properties list as it is a node.
 
Changes in v3:

  * Fixed License to GPL v2.
  * Fixed an indentation issue.

Changes in v2:

  * Fixed a bunch of whitespace errors.
  * Changed the License to short form.
  * Added the generic compatible lp87565
  * Removed i2c_device_id table.
  * Introduced probe_new function in place of probe.

 Documentation/devicetree/bindings/mfd/lp87565.txt |  43 
 drivers/mfd/Kconfig   |  14 ++
 drivers/mfd/Makefile  |   1 +
 drivers/mfd/lp87565.c | 100 
 include/linux/mfd/lp87565.h   | 270 ++
 5 files changed, 428 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/lp87565.txt
 create mode 100644 drivers/mfd/lp87565.c
 create mode 100644 include/linux/mfd/lp87565.h

diff --git a/Documentation/devicetree/bindings/mfd/lp87565.txt 
b/Documentation/devicetree/bindings/mfd/lp87565.txt
new file mode 100644
index 000..a48df7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp87565.txt
@@ -0,0 +1,43 @@
+TI LP87565 PMIC MFD driver
+
+Required properties:
+  - compatible:"ti,lp87565", "ti,lp87565-q1"
+  - reg:   I2C slave address.
+  - gpio-controller:   Marks the device node as a GPIO Controller.
+  - #gpio-cells:   Should be two.  The first cell is the pin number and
+   the second cell is used to specify flags.
+   See ../gpio/gpio.txt for more information.
+  - xxx-in-supply: Phandle to parent supply node of each regulator
+   populated under regulators node. xxx should match
+   the supply_name populated in driver.
+Example:
+
+lp87565_pmic: pmic@60 {
+   compatible = "ti,lp87565-q1";
+   reg = <0x60>;
+   gpio-controller;
+   #gpio-cells = <2>;
+
+   buck10-in-supply = <_3v3>;
+   buck23-in-supply = <_3v3>;
+
+   regulators: regulators {
+   buck10_reg: buck10 {
+   /* VDD_MPU */
+   regulator-name = "buck10";
+   regulator-min-microvolt = <85>;
+   regulator-max-microvolt = <125>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
+
+   buck23_reg: buck23 {
+   /* VDD_GPU */
+   regulator-name = "buck23";
+   regulator-min-microvolt = <85>;
+   regulator-max-microvolt = <125>;
+   regulator-boot-on;
+   regulator-always-on;
+   };
+   };
+};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c6df644..e0da25e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1249,6 +1249,20 @@ config MFD_TI_LP873X
  This driver can also be built as a module. If so, the module
  will be called lp873x.
 
+config MFD_TI_LP87565
+   tristate "TI LP87565 Power Management IC"
+   depends on I2C && OF
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ If you say yes here then you get support for the LP87565 series of
+ Power Management Integrated Circuits (PMIC).
+ These include voltage regulators, thermal protection, configurable
+ General Purpose Outputs (GPO) that are used in portable devices.
+
+ This driver can also be built as a module. If so, the module
+ will be called lp87565.
+
 config MFD_TPS65218
tristate "TI TPS65218 Power Management chips"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 9834e66..58b4ffe 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_HTC_PASIC3)  += htc-pasic3.o
 obj-$(CONFIG_HTC_I2CPLD)   += htc-i2cpld.o
 
 obj-$(CONFIG_MFD_TI_LP873X)+= lp873x.o
+obj-$(CONFIG_MFD_TI_LP87565)   += lp87565.o
 
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c
new file mode 100644
index 000..340ad0c
--- 

[PATCH] reset: zx2967: constify zx2967_reset_ops.

2017-06-12 Thread Arvind Yadav
File size before:
   textdata bss dec hex filename
794 232   01026 402 drivers/reset/reset-zx2967.o

File size After adding 'const':
   textdata bss dec hex filename
842 184   01026 402 drivers/reset/reset-zx2967.o

Signed-off-by: Arvind Yadav 
---
 drivers/reset/reset-zx2967.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
index 4dabb9e..4f319f7 100644
--- a/drivers/reset/reset-zx2967.c
+++ b/drivers/reset/reset-zx2967.c
@@ -55,7 +55,7 @@ static int zx2967_reset_deassert(struct reset_controller_dev 
*rcdev,
return zx2967_reset_act(rcdev, id, false);
 }
 
-static struct reset_control_ops zx2967_reset_ops = {
+static const struct reset_control_ops zx2967_reset_ops = {
.assert = zx2967_reset_assert,
.deassert   = zx2967_reset_deassert,
 };
-- 
1.9.1



[PATCH] reset: zx2967: constify zx2967_reset_ops.

2017-06-12 Thread Arvind Yadav
File size before:
   textdata bss dec hex filename
794 232   01026 402 drivers/reset/reset-zx2967.o

File size After adding 'const':
   textdata bss dec hex filename
842 184   01026 402 drivers/reset/reset-zx2967.o

Signed-off-by: Arvind Yadav 
---
 drivers/reset/reset-zx2967.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
index 4dabb9e..4f319f7 100644
--- a/drivers/reset/reset-zx2967.c
+++ b/drivers/reset/reset-zx2967.c
@@ -55,7 +55,7 @@ static int zx2967_reset_deassert(struct reset_controller_dev 
*rcdev,
return zx2967_reset_act(rcdev, id, false);
 }
 
-static struct reset_control_ops zx2967_reset_ops = {
+static const struct reset_control_ops zx2967_reset_ops = {
.assert = zx2967_reset_assert,
.deassert   = zx2967_reset_deassert,
 };
-- 
1.9.1



Re: [RFC PATCH 1/7 v1]powerpc: Free up four PTE bits to accommodate memory keys

2017-06-12 Thread Aneesh Kumar K.V
Ram Pai  writes:

> Rearrange  PTE   bits to  free  up  bits 3, 4, 5  and  6  for
> memory keys. Bit 3, 4, 5, 6 and 57  shall  be used for memory
> keys.
>
> The patch does the following change to the 64K PTE format
>
> H_PAGE_BUSY moves from bit 3 to bit 7
> H_PAGE_F_SECOND which occupied bit 4 moves to the second part
>   of the pte.
> H_PAGE_F_GIX which  occupied bit 5, 6 and 7 also moves to the
>   second part of the pte.
>
> The second part of the PTE will hold
>a (H_PAGE_F_SECOND|H_PAGE_F_GIX)  for  64K page backed pte,
>and sixteen (H_PAGE_F_SECOND|H_PAGE_F_GIX)  for 4k  backed
>   pte.
>
> the four  bits((H_PAGE_F_SECOND|H_PAGE_F_GIX) that represent a slot
> is initialized to 0xF indicating a invalid slot. if a hashpage does
> get  allocated  to  the  0xF  slot, it is released and not used. In
> other words, even  though  0xF  is  a valid slot we discard it  and
> consider it as invalid slot(HPTE_SOFT_INVALID). This  gives  us  an
> opportunity to  not  depend on a bit in the primary PTE in order to
> determine the validity of a slot.
>
> When  we  release  a  0xF slot we also release a legitimate primary
> slot  and  unmap  that  entry. This  is  to  ensure  that we do get
> a legimate non-0xF slot the next time we retry for a slot.
>
> Though treating 0xF slot as invalid reduces the number of available
> slots and make have a effect on the performance, the probabilty
> of hitting a 0xF is extermely low.
>
> Compared  to the current scheme, the above described scheme reduces
> the number of false hash table updates  significantly  and  has the
> added  advantage  of  releasing  four  valuable  PTE bits for other
> purpose.
>
> This idea was jointly developed by Paul Mackerras, Aneesh, Michael
> Ellermen and myself.
>
> 4K PTE format remain unchanged currently.
>

Can you also split this patch into two. One which changes
__hash_page_4k() ie, linux pte format w.r.t 4k hash pte. Second patch
with changes w.r.t __hash_page_64k() ie, pte format w.r.t 64k hash pte.

-aneesh



Re: [RFC PATCH 1/7 v1]powerpc: Free up four PTE bits to accommodate memory keys

2017-06-12 Thread Aneesh Kumar K.V
Ram Pai  writes:

> Rearrange  PTE   bits to  free  up  bits 3, 4, 5  and  6  for
> memory keys. Bit 3, 4, 5, 6 and 57  shall  be used for memory
> keys.
>
> The patch does the following change to the 64K PTE format
>
> H_PAGE_BUSY moves from bit 3 to bit 7
> H_PAGE_F_SECOND which occupied bit 4 moves to the second part
>   of the pte.
> H_PAGE_F_GIX which  occupied bit 5, 6 and 7 also moves to the
>   second part of the pte.
>
> The second part of the PTE will hold
>a (H_PAGE_F_SECOND|H_PAGE_F_GIX)  for  64K page backed pte,
>and sixteen (H_PAGE_F_SECOND|H_PAGE_F_GIX)  for 4k  backed
>   pte.
>
> the four  bits((H_PAGE_F_SECOND|H_PAGE_F_GIX) that represent a slot
> is initialized to 0xF indicating a invalid slot. if a hashpage does
> get  allocated  to  the  0xF  slot, it is released and not used. In
> other words, even  though  0xF  is  a valid slot we discard it  and
> consider it as invalid slot(HPTE_SOFT_INVALID). This  gives  us  an
> opportunity to  not  depend on a bit in the primary PTE in order to
> determine the validity of a slot.
>
> When  we  release  a  0xF slot we also release a legitimate primary
> slot  and  unmap  that  entry. This  is  to  ensure  that we do get
> a legimate non-0xF slot the next time we retry for a slot.
>
> Though treating 0xF slot as invalid reduces the number of available
> slots and make have a effect on the performance, the probabilty
> of hitting a 0xF is extermely low.
>
> Compared  to the current scheme, the above described scheme reduces
> the number of false hash table updates  significantly  and  has the
> added  advantage  of  releasing  four  valuable  PTE bits for other
> purpose.
>
> This idea was jointly developed by Paul Mackerras, Aneesh, Michael
> Ellermen and myself.
>
> 4K PTE format remain unchanged currently.
>

Can you also split this patch into two. One which changes
__hash_page_4k() ie, linux pte format w.r.t 4k hash pte. Second patch
with changes w.r.t __hash_page_64k() ie, pte format w.r.t 64k hash pte.

-aneesh



  1   2   3   4   5   6   7   8   9   10   >