Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ASoC: sun4i-i2s: Implement capture support
From: Maxime Ripard @ 2016-11-03 16:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103153218.fibbz7y7pqwqyo7r@sirena.org.uk>

On Thu, Nov 03, 2016 at 09:32:18AM -0600, Mark Brown wrote:
> On Thu, Nov 03, 2016 at 11:20:48AM +0100, Maxime Ripard wrote:
> > The i2s driver was only implementing playback for now. Implement capture to
> > make sure that's not a limitation anymore.
> 
> This doesn't apply against current code, please check and resend.

Argh, yes, sorry.

I'll send a new version.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/4a5d247c/attachment-0001.sig>

^ permalink raw reply

* [PATCH v2] ASoC: sun4i-i2s: Implement capture support
From: Maxime Ripard @ 2016-11-03 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

The i2s driver was only implementing playback for now. Implement capture to
make sure that's not a limitation anymore.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Changes from v1:
   - Rebased on top of asoc's topic/sunxi branch

 sound/soc/sunxi/sun4i-i2s.c | 52 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 687a8f83dbe5..a7653114e895 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -93,6 +93,7 @@ struct sun4i_i2s {
 	struct clk	*mod_clk;
 	struct regmap	*regmap;
 
+	struct snd_dmaengine_dai_dma_data	capture_dma_data;
 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
 };
 
@@ -341,6 +342,27 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	return 0;
 }
 
+static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
+{
+	/* Flush RX FIFO */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
+			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
+			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
+
+	/* Clear RX counter */
+	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
+
+	/* Enable RX Block */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+			   SUN4I_I2S_CTRL_RX_EN,
+			   SUN4I_I2S_CTRL_RX_EN);
+
+	/* Enable RX DRQ */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
+			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
+			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
+}
+
 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 {
 	/* Flush TX FIFO */
@@ -362,6 +384,18 @@ static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
 }
 
+static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
+{
+	/* Disable RX Block */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+			   SUN4I_I2S_CTRL_RX_EN,
+			   0);
+
+	/* Disable RX DRQ */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
+			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
+			   0);
+}
 
 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
 {
@@ -388,7 +422,7 @@ static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			sun4i_i2s_start_playback(i2s);
 		else
-			return -EINVAL;
+			sun4i_i2s_start_capture(i2s);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -397,7 +431,7 @@ static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			sun4i_i2s_stop_playback(i2s);
 		else
-			return -EINVAL;
+			sun4i_i2s_stop_capture(i2s);
 		break;
 
 	default:
@@ -459,7 +493,9 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 {
 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 
-	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, NULL);
+	snd_soc_dai_init_dma_data(dai,
+				  &i2s->playback_dma_data,
+				  &i2s->capture_dma_data);
 
 	snd_soc_dai_set_drvdata(dai, i2s);
 
@@ -468,6 +504,13 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 
 static struct snd_soc_dai_driver sun4i_i2s_dai = {
 	.probe = sun4i_i2s_dai_probe,
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
 	.playback = {
 		.stream_name = "Playback",
 		.channels_min = 2,
@@ -630,6 +673,9 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
 	i2s->playback_dma_data.maxburst = 4;
 
+	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
+	i2s->capture_dma_data.maxburst = 4;
+
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
-- 
2.10.1

^ permalink raw reply related

* [GIT PULL] iommu/arm-smmu: Fixes for 4.9
From: Joerg Roedel @ 2016-11-03 16:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0dbf2665-4292-d49a-b9e7-688bcdf29c6e@arm.com>

On Thu, Nov 03, 2016 at 04:22:04PM +0000, Robin Murphy wrote:
> But bus_set_iommu() is already checking whether another SMMU (in this
> case) has probed, by virtue of bus->iommu_ops being non-NULL, and
> returning without doing anything if so. What's the value of adding a
> whole  bunch more code to effectively duplicate that in a less elegant
> manner?

No, bus_set_iommu() checks whether there is _any_ other IOMMU already
registered. This doesn't need to be an smmu. So I think the return value
of bus_set_iommu shouldn't be generally ignored.


	Joerg

^ permalink raw reply

* [PATCH v2 6/6] ARM: dts: stm32f429: Add QSPI clock
From: Alexandre Torgue @ 2016-11-03 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476436699-21879-7-git-send-email-gabriel.fernandez@st.com>

Hi Gabriel,

On 10/14/2016 11:18 AM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch adds the QSPI clock for stm32f469 discovery board.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
>  arch/arm/boot/dts/stm32f469-disco.dts | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
> index e911af8..4052023 100644
> --- a/arch/arm/boot/dts/stm32f469-disco.dts
> +++ b/arch/arm/boot/dts/stm32f469-disco.dts
> @@ -66,6 +66,10 @@
>  	};
>  };
>
> +&rcc {
> +	compatible = "st,stm32f469-rcc", "st,stm32-rcc";
> +};
> +

With this patch, stm32f469-disco doesn't boot if clk drivers patch are 
not applied.
Can you please send a new version to keep compatibility with older clk 
driver.

&rcc {
 > +	compatible = "st,stm32f469-rcc", "st,stm32-rcc";
-> compatible = "st,stm32f469-rcc", "st,stm32f42xx-rcc", "st,stm32-rcc";
 > +};
 > +
I will take it in next pull request round.


Regards
Alex


>  &clk_hse {
>  	clock-frequency = <8000000>;
>  };
>

^ permalink raw reply

* [PATCH v5 5/7] net: ethernet: bgmac: device tree phy enablement
From: Jon Mason @ 2016-11-03 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <35b16640-8600-8c48-2f04-886dc925229d@milecki.pl>

On Thu, Nov 03, 2016 at 09:31:21AM +0100, Rafal Milecki wrote:
> On 11/02/2016 06:08 PM, Jon Mason wrote:
> >Change the bgmac driver to allow for phy's defined by the device tree
> 
> This is a late review, I know, sorry... :(
> 
> 
> >+static int bcma_phy_direct_connect(struct bgmac *bgmac)
> >+{
> >+	struct fixed_phy_status fphy_status = {
> >+		.link = 1,
> >+		.speed = SPEED_1000,
> >+		.duplex = DUPLEX_FULL,
> >+	};
> >+	struct phy_device *phy_dev;
> >+	int err;
> >+
> >+	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
> >+	if (!phy_dev || IS_ERR(phy_dev)) {
> >+		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
> >+		return -ENODEV;
> >+	}
> >+
> >+	err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
> >+				 PHY_INTERFACE_MODE_MII);
> >+	if (err) {
> >+		dev_err(bgmac->dev, "Connecting PHY failed\n");
> >+		return err;
> >+	}
> >+
> >+	return err;
> >+}
> 
> This bcma specific function looks exactly the same as...
> 
> 
> >+static int platform_phy_direct_connect(struct bgmac *bgmac)
> >+{
> >+	struct fixed_phy_status fphy_status = {
> >+		.link = 1,
> >+		.speed = SPEED_1000,
> >+		.duplex = DUPLEX_FULL,
> >+	};
> >+	struct phy_device *phy_dev;
> >+	int err;
> >+
> >+	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
> >+	if (!phy_dev || IS_ERR(phy_dev)) {
> >+		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
> >+		return -ENODEV;
> >+	}
> >+
> >+	err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
> >+				 PHY_INTERFACE_MODE_MII);
> >+	if (err) {
> >+		dev_err(bgmac->dev, "Connecting PHY failed\n");
> >+		return err;
> >+	}
> >+
> >+	return err;
> >+}
> 
> This one.
> 
> Would that make sense to keep bgmac_phy_connect_direct and just use it in
> bcma/platform code?

Yes, I was having the same internal debate.  I hate the duplication of
code, but I really wanted to keep the PHY logic out of the bgmac.c
file.  Do you think it is acceptable to make this an inline function
in bgmac.h?

Thanks,
Jon

^ permalink raw reply

* [PATCH v2 0/3] davinci: ohci: fix usb ohci device name
From: David Lechner @ 2016-11-03 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103160308.29588-1-ahaslam@baylibre.com>

On 11/03/2016 11:03 AM, Axel Haslam wrote:
> The usb ohci clock match is not working because the usb clock
> is registered as "ohci" instead of "ohci.0"
>
> But since there is only a single ohci instance, lets pass -1 to
> the platform data id parameter and avoid the extra ".0" matching.
>
> while we are fixing this, rename the driver from "ohci" to
> "ohci-da8xx" which  is less generic and consistent with other
> usb drivers.
>
> changes form v1 -> v2
> *Reword commit messages (David Lechner)
>
> Because of the recently accepted patches on the ARM-davinci side,
> This patch series is based on:
> branch: /v4.10/soc of the linux-davinci tree.
>
> It Depends on two accepted usb patches missing on that branch:
> 6c21caa USB: OHCI: make ohci-da8xx a separate driver (in next-usb)
> 6110c42 usb: ohci-da8xx: Remove code that references mach (in linux-next)
>
> A branch with both patches applied + this series can be found here:
> https://github.com/axelhaslamx/linux-axel/commits/ti-davinci-ohci-rename
>
>
> Axel Haslam (3):
>   ARM: davinci: da8xx: Fix ohci device name
>   phy: da8xx-usb: rename the ohci device to ohci-da8xx
>   usb: ohci-da8xx: rename driver to ohci-da8xx
>
>  arch/arm/mach-davinci/da830.c     | 2 +-
>  arch/arm/mach-davinci/da850.c     | 2 +-
>  arch/arm/mach-davinci/da8xx-dt.c  | 2 +-
>  arch/arm/mach-davinci/usb-da8xx.c | 4 ++--
>  drivers/phy/phy-da8xx-usb.c       | 5 +++--
>  drivers/usb/host/ohci-da8xx.c     | 2 +-
>  6 files changed, 9 insertions(+), 8 deletions(-)
>

Thanks for making the changes. The commit messages make better sense to 
me now. :-)

^ permalink raw reply

* [PATCH 2/3] phy: da8xx-usb: rename the ohci device to ohci-da8xx
From: Kishon Vijay Abraham I @ 2016-11-03 16:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161102124435.31777-3-ahaslam@baylibre.com>



On Wednesday 02 November 2016 06:14 PM, Axel Haslam wrote:
> There is only one ohci on the da8xx series of chips,
> so remove the ".0" when creating the phy. Also add
> the "-da8xx" postfix to be consistent across davinci
> usb drivers.
> 
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>

Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/phy/phy-da8xx-usb.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c
> index 32ae78c..c85fb0b 100644
> --- a/drivers/phy/phy-da8xx-usb.c
> +++ b/drivers/phy/phy-da8xx-usb.c
> @@ -198,7 +198,8 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev)
>  	} else {
>  		int ret;
>  
> -		ret = phy_create_lookup(d_phy->usb11_phy, "usb-phy", "ohci.0");
> +		ret = phy_create_lookup(d_phy->usb11_phy, "usb-phy",
> +					"ohci-da8xx");
>  		if (ret)
>  			dev_warn(dev, "Failed to create usb11 phy lookup\n");
>  		ret = phy_create_lookup(d_phy->usb20_phy, "usb-phy",
> @@ -216,7 +217,7 @@ static int da8xx_usb_phy_remove(struct platform_device *pdev)
>  
>  	if (!pdev->dev.of_node) {
>  		phy_remove_lookup(d_phy->usb20_phy, "usb-phy", "musb-da8xx");
> -		phy_remove_lookup(d_phy->usb11_phy, "usb-phy", "ohci.0");
> +		phy_remove_lookup(d_phy->usb11_phy, "usb-phy", "ohci-da8xx");
>  	}
>  
>  	return 0;
> 

^ permalink raw reply

* [GIT PULL] iommu/arm-smmu: Fixes for 4.9
From: Robin Murphy @ 2016-11-03 16:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103162943.GS3541@8bytes.org>

On 03/11/16 16:29, Joerg Roedel wrote:
> On Thu, Nov 03, 2016 at 04:22:04PM +0000, Robin Murphy wrote:
>> But bus_set_iommu() is already checking whether another SMMU (in this
>> case) has probed, by virtue of bus->iommu_ops being non-NULL, and
>> returning without doing anything if so. What's the value of adding a
>> whole  bunch more code to effectively duplicate that in a less elegant
>> manner?
> 
> No, bus_set_iommu() checks whether there is _any_ other IOMMU already
> registered. This doesn't need to be an smmu. So I think the return value
> of bus_set_iommu shouldn't be generally ignored.

But if it is someone else's ops, then all that means is that the SMMU
driver isn't going to get notified about devices on that bus, or get
called with them later, so I still don't see where the problem is. If
there are devices on that bus which the SMMU *is* supposed to be
managing, then that system can't be supported with the current API anyway.

Robin.

^ permalink raw reply

* [PATCH] ARM: DTS: r8a7794: alt: Fix PCF names for DU
From: Sergei Shtylyov @ 2016-11-03 16:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478180574-15464-1-git-send-email-jacopo@jmondi.org>

Hello.

On 11/03/2016 04:42 PM, Jacopo Mondi wrote:

> Update the PCF pin groups and function names of DU interface for

    PFC maybe?

> r8a7794 ALT board.
>
> The currently specified pin groups and function names prevented PCF and
> DU interfaces from being correctly configured:
>
> sh-pfc e6060000.pin-controller: function 'du' not supported
> sh-pfc e6060000.pin-controller: invalid function du in map table
> sh-pfc e6060000.pin-controller: function 'du' not supported
> sh-pfc e6060000.pin-controller: invalid function du in map table
> sh-pfc e6060000.pin-controller: function 'du' not supported
> sh-pfc e6060000.pin-controller: invalid function du in map table
> sh-pfc e6060000.pin-controller: function 'du' not supported
> sh-pfc e6060000.pin-controller: invalid function du in map table
> rcar-du: probe of feb00000.display failed with error -22
>
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>
> Patch applied against Simon Horman's renesas/master branch.
> The PCF pin groups and function renaming was introduced by commit 56ed4bb9 and
> DTS for ALT board has never been update accordingly.

    We didn't care about Alt at the time, the patch was done in the interests 
of the SILK board. I didn't realize the DU pin groups were used for Alt before 
the actual support was added for them. Thank you for finally fixing this!

> Tested displaying frames on VGA interface: the rcar-du driver loads correctly.

MBR, Sergei

^ permalink raw reply

* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Sinan Kaya @ 2016-11-03 16:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103140058.GA31142@bhelgaas-glaptop.roam.corp.google.com>


On 11/3/2016 10:00 AM, Bjorn Helgaas wrote:
> On Wed, Nov 02, 2016 at 12:36:16PM -0400, Sinan Kaya wrote:
>> Hi Bjorn,
>>
>> On 11/2/2016 12:08 PM, Bjorn Helgaas wrote:
>>> On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
>>>> Hi Bjorn,
>>>>
>>>> On 2016-10-31 15:48, Bjorn Helgaas wrote:
>>>>> On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
>>>>>> The Qualcomm Technologies QDF2432 SoC does not support accesses
>>>>>> smaller
>>>>>> than 32 bits to the PCI configuration space. Register the appropriate
>>>>>> quirk.
>>>>>>
>>>>>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>>>>>
>>>>> Hi Christopher,
>>>>>
>>>>> Can you rebase this against v4.9-rc1?  It no longer applies to my tree.
>>>>
>>>> I apologize for not being clearer. This patch depends on:
>>>>
>>>> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
>>>> PCI/ACPI: Check platform-specific ECAM quirks
>>>>
>>>> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
>>>> branch, but that seems to have come and gone. How would you like to
>>>> proceed?
>>>
>>> Oh yes, that's right, I forgot that connection.  I'm afraid I kind of
>>> dropped the ball on that thread, so I went back and read through it
>>> again.
>>>
>>> I *think* the current state is:
>>>
>>>   - I'm OK with the first two patches that add the quirk
>>>     infrastructure.
>>>
>>>   - My issue with the last three patches that add ThunderX quirks is
>>>     that there's no generic description of the ECAM address space.
>>>
>>> So if I understand correctly, your Qualcomm patch depends only on the
>>> first two patches.
>>>
>>> Then the question is how the Qualcomm ECAM address space is described.
>>> Your quirk overrides the default pci_generic_ecam_ops with the
>>> &pci_32b_ops, but it doesn't touch the address space part, so I assume
>>> the bus ranges and corresponding address space in your MCFG is
>>> correct.  So far, so good.
>>
>> Qualcomm ECAM space includes both the root port and the endpoint address
>> space with a single contiguous 256 MB address space described in MCFG table.
>> There is no need to describe additional resources like PNP0C02.
> 
> This is the crucial point I have failed to communicate clearly: the
> PNP0C02 resource is *always* required, even if the MCFG is correct.
> 

Interesting...

It looks like there is a lot of lessons learnt here from history.

I think this requirement is only true if your system DDR space and PCIe
space overlaps in the memory map. I understand that Intel systems allow
sharing of these two memory ranges. An OS could potentially reclaim this
address range.

If there is no overlap and PCI is not enabled, there can't be any SW entity
to reclaim this space. 

Did I miss something?

> The reason is that MCFG is a PCI-specific table, and it should be
> possible to boot a kernel with no PCI support.  That kernel will not
> look at the MCFG.  The PCI hardware will still be present and will
> still consume the ECAM space, so the OS must be able to discover that
> the ECAM space is not available for other devices.
> 
> The usual way to for the OS to discover that would be via the _CRS of
> a PNP0A03 or PNP0A08 host bridge device.  _CRS is what I mean by a
> "generic" way to describe this address space, because the ACPI core
> can interpret _CRS for all ACPI devices, even if the kernel doesn't
> contain drivers for all of those devices.
> 
> It turns out that we can't use the _CRS of host bridges because of the
> Producer/Consumer bit screwup [1].  So the fallback is to include the
> ECAM space in the _CRS of a PNP0C02 device.  This is what the PCI
> Firmware spec r3.0, Table 4-2, footnote 2 is talking about.
> 
> Bjorn
> 
> [1] The original ACPI spec intent was that Consumer resources would be
> space like ECAM that is consumed directly by the bridge, and Producer
> resources would be the windows forwarded down to PCI.  But BIOSes
> didn't use the Producer/Consumer bit consistently, so we have to
> assume that all resources in host bridge _CRS are windows, which
> leaves us no way to describe the Consumer resources.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Sinan Kaya @ 2016-11-03 17:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <aa8bc916-9363-2de7-2997-4ce470562b2c@codeaurora.org>

On 11/3/2016 12:58 PM, Sinan Kaya wrote:
>> > This is the crucial point I have failed to communicate clearly: the
>> > PNP0C02 resource is *always* required, even if the MCFG is correct.
>> > 
> Interesting...
> 
> It looks like there is a lot of lessons learnt here from history.
> 
> I think this requirement is only true if your system DDR space and PCIe
> space overlaps in the memory map. I understand that Intel systems allow
> sharing of these two memory ranges. An OS could potentially reclaim this
> address range.
> 
> If there is no overlap and PCI is not enabled, there can't be any SW entity
> to reclaim this space. 
> 
> Did I miss something?
> 

For protection, it makes sense to reserve this range. I'm trying to understand
who would claim this range.

-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH v2 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399
From: Kishon Vijay Abraham I @ 2016-11-03 17:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478138774-3254-2-git-send-email-wulf@rock-chips.com>



On Thursday 03 November 2016 07:36 AM, William Wu wrote:
> The rk3399 SoC USB2 PHY is comprised of one Host port and
> one OTG port. And OTG port is for USB2.0 part of USB3.0 OTG
> controller, as a part to construct a fully feature Type-C
> subsystem.
> 
> With this patch, we can support OTG port with the following
> functions:
> - Support BC1.2 charger detect, and use extcon notifier to
>   send USB charger types to power driver.
> - Support PHY suspend for power management.
> - Support OTG Host only mode.
> 
> Also, correct 480MHz output clock stable time. We found that
> the system crashed due to 480MHz output clock of USB2 PHY was
> unstable after clock had been enabled by gpu module.

Can you split the clock fix into a separate patch?

Thanks
Kishon
> 
> Theoretically, 1 millisecond is a critical value for 480 output
> clock stable time, so we try changing the delay time to 1.2
> millisecond to avoid this issue.
> 
> Signed-off-by: William Wu <wulf@rock-chips.com>
> ---
> Changes in v2:
> - remove wakelock
> 
>  drivers/phy/phy-rockchip-inno-usb2.c | 593 +++++++++++++++++++++++++++++++++--
>  1 file changed, 562 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c
> index ac20310..8f2d2b6 100644
> --- a/drivers/phy/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/phy-rockchip-inno-usb2.c
> @@ -17,6 +17,7 @@
>  #include <linux/clk.h>
>  #include <linux/clk-provider.h>
>  #include <linux/delay.h>
> +#include <linux/extcon.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/gpio/consumer.h>
> @@ -30,11 +31,15 @@
>  #include <linux/of_platform.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/power_supply.h>
>  #include <linux/regmap.h>
>  #include <linux/mfd/syscon.h>
> +#include <linux/usb/of.h>
> +#include <linux/usb/otg.h>
>  
>  #define BIT_WRITEABLE_SHIFT	16
> -#define SCHEDULE_DELAY	(60 * HZ)
> +#define SCHEDULE_DELAY		(60 * HZ)
> +#define OTG_SCHEDULE_DELAY	(2 * HZ)
>  
>  enum rockchip_usb2phy_port_id {
>  	USB2PHY_PORT_OTG,
> @@ -49,6 +54,37 @@ enum rockchip_usb2phy_host_state {
>  	PHY_STATE_FS_LS_ONLINE	= 4,
>  };
>  
> +/**
> + * Different states involved in USB charger detection.
> + * USB_CHG_STATE_UNDEFINED	USB charger is not connected or detection
> + *				process is not yet started.
> + * USB_CHG_STATE_WAIT_FOR_DCD	Waiting for Data pins contact.
> + * USB_CHG_STATE_DCD_DONE	Data pin contact is detected.
> + * USB_CHG_STATE_PRIMARY_DONE	Primary detection is completed (Detects
> + *				between SDP and DCP/CDP).
> + * USB_CHG_STATE_SECONDARY_DONE	Secondary detection is completed (Detects
> + *				between DCP and CDP).
> + * USB_CHG_STATE_DETECTED	USB charger type is determined.
> + */
> +enum usb_chg_state {
> +	USB_CHG_STATE_UNDEFINED = 0,
> +	USB_CHG_STATE_WAIT_FOR_DCD,
> +	USB_CHG_STATE_DCD_DONE,
> +	USB_CHG_STATE_PRIMARY_DONE,
> +	USB_CHG_STATE_SECONDARY_DONE,
> +	USB_CHG_STATE_DETECTED,
> +};
> +
> +static const unsigned int rockchip_usb2phy_extcon_cable[] = {
> +	EXTCON_USB,
> +	EXTCON_USB_HOST,
> +	EXTCON_CHG_USB_SDP,
> +	EXTCON_CHG_USB_CDP,
> +	EXTCON_CHG_USB_DCP,
> +	EXTCON_CHG_USB_SLOW,
> +	EXTCON_NONE,
> +};
> +
>  struct usb2phy_reg {
>  	unsigned int	offset;
>  	unsigned int	bitend;
> @@ -58,19 +94,55 @@ struct usb2phy_reg {
>  };
>  
>  /**
> + * struct rockchip_chg_det_reg: usb charger detect registers
> + * @cp_det: charging port detected successfully.
> + * @dcp_det: dedicated charging port detected successfully.
> + * @dp_det: assert data pin connect successfully.
> + * @idm_sink_en: open dm sink curren.
> + * @idp_sink_en: open dp sink current.
> + * @idp_src_en: open dm source current.
> + * @rdm_pdwn_en: open dm pull down resistor.
> + * @vdm_src_en: open dm voltage source.
> + * @vdp_src_en: open dp voltage source.
> + * @opmode: utmi operational mode.
> + */
> +struct rockchip_chg_det_reg {
> +	struct usb2phy_reg	cp_det;
> +	struct usb2phy_reg	dcp_det;
> +	struct usb2phy_reg	dp_det;
> +	struct usb2phy_reg	idm_sink_en;
> +	struct usb2phy_reg	idp_sink_en;
> +	struct usb2phy_reg	idp_src_en;
> +	struct usb2phy_reg	rdm_pdwn_en;
> +	struct usb2phy_reg	vdm_src_en;
> +	struct usb2phy_reg	vdp_src_en;
> +	struct usb2phy_reg	opmode;
> +};
> +
> +/**
>   * struct rockchip_usb2phy_port_cfg: usb-phy port configuration.
>   * @phy_sus: phy suspend register.
> + * @bvalid_det_en: vbus valid rise detection enable register.
> + * @bvalid_det_st: vbus valid rise detection status register.
> + * @bvalid_det_clr: vbus valid rise detection clear register.
>   * @ls_det_en: linestate detection enable register.
>   * @ls_det_st: linestate detection state register.
>   * @ls_det_clr: linestate detection clear register.
> + * @utmi_avalid: utmi vbus avalid status register.
> + * @utmi_bvalid: utmi vbus bvalid status register.
>   * @utmi_ls: utmi linestate state register.
>   * @utmi_hstdet: utmi host disconnect register.
>   */
>  struct rockchip_usb2phy_port_cfg {
>  	struct usb2phy_reg	phy_sus;
> +	struct usb2phy_reg	bvalid_det_en;
> +	struct usb2phy_reg	bvalid_det_st;
> +	struct usb2phy_reg	bvalid_det_clr;
>  	struct usb2phy_reg	ls_det_en;
>  	struct usb2phy_reg	ls_det_st;
>  	struct usb2phy_reg	ls_det_clr;
> +	struct usb2phy_reg	utmi_avalid;
> +	struct usb2phy_reg	utmi_bvalid;
>  	struct usb2phy_reg	utmi_ls;
>  	struct usb2phy_reg	utmi_hstdet;
>  };
> @@ -80,31 +152,51 @@ struct rockchip_usb2phy_port_cfg {
>   * @reg: the address offset of grf for usb-phy config.
>   * @num_ports: specify how many ports that the phy has.
>   * @clkout_ctl: keep on/turn off output clk of phy.
> + * @chg_det: charger detection registers.
>   */
>  struct rockchip_usb2phy_cfg {
>  	unsigned int	reg;
>  	unsigned int	num_ports;
>  	struct usb2phy_reg	clkout_ctl;
>  	const struct rockchip_usb2phy_port_cfg	port_cfgs[USB2PHY_NUM_PORTS];
> +	const struct rockchip_chg_det_reg	chg_det;
>  };
>  
>  /**
>   * struct rockchip_usb2phy_port: usb-phy port data.
>   * @port_id: flag for otg port or host port.
>   * @suspended: phy suspended flag.
> + * @utmi_avalid: utmi avalid status usage flag.
> + *	true	- use avalid to get vbus status
> + *	flase	- use bvalid to get vbus status
> + * @vbus_attached: otg device vbus status.
> + * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
>   * @ls_irq: IRQ number assigned for linestate detection.
>   * @mutex: for register updating in sm_work.
> - * @sm_work: OTG state machine work.
> + * @chg_work: charge detect work.
> + * @otg_sm_work: OTG state machine work.
> + * @sm_work: HOST state machine work.
>   * @phy_cfg: port register configuration, assigned by driver data.
> + * @event_nb: hold event notification callback.
> + * @state: define OTG enumeration states before device reset.
> + * @mode: the dr_mode of the controller.
>   */
>  struct rockchip_usb2phy_port {
>  	struct phy	*phy;
>  	unsigned int	port_id;
>  	bool		suspended;
> +	bool		utmi_avalid;
> +	bool		vbus_attached;
> +	int		bvalid_irq;
>  	int		ls_irq;
>  	struct mutex	mutex;
> +	struct		delayed_work chg_work;
> +	struct		delayed_work otg_sm_work;
>  	struct		delayed_work sm_work;
>  	const struct	rockchip_usb2phy_port_cfg *port_cfg;
> +	struct notifier_block	event_nb;
> +	enum usb_otg_state	state;
> +	enum usb_dr_mode	mode;
>  };
>  
>  /**
> @@ -113,6 +205,11 @@ struct rockchip_usb2phy_port {
>   * @clk: clock struct of phy input clk.
>   * @clk480m: clock struct of phy output clk.
>   * @clk_hw: clock struct of phy output clk management.
> + * @chg_state: states involved in USB charger detection.
> + * @chg_type: USB charger types.
> + * @dcd_retries: The retry count used to track Data contact
> + *		 detection process.
> + * @edev: extcon device for notification registration
>   * @phy_cfg: phy register configuration, assigned by driver data.
>   * @ports: phy port instance.
>   */
> @@ -122,6 +219,10 @@ struct rockchip_usb2phy {
>  	struct clk	*clk;
>  	struct clk	*clk480m;
>  	struct clk_hw	clk480m_hw;
> +	enum usb_chg_state	chg_state;
> +	enum power_supply_type	chg_type;
> +	u8			dcd_retries;
> +	struct extcon_dev	*edev;
>  	const struct rockchip_usb2phy_cfg	*phy_cfg;
>  	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
>  };
> @@ -166,7 +267,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw)
>  			return ret;
>  
>  		/* waitting for the clk become stable */
> -		mdelay(1);
> +		udelay(1200);
>  	}
>  
>  	return 0;
> @@ -263,33 +364,84 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  	return ret;
>  }
>  
> -static int rockchip_usb2phy_init(struct phy *phy)
> +static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
>  {
> -	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> -	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
>  	int ret;
> +	struct device_node *node = rphy->dev->of_node;
> +	struct extcon_dev *edev;
> +
> +	if (of_property_read_bool(node, "extcon")) {
> +		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
> +		if (IS_ERR(edev)) {
> +			if (PTR_ERR(edev) != -EPROBE_DEFER)
> +				dev_err(rphy->dev, "Invalid or missing extcon\n");
> +			return PTR_ERR(edev);
> +		}
> +	} else {
> +		/* Initialize extcon device */
> +		edev = devm_extcon_dev_allocate(rphy->dev,
> +						rockchip_usb2phy_extcon_cable);
>  
> -	if (rport->port_id == USB2PHY_PORT_HOST) {
> -		/* clear linestate and enable linestate detect irq */
> -		mutex_lock(&rport->mutex);
> +		if (IS_ERR(edev))
> +			return -ENOMEM;
>  
> -		ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
> +		ret = devm_extcon_dev_register(rphy->dev, edev);
>  		if (ret) {
> -			mutex_unlock(&rport->mutex);
> +			dev_err(rphy->dev, "failed to register extcon device\n");
>  			return ret;
>  		}
> +	}
>  
> -		ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true);
> -		if (ret) {
> -			mutex_unlock(&rport->mutex);
> -			return ret;
> +	rphy->edev = edev;
> +
> +	return 0;
> +}
> +
> +static int rockchip_usb2phy_init(struct phy *phy)
> +{
> +	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
> +	int ret = 0;
> +
> +	mutex_lock(&rport->mutex);
> +
> +	if (rport->port_id == USB2PHY_PORT_OTG) {
> +		if (rport->mode != USB_DR_MODE_HOST) {
> +			/* clear bvalid status and enable bvalid detect irq */
> +			ret = property_enable(rphy,
> +					      &rport->port_cfg->bvalid_det_clr,
> +					      true);
> +			if (ret)
> +				goto out;
> +
> +			ret = property_enable(rphy,
> +					      &rport->port_cfg->bvalid_det_en,
> +					      true);
> +			if (ret)
> +				goto out;
> +
> +			schedule_delayed_work(&rport->otg_sm_work,
> +					      OTG_SCHEDULE_DELAY);
> +		} else {
> +			/* If OTG works in host only mode, do nothing. */
> +			dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
>  		}
> +	} else if (rport->port_id == USB2PHY_PORT_HOST) {
> +		/* clear linestate and enable linestate detect irq */
> +		ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
> +		if (ret)
> +			goto out;
> +
> +		ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true);
> +		if (ret)
> +			goto out;
>  
> -		mutex_unlock(&rport->mutex);
>  		schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
>  	}
>  
> -	return 0;
> +out:
> +	mutex_unlock(&rport->mutex);
> +	return ret;
>  }
>  
>  static int rockchip_usb2phy_power_on(struct phy *phy)
> @@ -340,7 +492,11 @@ static int rockchip_usb2phy_exit(struct phy *phy)
>  {
>  	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
>  
> -	if (rport->port_id == USB2PHY_PORT_HOST)
> +	if (rport->port_id == USB2PHY_PORT_OTG &&
> +	    rport->mode != USB_DR_MODE_HOST) {
> +		cancel_delayed_work_sync(&rport->otg_sm_work);
> +		cancel_delayed_work_sync(&rport->chg_work);
> +	} else if (rport->port_id == USB2PHY_PORT_HOST)
>  		cancel_delayed_work_sync(&rport->sm_work);
>  
>  	return 0;
> @@ -354,6 +510,249 @@ static const struct phy_ops rockchip_usb2phy_ops = {
>  	.owner		= THIS_MODULE,
>  };
>  
> +static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(work, struct rockchip_usb2phy_port,
> +			     otg_sm_work.work);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +	static unsigned int cable;
> +	unsigned long delay;
> +	bool vbus_attach, sch_work, notify_charger;
> +
> +	if (rport->utmi_avalid)
> +		vbus_attach =
> +			property_enabled(rphy, &rport->port_cfg->utmi_avalid);
> +	else
> +		vbus_attach =
> +			property_enabled(rphy, &rport->port_cfg->utmi_bvalid);
> +
> +	sch_work = false;
> +	notify_charger = false;
> +	delay = OTG_SCHEDULE_DELAY;
> +	dev_dbg(&rport->phy->dev, "%s otg sm work\n",
> +		usb_otg_state_string(rport->state));
> +
> +	switch (rport->state) {
> +	case OTG_STATE_UNDEFINED:
> +		rport->state = OTG_STATE_B_IDLE;
> +		if (!vbus_attach)
> +			rockchip_usb2phy_power_off(rport->phy);
> +		/* fall through */
> +	case OTG_STATE_B_IDLE:
> +		if (extcon_get_cable_state_(rphy->edev, EXTCON_USB_HOST) > 0) {
> +			dev_dbg(&rport->phy->dev, "usb otg host connect\n");
> +			rport->state = OTG_STATE_A_HOST;
> +			rockchip_usb2phy_power_on(rport->phy);
> +			return;
> +		} else if (vbus_attach) {
> +			dev_dbg(&rport->phy->dev, "vbus_attach\n");
> +			switch (rphy->chg_state) {
> +			case USB_CHG_STATE_UNDEFINED:
> +				schedule_delayed_work(&rport->chg_work, 0);
> +				return;
> +			case USB_CHG_STATE_DETECTED:
> +				switch (rphy->chg_type) {
> +				case POWER_SUPPLY_TYPE_USB:
> +					dev_dbg(&rport->phy->dev,
> +						"sdp cable is connecetd\n");
> +					rockchip_usb2phy_power_on(rport->phy);
> +					rport->state = OTG_STATE_B_PERIPHERAL;
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_SDP;
> +					break;
> +				case POWER_SUPPLY_TYPE_USB_DCP:
> +					dev_dbg(&rport->phy->dev,
> +						"dcp cable is connecetd\n");
> +					rockchip_usb2phy_power_off(rport->phy);
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_DCP;
> +					break;
> +				case POWER_SUPPLY_TYPE_USB_CDP:
> +					dev_dbg(&rport->phy->dev,
> +						"cdp cable is connecetd\n");
> +					rockchip_usb2phy_power_on(rport->phy);
> +					rport->state = OTG_STATE_B_PERIPHERAL;
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_CDP;
> +					break;
> +				default:
> +					break;
> +				}
> +				break;
> +			default:
> +				break;
> +			}
> +		} else {
> +			notify_charger = true;
> +			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
> +		}
> +
> +		if (rport->vbus_attached != vbus_attach) {
> +			rport->vbus_attached = vbus_attach;
> +
> +			if (notify_charger && rphy->edev)
> +				extcon_set_cable_state_(rphy->edev,
> +							cable, vbus_attach);
> +		}
> +		break;
> +	case OTG_STATE_B_PERIPHERAL:
> +		if (!vbus_attach) {
> +			dev_dbg(&rport->phy->dev, "usb disconnect\n");
> +			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
> +			rport->state = OTG_STATE_B_IDLE;
> +			delay = 0;
> +			rockchip_usb2phy_power_off(rport->phy);
> +		}
> +		sch_work = true;
> +		break;
> +	case OTG_STATE_A_HOST:
> +		if (extcon_get_cable_state_(rphy->edev, EXTCON_USB_HOST) == 0) {
> +			dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
> +			rport->state = OTG_STATE_B_IDLE;
> +			rockchip_usb2phy_power_off(rport->phy);
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (sch_work)
> +		schedule_delayed_work(&rport->otg_sm_work, delay);
> +}
> +
> +static const char *chg_to_string(enum power_supply_type chg_type)
> +{
> +	switch (chg_type) {
> +	case POWER_SUPPLY_TYPE_USB:
> +		return "USB_SDP_CHARGER";
> +	case POWER_SUPPLY_TYPE_USB_DCP:
> +		return "USB_DCP_CHARGER";
> +	case POWER_SUPPLY_TYPE_USB_CDP:
> +		return "USB_CDP_CHARGER";
> +	default:
> +		return "INVALID_CHARGER";
> +	}
> +}
> +
> +static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
> +				    bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en);
> +}
> +
> +static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
> +					    bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en);
> +}
> +
> +static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
> +					      bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en);
> +}
> +
> +#define CHG_DCD_POLL_TIME	(100 * HZ / 1000)
> +#define CHG_DCD_MAX_RETRIES	6
> +#define CHG_PRIMARY_DET_TIME	(40 * HZ / 1000)
> +#define CHG_SECONDARY_DET_TIME	(40 * HZ / 1000)
> +static void rockchip_chg_detect_work(struct work_struct *work)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +	bool is_dcd, tmout, vout;
> +	unsigned long delay;
> +
> +	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
> +		rphy->chg_state);
> +	switch (rphy->chg_state) {
> +	case USB_CHG_STATE_UNDEFINED:
> +		if (!rport->suspended)
> +			rockchip_usb2phy_power_off(rport->phy);
> +		/* put the controller in non-driving mode */
> +		property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false);
> +		/* Start DCD processing stage 1 */
> +		rockchip_chg_enable_dcd(rphy, true);
> +		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
> +		rphy->dcd_retries = 0;
> +		delay = CHG_DCD_POLL_TIME;
> +		break;
> +	case USB_CHG_STATE_WAIT_FOR_DCD:
> +		/* get data contact detection status */
> +		is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det);
> +		tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
> +		/* stage 2 */
> +		if (is_dcd || tmout) {
> +			/* stage 4 */
> +			/* Turn off DCD circuitry */
> +			rockchip_chg_enable_dcd(rphy, false);
> +			/* Voltage Source on DP, Probe on DM */
> +			rockchip_chg_enable_primary_det(rphy, true);
> +			delay = CHG_PRIMARY_DET_TIME;
> +			rphy->chg_state = USB_CHG_STATE_DCD_DONE;
> +		} else {
> +			/* stage 3 */
> +			delay = CHG_DCD_POLL_TIME;
> +		}
> +		break;
> +	case USB_CHG_STATE_DCD_DONE:
> +		vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det);
> +		rockchip_chg_enable_primary_det(rphy, false);
> +		if (vout) {
> +			/* Voltage Source on DM, Probe on DP  */
> +			rockchip_chg_enable_secondary_det(rphy, true);
> +			delay = CHG_SECONDARY_DET_TIME;
> +			rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
> +		} else {
> +			if (tmout) {
> +				/* floating charger found */
> +				rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
> +				rphy->chg_state = USB_CHG_STATE_DETECTED;
> +				delay = 0;
> +			} else {
> +				rphy->chg_type = POWER_SUPPLY_TYPE_USB;
> +				rphy->chg_state = USB_CHG_STATE_DETECTED;
> +				delay = 0;
> +			}
> +		}
> +		break;
> +	case USB_CHG_STATE_PRIMARY_DONE:
> +		vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det);
> +		/* Turn off voltage source */
> +		rockchip_chg_enable_secondary_det(rphy, false);
> +		if (vout)
> +			rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
> +		else
> +			rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
> +		/* fall through */
> +	case USB_CHG_STATE_SECONDARY_DONE:
> +		rphy->chg_state = USB_CHG_STATE_DETECTED;
> +		delay = 0;
> +		/* fall through */
> +	case USB_CHG_STATE_DETECTED:
> +		/* put the controller in normal mode */
> +		property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true);
> +		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
> +		dev_info(&rport->phy->dev, "charger = %s\n",
> +			 chg_to_string(rphy->chg_type));
> +		return;
> +	default:
> +		return;
> +	}
> +
> +	schedule_delayed_work(&rport->chg_work, delay);
> +}
> +
>  /*
>   * The function manage host-phy port state and suspend/resume phy port
>   * to save power.
> @@ -485,6 +884,26 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
> +{
> +	struct rockchip_usb2phy_port *rport = data;
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +
> +	if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st))
> +		return IRQ_NONE;
> +
> +	mutex_lock(&rport->mutex);
> +
> +	/* clear bvalid detect irq pending status */
> +	property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true);
> +
> +	mutex_unlock(&rport->mutex);
> +
> +	rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
>  					   struct rockchip_usb2phy_port *rport,
>  					   struct device_node *child_np)
> @@ -509,13 +928,86 @@ static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
>  					IRQF_ONESHOT,
>  					"rockchip_usb2phy", rport);
>  	if (ret) {
> -		dev_err(rphy->dev, "failed to request irq handle\n");
> +		dev_err(rphy->dev, "failed to request linestate irq handle\n");
>  		return ret;
>  	}
>  
>  	return 0;
>  }
>  
> +static int rockchip_otg_event(struct notifier_block *nb,
> +			      unsigned long event, void *ptr)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(nb, struct rockchip_usb2phy_port, event_nb);
> +
> +	schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
> +					  struct rockchip_usb2phy_port *rport,
> +					  struct device_node *child_np)
> +{
> +	int ret;
> +
> +	rport->port_id = USB2PHY_PORT_OTG;
> +	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
> +	rport->state = OTG_STATE_UNDEFINED;
> +
> +	/*
> +	 * set suspended flag to true, but actually don't
> +	 * put phy in suspend mode, it aims to enable usb
> +	 * phy and clock in power_on() called by usb controller
> +	 * driver during probe.
> +	 */
> +	rport->suspended = true;
> +	rport->vbus_attached = false;
> +
> +	mutex_init(&rport->mutex);
> +
> +	rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
> +	if (rport->mode == USB_DR_MODE_HOST) {
> +		ret = 0;
> +		goto out;
> +	}
> +
> +	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
> +	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
> +
> +	rport->utmi_avalid =
> +		of_property_read_bool(child_np, "rockchip,utmi-avalid");
> +
> +	rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
> +	if (rport->bvalid_irq < 0) {
> +		dev_err(rphy->dev, "no vbus valid irq provided\n");
> +		ret = rport->bvalid_irq;
> +		goto out;
> +	}
> +
> +	ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, NULL,
> +					rockchip_usb2phy_bvalid_irq,
> +					IRQF_ONESHOT,
> +					"rockchip_usb2phy_bvalid", rport);
> +	if (ret) {
> +		dev_err(rphy->dev, "failed to request otg-bvalid irq handle\n");
> +		goto out;
> +	}
> +
> +	if (!IS_ERR(rphy->edev)) {
> +		rport->event_nb.notifier_call = rockchip_otg_event;
> +
> +		ret = extcon_register_notifier(rphy->edev, EXTCON_USB_HOST,
> +					       &rport->event_nb);
> +		if (ret)
> +			dev_err(rphy->dev, "register USB HOST notifier failed\n");
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -553,8 +1045,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  
>  	rphy->dev = dev;
>  	phy_cfgs = match->data;
> +	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
>  	platform_set_drvdata(pdev, rphy);
>  
> +	ret = rockchip_usb2phy_extcon_register(rphy);
> +	if (ret)
> +		return ret;
> +
>  	/* find out a proper config which can be matched with dt. */
>  	index = 0;
>  	while (phy_cfgs[index].reg) {
> @@ -591,13 +1089,9 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  		struct rockchip_usb2phy_port *rport = &rphy->ports[index];
>  		struct phy *phy;
>  
> -		/*
> -		 * This driver aim to support both otg-port and host-port,
> -		 * but unfortunately, the otg part is not ready in current,
> -		 * so this comments and below codes are interim, which should
> -		 * be changed after otg-port is supplied soon.
> -		 */
> -		if (of_node_cmp(child_np->name, "host-port"))
> +		/* This driver aims to support both otg-port and host-port */
> +		if (of_node_cmp(child_np->name, "host-port") &&
> +		    of_node_cmp(child_np->name, "otg-port"))
>  			goto next_child;
>  
>  		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
> @@ -610,9 +1104,18 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  		rport->phy = phy;
>  		phy_set_drvdata(rport->phy, rport);
>  
> -		ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np);
> -		if (ret)
> -			goto put_child;
> +		/* initialize otg/host port separately */
> +		if (!of_node_cmp(child_np->name, "host-port")) {
> +			ret = rockchip_usb2phy_host_port_init(rphy, rport,
> +							      child_np);
> +			if (ret)
> +				goto put_child;
> +		} else {
> +			ret = rockchip_usb2phy_otg_port_init(rphy, rport,
> +							     child_np);
> +			if (ret)
> +				goto put_child;
> +		}
>  
>  next_child:
>  		/* to prevent out of boundary */
> @@ -654,10 +1157,18 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
>  
>  static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
>  	{
> -		.reg = 0xe450,
> +		.reg		= 0xe450,
>  		.num_ports	= 2,
>  		.clkout_ctl	= { 0xe450, 4, 4, 1, 0 },
>  		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus	= { 0xe454, 1, 0, 2, 1 },
> +				.bvalid_det_en	= { 0xe3c0, 3, 3, 0, 1 },
> +				.bvalid_det_st	= { 0xe3e0, 3, 3, 0, 1 },
> +				.bvalid_det_clr	= { 0xe3d0, 3, 3, 0, 1 },
> +				.utmi_avalid	= { 0xe2ac, 7, 7, 0, 1 },
> +				.utmi_bvalid	= { 0xe2ac, 12, 12, 0, 1 },
> +			},
>  			[USB2PHY_PORT_HOST] = {
>  				.phy_sus	= { 0xe458, 1, 0, 0x2, 0x1 },
>  				.ls_det_en	= { 0xe3c0, 6, 6, 0, 1 },
> @@ -667,12 +1178,32 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
>  				.utmi_hstdet	= { 0xe2ac, 23, 23, 0, 1 }
>  			}
>  		},
> +		.chg_det = {
> +			.opmode		= { 0xe454, 3, 0, 5, 1 },
> +			.cp_det		= { 0xe2ac, 2, 2, 0, 1 },
> +			.dcp_det	= { 0xe2ac, 1, 1, 0, 1 },
> +			.dp_det		= { 0xe2ac, 0, 0, 0, 1 },
> +			.idm_sink_en	= { 0xe450, 8, 8, 0, 1 },
> +			.idp_sink_en	= { 0xe450, 7, 7, 0, 1 },
> +			.idp_src_en	= { 0xe450, 9, 9, 0, 1 },
> +			.rdm_pdwn_en	= { 0xe450, 10, 10, 0, 1 },
> +			.vdm_src_en	= { 0xe450, 12, 12, 0, 1 },
> +			.vdp_src_en	= { 0xe450, 11, 11, 0, 1 },
> +		},
>  	},
>  	{
> -		.reg = 0xe460,
> +		.reg		= 0xe460,
>  		.num_ports	= 2,
>  		.clkout_ctl	= { 0xe460, 4, 4, 1, 0 },
>  		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus        = { 0xe464, 1, 0, 2, 1 },
> +				.bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
> +				.bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
> +				.bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
> +				.utmi_avalid	= { 0xe2ac, 10, 10, 0, 1 },
> +				.utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
> +			},
>  			[USB2PHY_PORT_HOST] = {
>  				.phy_sus	= { 0xe468, 1, 0, 0x2, 0x1 },
>  				.ls_det_en	= { 0xe3c0, 11, 11, 0, 1 },
> 

^ permalink raw reply

* [PATCH] arm64: errata: Check for --fix-cortex-a53-843419 and --fix-cortex-a53
From: Florian Fainelli @ 2016-11-03 17:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103141559.GQ22791@arm.com>

On 11/03/2016 07:16 AM, Will Deacon wrote:
> On Wed, Nov 02, 2016 at 02:57:26PM -0700, Florian Fainelli wrote:
>> On 11/02/2016 02:41 PM, Markus Mayer wrote:
>>> On 2 November 2016 at 14:27, Will Deacon <will.deacon@arm.com> wrote:
>>>> On Wed, Nov 02, 2016 at 02:07:17PM -0700, Markus Mayer wrote:
>>>>> The question I am asking is: What do we have to lose by supporting both options?
>>>>
>>>> We end up passing "--fix-cortex-a53" to the linker, without knowing what it
>>>> might do in the future.
>>>
>>> It seems highly unlikely that such a generic option would be added in
>>> the future, both, because the precedent has been set for topic
>>> specific options, and because they know it has been used in the past,
>>> so they wouldn't add a previously used option to do something
>>> completely different. (And if they really did, then that would be a
>>> huge binutils bug.)
>>>
>>> So, we have a trade-off between a real world problem that does
>>> currently exist and avoiding a theoretical issue that may never
>>> materialize.
>>
>> Agreed, also the way Markus' patch is designed makes it such that we
>> first try the full and current option name, and if not supported, try
>> the second (and earlier, now obsolete) option name, so I really don't
>> see a lot of room for things to go wrong here...
> 
> It's not beyond the realms of possibility that ld will grow a
> "fix-cortex-a53" option in the future, that enables all of the a53
> workarounds. Since ld is the linker supported by the kernel and gold isn't,
> I don't want to pass this option down.

No it's entirely reasonable to think this may happen, although:

- this has not happened yet, so once this happens, you will need to cook
a patch for this anyway, and you will be able to gate this catch all
linker option by an appropriate version check presumably

- you would supposedly want a fine grained set of linker options that
are specific to workarounds you have to have enabled, instead of a catch
all "enable all Cortex A53" workarounds

> 
> If you can't change toolchain and you want this worked around, why can't you
> either build gold with it enabled by default, or pass the extra flag on the
> command line to the kernel build system?

Because that creates a distribution problem and now we have to document
this for people who want to build a kernel on their own, without
necessarily understanding if this is something they might need, or why
this is needed, and why the kernel is not taking care of that on its
own? So yes, this comes down to who is responsible for what, in that
case the kernel's Makefile is the best place where to put such knowledge
as to which workaround needs to be enabled by the linker and it
simplifies things a lot for people.
-- 
Florian

^ permalink raw reply

* [PATCH 0/2] mm: fix the "counter.sh" failure for libhugetlbfs
From: Randy Dunlap @ 2016-11-03 17:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478141499-13825-1-git-send-email-shijie.huang@arm.com>

On 11/02/16 19:51, Huang Shijie wrote:
> 
> (2) The bug   
>    After I tested the libhugetlbfs, I found the test case "counter.sh"
>    will fail with the gigantic page (32M page in arm64 board).
> 
>    This patch set adds support for gigantic surplus hugetlb pages,
>    allowing the counter.sh unit test to pass.   

Hi,
Where is the counter.sh test? Where can I find it?

thanks.
-- 
~Randy

^ permalink raw reply

* Applied "ASoC: sun4i-codec: Move data structures to add create_card call to quirks" to the asoc tree
From: Mark Brown @ 2016-11-03 17:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-2-wens@csie.org>

The patch

   ASoC: sun4i-codec: Move data structures to add create_card call to quirks

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 2f2a3462bc15e9613412ca186bf8a6611afa66c7 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Thu, 3 Nov 2016 15:55:43 +0800
Subject: [PATCH] ASoC: sun4i-codec: Move data structures to add create_card
 call to quirks

The audio codec on later Allwinner SoCs have a different layout and
audio path compared to the A10/A20. However the PCM parts are still
the same.

The different layout and audio paths mean we need a different
create_card function for different families, so they can create
DAPM endpoint widgets and routes.

This patch moves the regmap configs, quirks and of_device_id
structures to just before the probe function, so we can, among other
things, include a pointer for the create_card function. None of the
lines of code were changed.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/sunxi/sun4i-codec.c | 78 +++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index a60707761abf..7b78f4045d38 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -678,45 +678,6 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 	 },
 };
 
-static const struct regmap_config sun4i_codec_regmap_config = {
-	.reg_bits	= 32,
-	.reg_stride	= 4,
-	.val_bits	= 32,
-	.max_register	= SUN4I_CODEC_ADC_RXCNT,
-};
-
-static const struct regmap_config sun7i_codec_regmap_config = {
-	.reg_bits	= 32,
-	.reg_stride	= 4,
-	.val_bits	= 32,
-	.max_register	= SUN7I_CODEC_AC_MIC_PHONE_CAL,
-};
-
-struct sun4i_codec_quirks {
-	const struct regmap_config *regmap_config;
-};
-
-static const struct sun4i_codec_quirks sun4i_codec_quirks = {
-	.regmap_config = &sun4i_codec_regmap_config,
-};
-
-static const struct sun4i_codec_quirks sun7i_codec_quirks = {
-	.regmap_config = &sun7i_codec_regmap_config,
-};
-
-static const struct of_device_id sun4i_codec_of_match[] = {
-	{
-		.compatible = "allwinner,sun4i-a10-codec",
-		.data = &sun4i_codec_quirks,
-	},
-	{
-		.compatible = "allwinner,sun7i-a20-codec",
-		.data = &sun7i_codec_quirks,
-	},
-	{}
-};
-MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
-
 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
 							int *num_links)
 {
@@ -781,6 +742,45 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
 	return card;
 };
 
+static const struct regmap_config sun4i_codec_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= SUN4I_CODEC_ADC_RXCNT,
+};
+
+static const struct regmap_config sun7i_codec_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= SUN7I_CODEC_AC_MIC_PHONE_CAL,
+};
+
+struct sun4i_codec_quirks {
+	const struct regmap_config *regmap_config;
+};
+
+static const struct sun4i_codec_quirks sun4i_codec_quirks = {
+	.regmap_config	= &sun4i_codec_regmap_config,
+};
+
+static const struct sun4i_codec_quirks sun7i_codec_quirks = {
+	.regmap_config	= &sun7i_codec_regmap_config,
+};
+
+static const struct of_device_id sun4i_codec_of_match[] = {
+	{
+		.compatible = "allwinner,sun4i-a10-codec",
+		.data = &sun4i_codec_quirks,
+	},
+	{
+		.compatible = "allwinner,sun7i-a20-codec",
+		.data = &sun7i_codec_quirks,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
+
 static int sun4i_codec_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card;
-- 
2.10.1

^ permalink raw reply related

* [GIT PULL] iommu/arm-smmu: Fixes for 4.9
From: Joerg Roedel @ 2016-11-03 17:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a6ded15c-5eea-70b8-61a1-b40873af8699@arm.com>

On Thu, Nov 03, 2016 at 04:57:40PM +0000, Robin Murphy wrote:
> But if it is someone else's ops, then all that means is that the SMMU
> driver isn't going to get notified about devices on that bus, or get
> called with them later, so I still don't see where the problem is. If
> there are devices on that bus which the SMMU *is* supposed to be
> managing, then that system can't be supported with the current API anyway.

If another IOMMU is already probed and set its iommu_ops, than there is
no point in probing the smmu anyway, no? The probe function should
return the failed probe in that case and not proceed silently.


	Joerg

^ permalink raw reply

* [PATCH v2 02/14] ASoC: sun4i-codec: Expand quirks to handle register offsets and card creation
From: Maxime Ripard @ 2016-11-03 17:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-3-wens@csie.org>

On Thu, Nov 03, 2016 at 03:55:44PM +0800, Chen-Yu Tsai wrote:
> The A31 has a similar codec to the A10/A20. The PCM parts are very
> similar, with just different register offsets. The analog paths are
> very different. There are more inputs and outputs.
> 
> The A31s, A23, and H3 have a similar PCM interface, again with register
> offsets slightly rearranged. The analog path controls, while very
> similar between them and the A31, have been moved a separate bus which
> is accessed through a message box like interface in the PRCM address
> range. This would be handled by a separate auxiliary device tied in
> through the device tree in its supporting create_card function.
> 
> The quirks structure is expanded to include different register offsets
> and separate callbacks for creating the ASoC card. The regmap_config,
> quirks, and of_device_match tables have been moved to facilitate this.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>

Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/a5744aaa/attachment.sig>

^ permalink raw reply

* [PATCHv2] ARM: OMAP3: Fix formatting of features printed
From: Tony Lindgren @ 2016-11-03 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

With the printk cleanups merged into v4.9-rc1, we now get the omap
revision printed on multiple lines. Let's fix that and also remove the
extra empty space at the end of the features. And let's update things
to use scnprintf as suggested by Ivaylo Dimitrov
<ivo.g.dimitrov.75@gmail.com>.

Reported-by: Adam Ford <aford173@gmail.com>
Cc: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/id.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -205,11 +205,15 @@ void __init omap2xxx_check_revision(void)
 
 #define OMAP3_SHOW_FEATURE(feat)		\
 	if (omap3_has_ ##feat())		\
-		printk(#feat" ");
+		n += scnprintf(buf + n, sizeof(buf) - n, #feat " ");
 
 static void __init omap3_cpuinfo(void)
 {
 	const char *cpu_name;
+	char buf[64];
+	int n = 0;
+
+	memset(buf, 0, sizeof(buf));
 
 	/*
 	 * OMAP3430 and OMAP3530 are assumed to be same.
@@ -241,10 +245,10 @@ static void __init omap3_cpuinfo(void)
 		cpu_name = "OMAP3503";
 	}
 
-	sprintf(soc_name, "%s", cpu_name);
+	scnprintf(soc_name, sizeof(soc_name), "%s", cpu_name);
 
 	/* Print verbose information */
-	pr_info("%s %s (", soc_name, soc_rev);
+	n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev);
 
 	OMAP3_SHOW_FEATURE(l2cache);
 	OMAP3_SHOW_FEATURE(iva);
@@ -252,8 +256,10 @@ static void __init omap3_cpuinfo(void)
 	OMAP3_SHOW_FEATURE(neon);
 	OMAP3_SHOW_FEATURE(isp);
 	OMAP3_SHOW_FEATURE(192mhz_clk);
-
-	printk(")\n");
+	if (*(buf + n - 1) == ' ')
+		n--;
+	n += scnprintf(buf + n, sizeof(buf) - n, ")\n");
+	pr_info("%s", buf);
 }
 
 #define OMAP3_CHECK_FEATURE(status,feat)				\
-- 
2.10.2

^ permalink raw reply

* [PATCH v2 06/14] ASoC: sun4i-codec: Add support for A31 playback through headphone output
From: Maxime Ripard @ 2016-11-03 17:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103075556.29018-7-wens@csie.org>

Hi,

On Thu, Nov 03, 2016 at 03:55:48PM +0800, Chen-Yu Tsai wrote:
> +/* headphone controls */
> +static const char * const sun6i_codec_hp_src_enum_text[] = {
> +	"DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
> +			    SUN6I_CODEC_OM_DACA_CTRL,
> +			    SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
> +			    SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
> +			    sun6i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
> +	SOC_DAPM_ENUM("Headphone Source Playback Route",
> +		      sun6i_codec_hp_src_enum),
> +};

What is that route exactly? A muxer?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/7eabc1f5/attachment.sig>

^ permalink raw reply

* [PATCH v2] iommu/arm-smmu: Don't inadvertently reject multiple SMMUv3s
From: Robin Murphy @ 2016-11-03 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

We now delay installing our per-bus iommu_ops until we know an SMMU has
successfully probed, as they don't serve much purpose beforehand, and
doing so also avoids fights between multiple IOMMU drivers in a single
kernel. However, the upshot of passing the return value of bus_set_iommu()
back from our probe function is that if there happens to be more than
one SMMUv3 device in a system, the second and subsequent probes will
wind up returning -EBUSY to the driver core and getting torn down again.

Avoid re-setting ops if ours are already installed, so that any genuine
failures stand out.

Fixes: 08d4ca2a672b ("iommu/arm-smmu: Support non-PCI devices with SMMUv3")
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
CC: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 15c01c3cd540..e6f9b2d745ca 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2636,17 +2636,26 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
 	/* And we're up. Go go go! */
 	of_iommu_set_ops(dev->of_node, &arm_smmu_ops);
 #ifdef CONFIG_PCI
-	pci_request_acs();
-	ret = bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-	if (ret)
-		return ret;
+	if (pci_bus_type.iommu_ops != &arm_smmu_ops) {
+		pci_request_acs();
+		ret = bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+		if (ret)
+			return ret;
+	}
 #endif
 #ifdef CONFIG_ARM_AMBA
-	ret = bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-	if (ret)
-		return ret;
+	if (amba_bustype.iommu_ops != &arm_smmu_ops) {
+		ret = bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+		if (ret)
+			return ret;
+	}
 #endif
-	return bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+	if (platform_bus_type.iommu_ops != &arm_smmu_ops) {
+		ret = bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+		if (ret)
+			return ret;
+	}
+	return 0;
 }
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
-- 
2.10.2.dirty

^ permalink raw reply related

* [PATCH v3] arm64: defconfig: enable EEPROM_AT25 config option
From: Florian Fainelli @ 2016-11-03 17:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476823202-8286-1-git-send-email-scott.branden@broadcom.com>

On 10/18/2016 01:40 PM, Scott Branden wrote:
> Enable support for on board SPI EEPROM by setting
> CONFIG_EEPROM_AT25=m
> 
> Signed-off-by: Scott Branden <scott.branden@broadcom.com>

Applied, thanks
-- 
Florian

^ permalink raw reply

* [PATCH v2 3/3] reset: Add the TI SCI reset driver
From: Andrew F. Davis @ 2016-11-03 17:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477647364.3010.28.camel@pengutronix.de>

On 10/28/2016 04:36 AM, Philipp Zabel wrote:
> Hi Andrew,
> 
> is there (going to be) as stable branch I can base these on, or should I
> just wait until the prerequisite patches appear in arm-soc/for-next?
> 
> Am Donnerstag, den 27.10.2016, 16:49 -0500 schrieb Andrew F. Davis:
>> Some TI Keystone family of SoCs contain a system controller (like the
>> Power Management Micro Controller (PMMC) on K2G SoCs) that manage the
>> low-level device control (like clocks, resets etc) for the various
>> hardware modules present on the SoC. These device control operations
>> are provided to the host processor OS through a communication protocol
>> called the TI System Control Interface (TI SCI) protocol.
>>
>> This patch adds a reset driver that communicates to the system
>> controller over the TI SCI protocol for performing reset management
>> of various devices present on the SoC. Various reset functionalities
>> are achieved by the means of different TI SCI device operations
>> provided by the TI SCI framework.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> [s-anna at ti.com: documentation changes, revised commit message]
>> Signed-off-by: Suman Anna <s-anna@ti.com>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> ---
>>  MAINTAINERS                  |   1 +
>>  drivers/reset/Kconfig        |   9 ++
>>  drivers/reset/Makefile       |   1 +
>>  drivers/reset/reset-ti-sci.c | 262 +++++++++++++++++++++++++++++++++++++++++++
>>  4 files changed, 273 insertions(+)
>>  create mode 100644 drivers/reset/reset-ti-sci.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index accf991..b93d91a 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -11901,6 +11901,7 @@ F:	include/dt-bindings/clock/k2g.h
>>  F:	drivers/clk/keystone/sci-clk.c
>>  F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
>>  F:	include/dt-bindings/reset/k2g.h
>> +F:	drivers/reset/reset-ti-sci.c
>>  
>>  THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
>>  M:	Hans Verkuil <hverkuil@xs4all.nl>
>> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
>> index 06d9fa2..4c21c9d 100644
>> --- a/drivers/reset/Kconfig
>> +++ b/drivers/reset/Kconfig
>> @@ -66,6 +66,15 @@ config RESET_SUNXI
>>  	help
>>  	  This enables the reset driver for Allwinner SoCs.
>>  
>> +config RESET_TI_SCI
>> +	tristate "TI System Control Interface (TI-SCI) reset driver"
>> +	depends on RESET_CONTROLLER
>> +	depends on TI_SCI_PROTOCOL
>> +	help
>> +	  This enables the reset driver support over TI System Control Interface
>> +	  available on some new TI SoCs. If you wish to use reset resources
>> +	  managed by the TI System Controller, say Y here. Otherwise, say N.
>> +
>>  config TI_SYSCON_RESET
>>  	tristate "TI SYSCON Reset Driver"
>>  	depends on HAS_IOMEM
>> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
>> index bbe7026..36321f2 100644
>> --- a/drivers/reset/Makefile
>> +++ b/drivers/reset/Makefile
>> @@ -10,6 +10,7 @@ obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
>>  obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
>>  obj-$(CONFIG_RESET_STM32) += reset-stm32.o
>>  obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
>> +obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
>>  obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
>>  obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
>>  obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
>> diff --git a/drivers/reset/reset-ti-sci.c b/drivers/reset/reset-ti-sci.c
>> new file mode 100644
>> index 0000000..42ccf12
>> --- /dev/null
>> +++ b/drivers/reset/reset-ti-sci.c
>> @@ -0,0 +1,262 @@
>> +/*
>> + * Texas Instrument's System Control Interface (TI-SCI) reset driver
>> + *
>> + * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
>> + *	Andrew F. Davis <afd@ti.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>> + * kind, whether express or implied; without even the implied warranty
>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/idr.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/reset-controller.h>
>> +#include <linux/soc/ti/ti_sci_protocol.h>
>> +
>> +/**
>> + * struct ti_sci_reset_control - reset control structure
>> + * @dev_id: SoC-specific device identifier
>> + * @reset_mask: reset mask to use for toggling reset
>> + */
>> +struct ti_sci_reset_control {
>> +	u32 dev_id;
>> +	u32 reset_mask;
>> +};
>> +
>> +/**
>> + * struct ti_sci_reset_data - reset controller information structure
>> + * @rcdev: reset controller entity
>> + * @dev: reset controller device pointer
>> + * @sci: TI SCI handle used for communication with system controller
>> + * @idr: idr structure for mapping ids to reset control structures
>> + */
>> +struct ti_sci_reset_data {
>> +	struct reset_controller_dev rcdev;
>> +	struct device *dev;
>> +	const struct ti_sci_handle *sci;
>> +	struct idr idr;
>> +};
>> +
>> +#define to_ti_sci_reset_data(p)	\
>> +	container_of((p), struct ti_sci_reset_data, rcdev)
>> +
>> +/**
>> + * ti_sci_reset_set() - program a device's reset
>> + * @rcdev: reset controller entity
>> + * @id: ID of the reset to toggle
>> + * @assert: boolean flag to indicate assert or deassert
>> + *
>> + * This is a common internal function used to assert or deassert a device's
>> + * reset using the TI SCI protocol. The device's reset is asserted if the
>> + * @assert argument is true, or deasserted if @assert argument is false.
>> + * The mechanism itself is a read-modify-write procedure, the current device
>> + * reset register is read using a TI SCI device operation, the new value is
>> + * set or un-set using the reset's mask, and the new reset value written by
>> + * using another TI SCI device operation.
>> + *
>> + * Return: 0 for successful request, else a corresponding error value
>> + */
>> +static int ti_sci_reset_set(struct reset_controller_dev *rcdev,
>> +			    unsigned long id, bool assert)
>> +{
>> +	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
>> +	const struct ti_sci_handle *sci = data->sci;
>> +	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
>> +	struct ti_sci_reset_control *control;
>> +	u32 reset_state;
>> +	int ret;
>> +
>> +	control = idr_find(&data->idr, id);
>> +	if (!control)
>> +		return -EINVAL;
>> +
>> +	ret = dev_ops->get_device_resets(sci, control->dev_id,
>> +					 &reset_state);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (assert)
>> +		reset_state |= control->reset_mask;
>> +	else
>> +		reset_state &= ~control->reset_mask;
>> +
>> +	return dev_ops->set_device_resets(sci, control->dev_id,
>> +					  reset_state);
> 
> Without any locking? Maybe the read-modify-write could just be moved one
> level down with an update_bits type of callback in the ti_sci_dev_ops.
> 

That may be useful to add at some point, for now I want to work with the
existing framework, it can always be moved later. I'll add some
per-control locks for v3.

Thanks,
Andrew

>> +}
>> +
>> +/**
>> + * ti_sci_reset_assert() - assert device reset
>> + * @rcdev: reset controller entity
>> + * @id: ID of the reset to be asserted
>> + *
>> + * This function implements the reset driver op to assert a device's reset
>> + * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
>> + * with the corresponding parameters as passed in, but with the @assert
>> + * argument set to true for asserting the reset.
>> + *
>> + * Return: 0 for successful request, else a corresponding error value
>> + */
>> +static int ti_sci_reset_assert(struct reset_controller_dev *rcdev,
>> +			       unsigned long id)
>> +{
>> +	return ti_sci_reset_set(rcdev, id, true);
>> +}
>> +
>> +/**
>> + * ti_sci_reset_deassert() - deassert device reset
>> + * @rcdev: reset controller entity
>> + * @id: ID of the reset to be deasserted
>> + *
>> + * This function implements the reset driver op to deassert a device's reset
>> + * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
>> + * with the corresponding parameters as passed in, but with the @assert
>> + * argument set to false for deasserting the reset.
>> + *
>> + * Return: 0 for successful request, else a corresponding error value
>> + */
>> +static int ti_sci_reset_deassert(struct reset_controller_dev *rcdev,
>> +				 unsigned long id)
>> +{
>> +	return ti_sci_reset_set(rcdev, id, false);
>> +}
>> +
>> +/**
>> + * ti_sci_reset_status() - check device reset status
>> + * @rcdev: reset controller entity
>> + * @id: ID of reset to be checked
>> + *
>> + * This function implements the reset driver op to return the status of a
>> + * device's reset using the TI SCI protocol. The reset register value is read
>> + * by invoking the TI SCI device opertation .get_device_resets(), and the
>> + * status of the specific reset is extracted and returned using this reset's
>> + * reset mask.
>> + *
>> + * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
>> + */
>> +static int ti_sci_reset_status(struct reset_controller_dev *rcdev,
>> +			       unsigned long id)
>> +{
>> +	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
>> +	const struct ti_sci_handle *sci = data->sci;
>> +	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
>> +	struct ti_sci_reset_control *control;
>> +	u32 reset_state;
>> +	int ret;
>> +
>> +	control = idr_find(&data->idr, id);
>> +	if (!control)
>> +		return -EINVAL;
>> +
>> +	ret = dev_ops->get_device_resets(sci, control->dev_id,
>> +					 &reset_state);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return reset_state & control->reset_mask;
>> +}
>> +
>> +static struct reset_control_ops ti_sci_reset_ops = {
>> +	.assert		= ti_sci_reset_assert,
>> +	.deassert	= ti_sci_reset_deassert,
>> +	.status		= ti_sci_reset_status,
>> +};
>> +
>> +/**
>> + * ti_sci_reset_of_xlate() - translate a set of OF arguments to a reset ID
>> + * @rcdev: reset controller entity
>> + * @reset_spec: OF reset argument specifier
>> + *
>> + * This function performs the translation of the reset argument specifier
>> + * values defined in a reset consumer device node. The function allocates a
>> + * reset control structure for that device reset, and will be used by the
>> + * driver for performing any reset functions on that reset. An idr structure
>> + * is allocated and used to map to the reset control structure. This idr
>> + * is used by the driver to do reset lookups.
>> + *
>> + * Return: 0 for successful request, else a corresponding error value
>> + */
>> +static int ti_sci_reset_of_xlate(struct reset_controller_dev *rcdev,
>> +				 const struct of_phandle_args *reset_spec)
>> +{
>> +	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
>> +	struct ti_sci_reset_control *control;
>> +
>> +	if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
>> +		return -EINVAL;
>> +
>> +	control = devm_kzalloc(data->dev, sizeof(*control), GFP_KERNEL);
>> +	if (!control)
>> +		return -ENOMEM;
>> +
>> +	control->dev_id = reset_spec->args[0];
>> +	control->reset_mask = reset_spec->args[1];
>> +
>> +	return idr_alloc(&data->idr, control, 0, 0, GFP_KERNEL);
>> +}
>> +
>> +static const struct of_device_id ti_sci_reset_of_match[] = {
>> +	{ .compatible = "ti,sci-reset", },
>> +	{ /* sentinel */ },
>> +};
>> +MODULE_DEVICE_TABLE(of, ti_sci_reset_of_match);
>> +
>> +static int ti_sci_reset_probe(struct platform_device *pdev)
>> +{
>> +	struct ti_sci_reset_data *data;
>> +
>> +	if (!pdev->dev.of_node)
>> +		return -ENODEV;
>> +
>> +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +	data->sci = devm_ti_sci_get_handle(&pdev->dev);
>> +	if (IS_ERR(data->sci))
>> +		return PTR_ERR(data->sci);
>> +
>> +	data->rcdev.ops = &ti_sci_reset_ops;
>> +	data->rcdev.owner = THIS_MODULE;
>> +	data->rcdev.of_node = pdev->dev.of_node;
>> +	data->rcdev.of_reset_n_cells = 2;
>> +	data->rcdev.of_xlate = ti_sci_reset_of_xlate;
>> +	data->dev = &pdev->dev;
>> +	idr_init(&data->idr);
>> +
>> +	platform_set_drvdata(pdev, data);
>> +
>> +	return reset_controller_register(&data->rcdev);
>> +}
>> +
>> +static int ti_sci_reset_remove(struct platform_device *pdev)
>> +{
>> +	struct ti_sci_reset_data *data = platform_get_drvdata(pdev);
>> +
>> +	reset_controller_unregister(&data->rcdev);
>> +
>> +	idr_destroy(&data->idr);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver ti_sci_reset_driver = {
>> +	.probe = ti_sci_reset_probe,
>> +	.remove = ti_sci_reset_remove,
>> +	.driver = {
>> +		.name = "ti-sci-reset",
>> +		.of_match_table = ti_sci_reset_of_match,
>> +	},
>> +};
>> +module_platform_driver(ti_sci_reset_driver);
>> +
>> +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
>> +MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reset driver");
>> +MODULE_LICENSE("GPL v2");
> 
> regards
> Philipp
> 

^ permalink raw reply

* [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
From: Nipun Gupta @ 2016-11-03 18:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <05d13b82-6fb6-95c0-8e64-54bcf57b3221@arm.com>

Hi Robin,

> -----Original Message-----
> From: Robin Murphy [mailto:robin.murphy at arm.com]
> Sent: Thursday, November 03, 2016 16:39
> To: Nipun Gupta <nipun.gupta@nxp.com>; will.deacon at arm.com; linux-arm-
> kernel at lists.infradead.org; iommu at lists.linux-foundation.org
> Cc: Stuart Yoder <stuart.yoder@nxp.com>
> Subject: Re: [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable
> caching of bypass entries
> 
> On 02/11/16 19:26, Nipun Gupta wrote:
> >
> > Hi Robin,
> >
> >> -----Original Message-----
> >> From: Robin Murphy [mailto:robin.murphy at arm.com]
> >> Sent: Wednesday, November 02, 2016 16:51
> >> To: Nipun Gupta <nipun.gupta@nxp.com>; will.deacon at arm.com; linux-arm-
> >> kernel at lists.infradead.org; iommu at lists.linux-foundation.org
> >> Cc: Stuart Yoder <stuart.yoder@nxp.com>
> >> Subject: Re: [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to
> enable
> >> caching of bypass entries
> >>
> >> Hi Nipun,
> >>
> >> On 02/11/16 13:35, Nipun Gupta wrote:
> >>> The SMTNMB_TLBEN in the Auxiliary Configuration Register (ACR)
> >>> provides an option to enable the updation of TLB in case of bypass
> >>> transactions due to no stream match in the stream match table. This
> >>> reduces the latencies of the subsequent transactions with the same stream-
> id
> >> which bypasses the SMMU.
> >>> This provides a significant performance benefit for certain networking
> >>> workloads.
> >>
> >> ...at the cost of increased TLB contention against other workloads.
> >> However, in the general case we'd expect the system to be fully described, so
> if
> >> there aren't any unmatched Stream IDs there hopefully shouldn't be an
> impact
> >> to leaving this switched on. I'd be interested to see some actual performance
> >> numbers, though - you already know my opinion about unsubstantiated
> quotes
> >> from the MMU-500 TRM.
> >
> > With this change we have seen substantial performance improvement of ~9-
> 10%
> > with DPDK l3fwd application
> (http://dpdk.org/doc/guides/sample_app_ug/l3_forward.html)
> > on NXP's LS2088a platform (single core as well as multi-core). Also, with ODP
> reflector application
> > (loopback mode - NXP in-house) we have seen 5% improvement in
> performance on
> > LS1088 platform.
> >
> > W.r.t. the read latencies, they are reduced to avg. ~50 platform cycles from
> avg. ~140
> > platform cycles per memory read transactions which follow this bypass path
> (on LS2088
> > with DPDK l3fwd application).
> >
> > (Apologies, I cannot share the DPDK/ODP exact performance numbers on the
> mailing list).
> 
> That's understandable, and I'm not sure I'd know how to interpret them
> anyway ;) I reckon the percentages make a sufficiently compelling
> qualification of the improvement, so it would be good to have that
> summarised in the commit log.

Sure, I'll add a part of it in the commit log.

> 
> >>
> >>> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> >>> ---
> >>>  drivers/iommu/arm-smmu.c | 21 +++++++++++++++------
> >>>  1 file changed, 15 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index
> >>> ce2a9d4..7010a5c 100644
> >>> --- a/drivers/iommu/arm-smmu.c
> >>> +++ b/drivers/iommu/arm-smmu.c
> >>> @@ -246,6 +246,7 @@ enum arm_smmu_s2cr_privcfg {
> >>>
> >>>  #define ARM_MMU500_ACTLR_CPRE		(1 << 1)
> >>>
> >>> +#define ACR_SMTNMB_TLBEN		(1 << 8)
> >>
> >> ACR is entirely implementation-defined, so there are no generic field names.
> >> Please follow the naming convention handily demonstrated in the subsequent
> >> context line.
> >>
> >>>  #define ARM_MMU500_ACR_CACHE_LOCK	(1 << 26)
> >>
> >> Actually, can we also please keep these in descending order of bit position
> like
> >> everything else?
> >>
> >>>  #define CB_PAR_F			(1 << 0)
> >>> @@ -1569,18 +1570,26 @@ static void arm_smmu_device_reset(struct
> >> arm_smmu_device *smmu)
> >>>  	for (i = 0; i < smmu->num_mapping_groups; ++i)
> >>>  		arm_smmu_write_sme(smmu, i);
> >>>
> >>> +	/* Get the major rev required for configuring ACR */
> >>
> >> That comment is nonsense.
> >>
> >>> +	reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
> >>> +	major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
> >>> +
> >>>  	/*
> >>>  	 * Before clearing ARM_MMU500_ACTLR_CPRE, need to
> >>>  	 * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
> >>>  	 * bit is only present in MMU-500r2 onwards.
> >>>  	 */
> >>> -	reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
> >>> -	major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
> >>> -	if ((smmu->model == ARM_MMU500) && (major >= 2)) {
> >>> -		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
> >>> +	reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
> >>> +	if ((smmu->model == ARM_MMU500) && (major >= 2))
> >>>  		reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
> >>> -		writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
> >>> -	}
> >>> +
> >>> +	/*
> >>> +	 * Set the SMTNMB_TLBEN in ACR so that the transactions which
> >>> +	 * bypass with SMMU due to no stream match found in the SMR table
> >>> +	 * are updated in the TLB's.
> >>
> >> Or simply, e.g. "Allow unmatched Stream IDs to allocate bypass TLB entries
> for
> >> reduced latency". It's already clear from the code what bit's being set where,
> we
> >> only need to remember *why*.
> >>
> >>> +	 */
> >>> +	reg |= ACR_SMTNMB_TLBEN;
> >>> +	writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
> >>
> >> Are you sure it's perfectly fine to set that implementation-defined bit on any
> >> SMMU implementation other than the two-and-a-half ARM Ltd. ones which
> >> happen to share the same meaning? I'm certainly not.
> >>
> >> The correct flow would be something like this:
> >>
> >> 	if (smmu->model == ARM_MMU500) {
> >> 		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
> >> 		major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
> >> 		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
> >> 		if (major >= 2)
> >> 	  		reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
> >> 		reg |= ACR_SMTNMB_TLBEN;
> >> 		writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
> >> 	}
> >>
> >> The shape of the current code avoids an extra level of indentation, but once
> you
> >> have to have the nested conditional anyway, it might as well all be predicated
> >> appropriately.
> >>
> >
> > Thank you for providing the useful comments. I would incorporate them all in
> next version :).
> 
> Cool. Just for clarity (I realise I was thinking it, but never said it
> outright), whilst MMU-40x do share the same feature with the same ACR
> bit definition as MMU-500, I'd be inclined not to bother with them.
> Since the monolithic microarchitecture means there's normally a separate
> MMU-40x per device, if you don't want translation for that device you
> can simply not probe the thing to turn it on in the first place.
> 

This seems a pretty decent reason to have this bit set only for MMU-500.
I'll send a patch v2 soon.

Thanks,
Nipun

> Robin.
> 
> >
> > Regards,
> > Nipun
> >
> >> Robin.
> >>
> >>>  	/* Make sure all context banks are disabled and clear CB_FSR  */
> >>>  	for (i = 0; i < smmu->num_context_banks; ++i) {
> >>>
> >

^ permalink raw reply

* [RESEND PATCH v1 05/11] dt-bindings: perf: hisi: Add Devicetree bindings for Hisilicon SoC PMU
From: Krzysztof Kozlowski @ 2016-11-03 18:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478151727-20250-6-git-send-email-anurup.m@huawei.com>

On Thu, Nov 03, 2016 at 01:42:01AM -0400, Anurup M wrote:
> 	1) Device tree bindings for Hisilicon SoC PMU.
> 	2) Add example for Hisilicon L3 cache, MN and DDRC PMU.

Get rid of this weird indentation in all patches.


> 
> Signed-off-by: Anurup M <anurup.m@huawei.com>
> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> ---
>  .../devicetree/bindings/arm/hisilicon/pmu.txt      | 127 +++++++++++++++++++++
>  1 file changed, 127 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> new file mode 100644
> index 0000000..e7b35e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> @@ -0,0 +1,127 @@
> +Hisilicon SoC hip05/06/07 ARMv8 PMU
> +===================================
> +
> +The Hisilicon SoC chips like hip05/06/07 etc. consist of varous independent
> +system device PMU's such as L3 cache (L3C), Miscellaneous Nodes(MN) and DDR
> +comtroller. These PMU devices are independent and have hardware logic to
> +gather statistics and performance information.
> +
> +HiSilicon SoC chip is encapsulated by multiple CPU and IO die's. The CPU die
> +is called as Super CPU cluster (SCCL) which includes 16 cpu-cores. Every SCCL
> +is further grouped as CPU clusters (CCL) which includes 4 cpu-cores each.
> +e.g. In the case of hip05/06/07, each SCCL has 1 L3 cache and 1 MN PMU device.
> +
> +The Hisilicon SoC PMU DT node bindigs for uncore PMU devices are as below.
> +For PMU devices like L3 cache. MN etc. which are accessed using the djtag,
> +the parent node will be the djtag node of the corresponding CPU die(SCCL).
> +
> +For uncore PMU devices there are some common required properties as detailed
> +below.
> +
> +Required properties:
> +	- compatible : This field contain two values. The first value is
> +		always "hisilicon" and second value is the Module type as shown
> +		in below examples:

Over-complicated sentence. Just:

	- compatible : One of:
		"hisilicon,hisi-pmu-l3c-v1" for Hisilicon SoC L3C PMU
			device (Version 1)
		...
		...

BTW, No need of CC-ing me. I am not a maintainer of relevant subsystems.

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH 10/13] ARM: dts: exynos: replace to "max-frequecy" instead of "clock-freq-min-max"
From: Krzysztof Kozlowski @ 2016-11-03 18:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103062135.10697-11-jh80.chung@samsung.com>

On Thu, Nov 03, 2016 at 03:21:32PM +0900, Jaehoon Chung wrote:
> In drivers/mmc/core/host.c, there is "max-frequency" property.
> It should be same behavior. So Use the "max-frequency" instead of
> "clock-freq-min-max".
> 
> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
>  arch/arm/boot/dts/exynos3250-artik5-eval.dts | 2 +-
>  arch/arm/boot/dts/exynos3250-artik5.dtsi     | 2 +-
>  arch/arm/boot/dts/exynos3250-monk.dts        | 2 +-
>  arch/arm/boot/dts/exynos3250-rinato.dts      | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)

This looks totally independent to rest of patches so it can be applied
separately without any functional impact (except lack of minimum
frequency). Is that correct?

Best regards,
Krzysztof

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox