Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH] of: overlay: validate offset from property fixups
From: Frank Rowand @ 2018-05-17 16:58 UTC (permalink / raw)
  To: Rob Herring, pantelis.antoniou, Pantelis Antoniou
  Cc: Dan Carpenter, devicetree, linux-kernel
In-Reply-To: <21ae05b7-e9d4-d518-c341-861c74f32922@gmail.com>

On 05/17/18 09:56, Frank Rowand wrote:
> Hi Rob,
> 
> On 05/16/18 21:19, frowand.list@gmail.com wrote:
>> From: Frank Rowand <frank.rowand@sony.com>
>>
>> The smatch static checker marks the data in offset as untrusted,
>> leading it to warn:
>>
>>   drivers/of/resolver.c:125 update_usages_of_a_phandle_reference()
>>   error: buffer underflow 'prop->value' 's32min-s32max'
>>
>> Add check to verify that offset is within the property data.
>>
>> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
>> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
>> ---
>>  drivers/of/resolver.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>> index 65d0b7adfcd4..7edfac6f1914 100644
>> --- a/drivers/of/resolver.c
>> +++ b/drivers/of/resolver.c
>> @@ -122,6 +122,11 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay,
>>  			goto err_fail;
>>  		}
>>  
>> +		if (offset < 0 || offset + sizeof(__be32) > prop->length) {
>> +			err = -EINVAL;
>> +			goto err_fail;
>> +		}
>> +
>>  		*(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
>>  	}
>>  
>>
> 
> I should have mentioned that this results in a new compile warning
> for W=2 and W=3.  The new if statement results in:
> 

W=2 warning is:

> drivers/of/resolver.c:125:45: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

W=3 warning is:

drivers/of/resolver.c:125:3: warning: conversion to 'unsigned int' from 'int' may change the sign of the result [-Wsign-conversion]

> 
> There are other pre-existing warnings in the same file for comparing
> an integer to prop->length.  The correct solution is probably to
> change the type of the length field in struct property to be
> unsigned.  I have added that task to my todo list.
> 
> -Frank
> 

^ permalink raw reply

* Re: [PATCH v2 01/40] iommu: Introduce Shared Virtual Addressing API
From: Jacob Pan @ 2018-05-17 17:00 UTC (permalink / raw)
  To: Jean-Philippe Brucker
  Cc: xieyisheng1@huawei.com, liubo95@huawei.com, kvm@vger.kernel.org,
	linux-pci@vger.kernel.org, xuzaibo@huawei.com,
	jonathan.cameron@huawei.com, Will Deacon, okaya@codeaurora.org,
	linux-mm@kvack.org, yi.l.liu@intel.com, ashok.raj@intel.com,
	tn@semihalf.com, joro@8bytes.org, robdclark@gmail.com,
	bharatku@xilinx.com, linux-acpi@vger.kernel.org,
	liudongdong3@huawei.com, rfranz@cavium.com,
	devicetree@vger.kernel.org
In-Reply-To: <96c1e0f0-0aa7-badf-123e-cbb1b05e645e@arm.com>

On Thu, 17 May 2018 11:02:02 +0100
Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote:

> Hi Jacob,
> 
> Thanks for reviewing this
> 
> On 16/05/18 21:41, Jacob Pan wrote:
>  [...]  
> > seems the min_pasid never gets used. do you really need it?  
> 
> Yes, the SMMU sets it to 1 in patch 28/40, because it needs to reserve
> PASID 0
> 
>  [...]  
> > should it be !features?  
> 
> This checks if the user sets any unsupported bit in features. No
> feature is supported right now, but patch 09/40 adds
> IOMMU_SVA_FEAT_IOPF, and changes this line to "features &
> ~IOMMU_SVA_FEAT_IOPF"
> 
> >> +	mutex_lock(&dev->iommu_param->lock);
> >> +	param = dev->iommu_param->sva_param;
> >> +	dev->iommu_param->sva_param = NULL;
> >> +	mutex_unlock(&dev->iommu_param->lock);
> >> +	if (!param)
> >> +		return -ENODEV;
> >> +
> >> +	if (domain->ops->sva_device_shutdown)
> >> +		domain->ops->sva_device_shutdown(dev, param);  
> > seems a little mismatch here, do you need pass the param. I don't
> > think there is anything else model specific iommu driver need to do
> > for the param.  
> 
> SMMU doesn't use it, but maybe it would remind other IOMMU driver
> which features were enabled, so they don't have to keep track of that
> themselves? I can remove it if it isn't useful
> 
If there is a use case, I guess iommu driver can always retrieve the
param from struct device.
> Thanks,
> Jean

[Jacob Pan]

^ permalink raw reply

* Re: [PATCH] pci: cadence: Host and EP driver updates for PHY and power management
From: Lorenzo Pieralisi @ 2018-05-17 17:05 UTC (permalink / raw)
  To: Alan Douglas
  Cc: bhelgaas@google.com, kishon@ti.com, linux-pci@vger.kernel.org,
	cyrille.pitchen@free-electrons.com, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, nsekhar@ti.com
In-Reply-To: <SN6PR07MB451229DF639238CD7F15FDCFD8920@SN6PR07MB4512.namprd07.prod.outlook.com>

On Wed, May 16, 2018 at 01:06:05PM +0000, Alan Douglas wrote:
> From: Alan Douglas <adouglas@cadence.com>
> 
> This patch is based on next branch in Bjorn Helgaas' linux-pci git repository.
This sentence does not belong in a commit log and you should not be
basing patches on top of Bjorn's next branch, use v4.17-rc1, that is
an immutable commit.

> Allow optional list of generic PHYs to be provided via DTS for cadence
> RP and EP drivers.  Added power management ops which will
> enable/disable these PHYs.  Corrected parameters for cdns_pcie_writel
> function, value to be written had too small width.

Too many things at once. Each patch must solve one logical problem
and one only - it is easier to understand why if you think that
a patch may need to be reverted - if many changes are lumped together
this becomes complicated, that's one of the reasons.

So, please split this patch and send a v2, thank you.

Lorenzo

> Signed-off-by: Alan Douglas <adouglas@cadence.com>
> ---
>  .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt  |    4 +
>  .../bindings/pci/cdns,cdns-pcie-host.txt           |    5 +
>  drivers/pci/cadence/pcie-cadence-ep.c              |   15 +++-
>  drivers/pci/cadence/pcie-cadence-host.c            |   36 ++++++-
>  drivers/pci/cadence/pcie-cadence.c                 |  123 ++++++++++++++++++++
>  drivers/pci/cadence/pcie-cadence.h                 |   13 ++-
>  6 files changed, 193 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
> index 9a30523..e40c635 100644
> --- a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
> +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
> @@ -9,6 +9,8 @@ Required properties:
>  
>  Optional properties:
>  - max-functions: Maximum number of functions that can be configured (default 1).
> +- phys: From PHY bindings: List of Generic PHY phandles.
> +- phy-names:  List of names to identify the PHY.
>  
>  Example:
>  
> @@ -19,4 +21,6 @@ pcie@fc000000 {
>  	reg-names = "reg", "mem";
>  	cdns,max-outbound-regions = <16>;
>  	max-functions = /bits/ 8 <8>;
> +	phys = <&ep_phy0 &ep_phy1>;
> +	phy-names = "pcie-lane0","pcie-lane1";
>  };
> diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
> index 20a33f3..13be218 100644
> --- a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
> +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
> @@ -24,6 +24,8 @@ Optional properties:
>    translations (default 32)
>  - vendor-id: The PCI vendor ID (16 bits, default is design dependent)
>  - device-id: The PCI device ID (16 bits, default is design dependent)
> +- phys: From PHY bindings: List of Generic PHY phandles.
> +- phy-names:  List of names to identify the PHY.
>  
>  Example:
>  
> @@ -57,4 +59,7 @@ pcie@fb000000 {
>  	interrupt-map-mask = <0x0 0x0 0x0  0x7>;
>  
>  	msi-parent = <&its_pci>;
> +
> +	phys = <&pcie_phy0>;
> +	phy-names = "pcie-phy";
>  };
> diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c
> index 3d8283e..e74b8a4 100644
> --- a/drivers/pci/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/cadence/pcie-cadence-ep.c
> @@ -439,6 +439,7 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
>  	struct pci_epc *epc;
>  	struct resource *res;
>  	int ret;
> +	int phy_count;
>  
>  	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
>  	if (!ep)
> @@ -472,6 +473,12 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
>  	if (!ep->ob_addr)
>  		return -ENOMEM;
>  
> +	ret = cdns_pcie_init_phy(dev, pcie);
> +	if (ret) {
> +		dev_err(dev, "failed to init phy\n");
> +		return ret;
> +	}
> +	platform_set_drvdata(pdev, pcie);
>  	pm_runtime_enable(dev);
>  	ret = pm_runtime_get_sync(dev);
>  	if (ret < 0) {
> @@ -520,6 +527,10 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
>  
>   err_get_sync:
>  	pm_runtime_disable(dev);
> +	cdns_pcie_disable_phy(pcie);
> +	phy_count = pcie->phy_count;
> +	while (phy_count--)
> +		device_link_del(pcie->link[phy_count]);
>  
>  	return ret;
>  }
> @@ -527,6 +538,7 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
>  static void cdns_pcie_ep_shutdown(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> +	struct cdns_pcie *pcie = dev_get_drvdata(dev);
>  	int ret;
>  
>  	ret = pm_runtime_put_sync(dev);
> @@ -535,13 +547,14 @@ static void cdns_pcie_ep_shutdown(struct platform_device *pdev)
>  
>  	pm_runtime_disable(dev);
>  
> -	/* The PCIe controller can't be disabled. */
> +	cdns_pcie_disable_phy(pcie);
>  }
>  
>  static struct platform_driver cdns_pcie_ep_driver = {
>  	.driver = {
>  		.name = "cdns-pcie-ep",
>  		.of_match_table = cdns_pcie_ep_of_match,
> +		.pm	= &cdns_pcie_pm_ops,
>  	},
>  	.probe = cdns_pcie_ep_probe,
>  	.shutdown = cdns_pcie_ep_shutdown,
> diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c
> index a4ebbd3..992ebe2 100644
> --- a/drivers/pci/cadence/pcie-cadence-host.c
> +++ b/drivers/pci/cadence/pcie-cadence-host.c
> @@ -37,7 +37,6 @@ struct cdns_pcie_rc {
>  	u16			vendor_id;
>  	u16			device_id;
>  };
> -
>  static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
>  				      int where)
>  {
> @@ -46,6 +45,7 @@ struct cdns_pcie_rc {
>  	struct cdns_pcie *pcie = &rc->pcie;
>  	unsigned int busn = bus->number;
>  	u32 addr0, desc0;
> +	u32 link_status;
>  
>  	if (busn == rc->bus_range->start) {
>  		/*
> @@ -58,6 +58,11 @@ struct cdns_pcie_rc {
>  
>  		return pcie->reg_base + (where & 0xfff);
>  	}
> +	/* Check that the link is up. Clear AXI link-down status  */
> +	link_status = cdns_pcie_readl(pcie, CDNS_PCIE_LM_BASE);
> +	if (!(link_status & 0x1))
> +		return NULL;
> +	cdns_pcie_writel(pcie, CDNS_PCIE_AT_LINKDOWN, 0x0);
>  
>  	/* Update Output registers for AXI region 0. */
>  	addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
> @@ -239,6 +244,7 @@ static int cdns_pcie_host_probe(struct platform_device *pdev)
>  	struct cdns_pcie *pcie;
>  	struct resource *res;
>  	int ret;
> +	int phy_count;
>  
>  	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
>  	if (!bridge)
> @@ -290,6 +296,13 @@ static int cdns_pcie_host_probe(struct platform_device *pdev)
>  	}
>  	pcie->mem_res = res;
>  
> +	ret = cdns_pcie_init_phy(dev, pcie);
> +	if (ret) {
> +		dev_err(dev, "failed to init phy\n");
> +		return ret;
> +	}
> +	platform_set_drvdata(pdev, pcie);
> +
>  	pm_runtime_enable(dev);
>  	ret = pm_runtime_get_sync(dev);
>  	if (ret < 0) {
> @@ -322,15 +335,36 @@ static int cdns_pcie_host_probe(struct platform_device *pdev)
>  
>   err_get_sync:
>  	pm_runtime_disable(dev);
> +	cdns_pcie_disable_phy(pcie);
> +	phy_count = pcie->phy_count;
> +	while (phy_count--)
> +		device_link_del(pcie->link[phy_count]);
>  
>  	return ret;
>  }
>  
> +static void cdns_pcie_shutdown(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct cdns_pcie *pcie = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = pm_runtime_put_sync(dev);
> +	if (ret < 0)
> +		dev_dbg(dev, "pm_runtime_put_sync failed\n");
> +
> +	pm_runtime_disable(dev);
> +	cdns_pcie_disable_phy(pcie);
> +}
> +
> +
>  static struct platform_driver cdns_pcie_host_driver = {
>  	.driver = {
>  		.name = "cdns-pcie-host",
>  		.of_match_table = cdns_pcie_host_of_match,
> +		.pm	= &cdns_pcie_pm_ops,
>  	},
>  	.probe = cdns_pcie_host_probe,
> +	.shutdown = cdns_pcie_shutdown,
>  };
>  builtin_platform_driver(cdns_pcie_host_driver);
> diff --git a/drivers/pci/cadence/pcie-cadence.c b/drivers/pci/cadence/pcie-cadence.c
> index 138d113..7a34780 100644
> --- a/drivers/pci/cadence/pcie-cadence.c
> +++ b/drivers/pci/cadence/pcie-cadence.c
> @@ -124,3 +124,126 @@ void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0);
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0);
>  }
> +
> +void cdns_pcie_disable_phy(struct cdns_pcie *pcie)
> +{
> +	int i = pcie->phy_count;
> +
> +	while (i--) {
> +		phy_power_off(pcie->phy[i]);
> +		phy_exit(pcie->phy[i]);
> +	}
> +}
> +
> +int cdns_pcie_enable_phy(struct cdns_pcie *pcie)
> +{
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < pcie->phy_count; i++) {
> +		ret = phy_init(pcie->phy[i]);
> +		if (ret < 0)
> +			goto err_phy;
> +
> +		ret = phy_power_on(pcie->phy[i]);
> +		if (ret < 0) {
> +			phy_exit(pcie->phy[i]);
> +			goto err_phy;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_phy:
> +	while (--i >= 0) {
> +		phy_power_off(pcie->phy[i]);
> +		phy_exit(pcie->phy[i]);
> +	}
> +
> +	return ret;
> +}
> +
> +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
> +{
> +	struct device_node *np = dev->of_node;
> +	int phy_count;
> +	struct phy **phy;
> +	struct device_link **link;
> +	int i;
> +	int ret;
> +	const char *name;
> +
> +	phy_count = of_property_count_strings(np, "phy-names");
> +	if (phy_count < 1) {
> +		dev_err(dev, "no phy-names.  PHY will not be initialized\n");
> +		pcie->phy_count = 0;
> +		return 0;
> +	}
> +
> +	phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL);
> +	if (!phy)
> +		return -ENOMEM;
> +
> +	link = devm_kzalloc(dev, sizeof(*link) * phy_count, GFP_KERNEL);
> +	if (!link)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < phy_count; i++) {
> +		of_property_read_string_index(np, "phy-names", i, &name);
> +		phy[i] = devm_phy_get(dev, name);
> +		if (IS_ERR(phy))
> +			return PTR_ERR(phy);
> +
> +		link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
> +		if (!link[i]) {
> +			ret = -EINVAL;
> +			goto err_link;
> +		}
> +	}
> +
> +	pcie->phy_count = phy_count;
> +	pcie->phy = phy;
> +	pcie->link = link;
> +
> +	ret =  cdns_pcie_enable_phy(pcie);
> +	if (ret)
> +		goto err_link;
> +
> +	return 0;
> +
> +err_link:
> +	while (--i >= 0)
> +		device_link_del(link[i]);
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int cdns_pcie_suspend_noirq(struct device *dev)
> +{
> +	struct cdns_pcie *pcie = dev_get_drvdata(dev);
> +
> +	cdns_pcie_disable_phy(pcie);
> +
> +	return 0;
> +}
> +
> +static int cdns_pcie_resume_noirq(struct device *dev)
> +{
> +	struct cdns_pcie *pcie = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = cdns_pcie_enable_phy(pcie);
> +	if (ret) {
> +		dev_err(dev, "failed to enable phy\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +const struct dev_pm_ops cdns_pcie_pm_ops = {
> +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_pcie_suspend_noirq,
> +				      cdns_pcie_resume_noirq)
> +};
> diff --git a/drivers/pci/cadence/pcie-cadence.h b/drivers/pci/cadence/pcie-cadence.h
> index 4bb2733..ae6bf2a 100644
> --- a/drivers/pci/cadence/pcie-cadence.h
> +++ b/drivers/pci/cadence/pcie-cadence.h
> @@ -8,6 +8,7 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/pci.h>
> +#include <linux/phy/phy.h>
>  
>  /*
>   * Local Management Registers
> @@ -165,6 +166,9 @@
>  #define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
>  	(CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
>  
> +/* AXI link down register */
> +#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
> +
>  enum cdns_pcie_rp_bar {
>  	RP_BAR0,
>  	RP_BAR1,
> @@ -229,6 +233,9 @@ struct cdns_pcie {
>  	struct resource		*mem_res;
>  	bool			is_rc;
>  	u8			bus;
> +	int			phy_count;
> +	struct phy		**phy;
> +	struct device_link	**link;
>  };
>  
>  /* Register access */
> @@ -279,7 +286,7 @@ static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
>  }
>  
>  static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
> -					  u32 reg, u16 value)
> +					  u32 reg, u32 value)
>  {
>  	writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
>  }
> @@ -307,5 +314,9 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
>  						  u32 r, u64 cpu_addr);
>  
>  void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
> +void cdns_pcie_disable_phy(struct cdns_pcie *pcie);
> +int cdns_pcie_enable_phy(struct cdns_pcie *pcie);
> +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie);
> +extern const struct dev_pm_ops cdns_pcie_pm_ops;
>  
>  #endif /* _PCIE_CADENCE_H */
> -- 
> 1.7.1
> 

^ permalink raw reply

* Re: [PATCH v3] ASoC: ssm2305: Add amplifier driver
From: Mark Brown @ 2018-05-17 17:08 UTC (permalink / raw)
  To: Marco Felsch
  Cc: mark.rutland, devicetree, alsa-devel, lars, lgirdwood, robh+dt,
	kernel
In-Reply-To: <20180517135518.29345-1-m.felsch@pengutronix.de>


[-- Attachment #1.1: Type: text/plain, Size: 372 bytes --]

On Thu, May 17, 2018 at 03:55:18PM +0200, Marco Felsch wrote:

> +++ b/sound/soc/codecs/ssm2305.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Analog Devices SSM2305 Amplifier Driver

Please submit a followup patch which makes the entire comment a C++ one
rather than mixing them in the same comment block, it makes things look
more intentional.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: OMAP serial runtime PM and autosuspend (was: Re: [PATCH 4/7] dt-bindings: gnss: add u-blox binding))
From: Tony Lindgren @ 2018-05-17 17:10 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Sebastian Reichel, H. Nikolaus Schaller, Andreas Kemnade,
	Mark Rutland, Arnd Bergmann, Pavel Machek,
	linux-kernel@vger.kernel.org,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg Kroah-Hartman, Rob Herring, linux-serial, linux-omap,
	linux-pm
In-Reply-To: <20180517100948.GI30172@localhost>

* Johan Hovold <johan@kernel.org> [180517 10:12]:
> [ Sorry about the late reply. ]
> 
> On Wed, May 09, 2018 at 06:57:06AM -0700, Tony Lindgren wrote:
> > * Johan Hovold <johan@kernel.org> [180509 13:12]:
> 
> > > It seems we really should not be using the negative autosuspend to
> > > configure the RPM behaviour the way these drivers do. Perhaps a new
> > > mechanism is needed.
> > 
> > Hmm well simply defaulting to "on" instead of "auto" and setting the
> > autosuspend_ms to 3000 by default might be doable. I think that way
> > we can keep use_autosuspend() in probe. Let's hope there are no
> > existing use cases that would break with that.
> 
> No, defaulting to "on" (i.e. calling pm_runtime_forbid()) wouldn't work
> either as that would also prevent the device from runtime suspending
> just as the current negative autosuspend delay does.

Well in that case we should just stick with -1 value for the
autosuspend. And just do pm_runtime_put_sync_suspend() after
probe and on close.

> I fail to see how we can implement this using the current toolbox. What
> you're after here is really a mechanism for selecting between two
> different runtime PM schemes at runtime:
> 
> 	1. normal serial RPM, where the controller is active while the
> 	   port is open (this should be the safe default)

Agreed. And that is the case already.

> 	2. aggressive serial RPM, where the controller is allowed to
> 	   suspend while the port is open even though this may result in
> 	   lost characters when waking up on incoming data

In this case it seems that the only thing needed is to just
configure the autosuspend delay for the parent port. The use of
-1 has been around since the start of runtime PM AFAIK, so maybe
we should just document it. I guess we could also introduce
pm_runtime_block_autoidle_unless_configured() :)

> For normal ttys, we need a user-space interface for selecting between
> the two, and for serdev we may want a way to select the RPM scheme from
> within the kernel.
> 
> Note that with my serdev controller runtime PM patch, serdev core could
> always opt for aggressive PM (as by default serdev core holds an RPM
> reference for the controller while the port is open).

So if your serdev controller was to set the parent autosuspend
delay on open() and set it back on close() this should work?

Regards,

Tony

^ permalink raw reply

* Re: [PATCH v8 09/24] ASoC: qdsp6: q6afe: Add q6afe driver
From: Srinivas Kandagatla @ 2018-05-17 17:10 UTC (permalink / raw)
  To: Mark Brown
  Cc: andy.gross, linux-arm-msm, alsa-devel, robh+dt, bgoswami, gregkh,
	david.brown, mark.rutland, lgirdwood, plai, tiwai, perex,
	devicetree, linux-kernel, linux-arm-kernel, rohkumar, spatakok
In-Reply-To: <20180517065544.GO20254@sirena.org.uk>

Thanks for the review.

On 17/05/18 07:55, Mark Brown wrote:
> On Wed, May 09, 2018 at 01:56:20PM +0100, Srinivas Kandagatla wrote:
> 
>> +static struct q6afe_port *afe_find_port(struct q6afe *afe, int token)
>> +{
>> +	struct q6afe_port *p = NULL;
>> +	struct q6afe_port *ret = NULL;
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&afe->port_list_lock, flags);
>> +	list_for_each_entry(p, &afe->port_list, node)
>> +		if (p->token == token) {
>> +			ret = p;
>> +			break;
>> +		}
>> +
>> +	spin_unlock_irqrestore(&afe->port_list_lock, flags);
>> +	return ret;
> 
> This lock only protects the list, it does nothing to ensure that the
> port we look up is still valid by the time we return to the caller.
> That means we won't crash during list traversal but does nothing to
> ensure we won't crash immediately afterwards if the port is deallocated
> just after we look it up.  What stops that happening?

Each port is allocated and de-allocated in dai probe and remove calls 
respectively.

Lets say... So for this case to happen the dai has to be removed (unload 
module) at the same time when the interrupt callback happens due to 
delayed response from previous commands.

This case would be almost impossible because all the calls to afe 
service are synchronous with timeouts, if any of the previous calls 
times out the respective caller would get an error, this should prevent 
him from unloading the module in the first place.


thanks,
srini

> 

^ permalink raw reply

* Re: [v0 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
From: Taniya Das @ 2018-05-17 17:13 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, linux-kernel, linux-pm, Stephen Boyd,
	Rajendra Nayak, Amit Nischal, devicetree, amit.kucheria
In-Reply-To: <20180517101405.23oxyqpmpjhauflx@vireshk-i7>

Hi Viresh,

Thanks for the review comments, I have already fixed the resource 
comment in the v1 series which I sent across. I will fix the rest of the 
comments and send it for review.

On 5/17/2018 3:44 PM, Viresh Kumar wrote:
> On 17-05-18, 15:00, Taniya Das wrote:
>> The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
>> for hanging the frequency of CPUs. The driver implements the cpufreq driver
>> interface for this firmware.
>>
>> Signed-off-by: Taniya Das <tdas@codeaurora.org>
>> ---
>>   drivers/cpufreq/Kconfig.arm       |   9 ++
>>   drivers/cpufreq/Makefile          |   1 +
>>   drivers/cpufreq/qcom-cpufreq-fw.c | 318 ++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 328 insertions(+)
>>   create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c
>>
>> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
>> index 96b35b8..a50aa6e 100644
>> --- a/drivers/cpufreq/Kconfig.arm
>> +++ b/drivers/cpufreq/Kconfig.arm
>> @@ -301,3 +301,12 @@ config ARM_PXA2xx_CPUFREQ
>>   	  This add the CPUFreq driver support for Intel PXA2xx SOCs.
>>
>>   	  If in doubt, say N.
>> +
>> +config ARM_QCOM_CPUFREQ_FW
>> +	tristate "QCOM CPUFreq FW driver"
>> +	help
>> +	 Support for the CPUFreq FW driver.
>> +	 The CPUfreq FW preset in some QCOM chipsets offloads the steps
>> +	 necessary for changing the frequency of CPUs. The driver
>> +	 implements the cpufreq driver interface for this firmware.
>> +	 Say Y if you want to support CPUFreq FW.
>> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
>> index 8d24ade..a3edbce 100644
>> --- a/drivers/cpufreq/Makefile
>> +++ b/drivers/cpufreq/Makefile
>> @@ -85,6 +85,7 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)	+= tegra124-cpufreq.o
>>   obj-$(CONFIG_ARM_TEGRA186_CPUFREQ)	+= tegra186-cpufreq.o
>>   obj-$(CONFIG_ARM_TI_CPUFREQ)		+= ti-cpufreq.o
>>   obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)	+= vexpress-spc-cpufreq.o
>> +obj-$(CONFIG_ARM_QCOM_CPUFREQ_FW)	+= qcom-cpufreq-fw.o
>>
>>
>>   ##################################################################################
>> diff --git a/drivers/cpufreq/qcom-cpufreq-fw.c b/drivers/cpufreq/qcom-cpufreq-fw.c
>> new file mode 100644
>> index 0000000..67996d5
>> --- /dev/null
>> +++ b/drivers/cpufreq/qcom-cpufreq-fw.c
>> @@ -0,0 +1,318 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
>> + */
>> +
>> +#include <linux/cpufreq.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +
>> +#define INIT_RATE			300000000UL
>> +#define XO_RATE				19200000UL
>> +#define LUT_MAX_ENTRIES			40U
>> +#define CORE_COUNT_VAL(val)		((val & GENMASK(18, 16)) >> 16)
>> +#define LUT_ROW_SIZE			32
>> +
>> +struct cpufreq_qcom {
>> +	struct cpufreq_frequency_table *table;
>> +	struct device *dev;
>> +	void __iomem *perf_base;
>> +	void __iomem *lut_base;
>> +	cpumask_t related_cpus;
>> +	unsigned int max_cores;
>> +};
>> +
>> +static struct cpufreq_qcom *qcom_freq_domain_map[NR_CPUS];
>> +
>> +static int
>> +qcom_cpufreq_fw_target_index(struct cpufreq_policy *policy, unsigned int index)
>> +{
>> +	struct cpufreq_qcom *c = policy->driver_data;
>> +
>> +	if (index >= LUT_MAX_ENTRIES) {
>> +		dev_err(c->dev,
>> +		"Passing an index (%u) that's greater than max (%d)\n",
> 
> Alignment issues here. Run checkpatch --strict.
> 
>> +					index, LUT_MAX_ENTRIES - 1);
>> +		return -EINVAL;
>> +	}
>> +
>> +	writel_relaxed(index, c->perf_base);
>> +
>> +	/* Make sure the write goes through before proceeding */
>> +	mb();
>> +	return 0;
>> +}
>> +
>> +static unsigned int qcom_cpufreq_fw_get(unsigned int cpu)
>> +{
>> +	struct cpufreq_qcom *c;
>> +	unsigned int index;
>> +
>> +	c = qcom_freq_domain_map[cpu];
>> +	if (!c)
>> +		return -ENODEV;
>> +
>> +	index = readl_relaxed(c->perf_base);
>> +	index = min(index, LUT_MAX_ENTRIES - 1);
>> +
>> +	return c->table[index].frequency;
>> +}
>> +
>> +static int qcom_cpufreq_fw_cpu_init(struct cpufreq_policy *policy)
>> +{
>> +	struct cpufreq_qcom *c;
>> +	int ret;
>> +
>> +	c = qcom_freq_domain_map[policy->cpu];
>> +	if (!c) {
>> +		pr_err("No scaling support for CPU%d\n", policy->cpu);
>> +		return -ENODEV;
>> +	}
>> +
>> +	cpumask_copy(policy->cpus, &c->related_cpus);
>> +
>> +	policy->table = c->table;
>> +	policy->driver_data = c;
>> +
>> +	return ret;
>> +}
>> +
>> +static struct freq_attr *qcom_cpufreq_fw_attr[] = {
>> +	&cpufreq_freq_attr_scaling_available_freqs,
>> +	&cpufreq_freq_attr_scaling_boost_freqs,
>> +	NULL
>> +};
>> +
>> +static struct cpufreq_driver cpufreq_qcom_fw_driver = {
>> +	.flags		= CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
>> +			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
>> +	.verify		= cpufreq_generic_frequency_table_verify,
>> +	.target_index	= qcom_cpufreq_fw_target_index,
>> +	.get		= qcom_cpufreq_fw_get,
>> +	.init		= qcom_cpufreq_fw_cpu_init,
>> +	.name		= "qcom-cpufreq-fw",
>> +	.attr		= qcom_cpufreq_fw_attr,
>> +	.boost_enabled	= true,
>> +};
>> +
>> +static int qcom_read_lut(struct platform_device *pdev,
>> +			struct cpufreq_qcom *c)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	u32 data, src, lval, i, core_count, prev_cc = 0;
>> +
>> +	c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
>> +				sizeof(*c->table), GFP_KERNEL);
>> +	if (!c->table)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
>> +		data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
>> +		src = ((data & GENMASK(31, 30)) >> 30);
>> +		lval = (data & GENMASK(7, 0));
>> +		core_count = CORE_COUNT_VAL(data);
> 
> Why do you need this here ? And why do below in case this doesn't
> match max-cores count ?
> 
>> +
>> +		if (!src)
>> +			c->table[i].frequency = INIT_RATE / 1000;
>> +		else
>> +			c->table[i].frequency = XO_RATE * lval / 1000;
>> +
>> +		c->table[i].driver_data = c->table[i].frequency;
>> +
>> +		dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
>> +				i, c->table[i].frequency, core_count);
>> +
>> +		if (core_count != c->max_cores)
>> +			c->table[i].frequency = CPUFREQ_ENTRY_INVALID;
>> +
>> +		/*
>> +		 * Two of the same frequencies with the same core counts means
>> +		 * end of table.
>> +		 */
>> +		if (i > 0 && c->table[i - 1].driver_data ==
>> +					c->table[i].driver_data
>> +					&& prev_cc == core_count) {
>> +			struct cpufreq_frequency_table *prev = &c->table[i - 1];
>> +
>> +			if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
>> +				prev->flags = CPUFREQ_BOOST_FREQ;
>> +				prev->frequency = prev->driver_data;
>> +			}
>> +
>> +			break;
>> +		}
>> +		prev_cc = core_count;
>> +	}
>> +	c->table[i].frequency = CPUFREQ_TABLE_END;
>> +
>> +	return 0;
>> +}
>> +
>> +static int qcom_get_related_cpus(struct device_node *np, struct cpumask *m)
>> +{
>> +	struct device_node *dev_phandle;
>> +	struct device *cpu_dev;
>> +	int cpu, i = 0, ret = -ENOENT;
>> +
>> +	dev_phandle = of_parse_phandle(np, "qcom,cpulist", i++);
> 
> TBH, I am not a great fan of the CPU phandle list you have created
> here. Lets see what Rob has to say on this.
> 
>> +	while (dev_phandle) {
>> +		for_each_possible_cpu(cpu) {
>> +			cpu_dev = get_cpu_device(cpu);
>> +			if (cpu_dev && cpu_dev->of_node == dev_phandle) {
>> +				cpumask_set_cpu(cpu, m);
>> +				ret = 0;
> 
> Maybe just remove this line ...
> 
>> +				break;
>> +			}
>> +		}
>> +		dev_phandle = of_parse_phandle(np, "qcom,cpulist", i++);
>> +	}
>> +
>> +	return ret;
> 
> and check for empty cpumask for an error here.
> 
>> +}
>> +
>> +static int qcom_cpu_resources_init(struct platform_device *pdev,
>> +						struct device_node *np)
> 
> You may want to align these properly. Try running checkpatch with
> --strict option.
> 
>> +{
>> +	struct cpufreq_qcom *c;
>> +	struct resource res;
>> +	struct device *dev = &pdev->dev;
>> +	void __iomem *en_base;
>> +	int cpu, index = 0, ret;
> 
> Why initialize index here ?
> 
>> +
>> +	c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
> 
> Check for a valid 'c' here ?
> 
>> +
>> +	res = platform_get_resource_byname(dev, IORESOURCE_MEM, "en_base");
> 
> You are assigning a pointer to a structure here :(
> 
>> +	if (!res) {
>> +		dev_err(dev, "Enable base not defined for %s\n", np->name);
>> +		return ret;
>> +	}
>> +
>> +	en_base = devm_ioremap(dev, res->start, resource_size(res));
> 
> You don't get a build error for doing res->start here ? Looks like you
> sent a driver upstream which doesn't even build.
> 
>> +	if (!en_base) {
>> +		dev_err(dev, "Unable to map %s en-base\n", np->name);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	/* FW should be enabled state to proceed */
>> +	if (!(readl_relaxed(en_base) & 0x1)) {
>> +		dev_err(dev, "%s firmware not enabled\n", np->name);
>> +		return -ENODEV;
>> +	}
>> +
>> +	devm_iounmap(&pdev->dev, en_base);
>> +
>> +	index = of_property_match_string(np, "reg-names", "perf_base");
>> +	if (index < 0)
>> +		return index;
>> +
>> +	if (of_address_to_resource(np, index, &res))
>> +		return -ENOMEM;
>> +
>> +	c->perf_base = devm_ioremap(dev, res.start, resource_size(&res));
>> +	if (!c->perf_base) {
>> +		dev_err(dev, "Unable to map %s perf-base\n", np->name);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	index = of_property_match_string(np, "reg-names", "lut_base");
>> +	if (index < 0)
>> +		return index;
>> +
>> +	if (of_address_to_resource(np, index, &res))
>> +		return -ENOMEM;
>> +
>> +	c->lut_base = devm_ioremap(dev, res.start, resource_size(&res));
>> +	if (!c->lut_base) {
>> +		dev_err(dev, "Unable to map %s lut-base\n", np->name);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	ret = qcom_get_related_cpus(np, &c->related_cpus);
>> +	if (ret) {
>> +		dev_err(dev, "%s failed to get core phandles\n", np->name);
>> +		return ret;
>> +	}
>> +
>> +	c->max_cores = cpumask_weight(&c->related_cpus);
>> +
>> +	ret = qcom_read_lut(pdev, c);
>> +	if (ret) {
>> +		dev_err(dev, "%s failed to read LUT\n", np->name);
>> +		return ret;
>> +	}
>> +
>> +	for_each_cpu(cpu, &c->related_cpus)
>> +		qcom_freq_domain_map[cpu] = c;
>> +
>> +	return 0;
>> +}
>> +
>> +static int qcom_resources_init(struct platform_device *pdev)
>> +{
>> +	struct device_node *np;
>> +	int ret = -ENODEV;
>> +
>> +	for_each_available_child_of_node(pdev->dev.of_node, np) {
>> +		if (of_device_is_compatible(np, "cpufreq")) {
>> +			ret = qcom_cpu_resources_init(pdev, np);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +	}
>> +
>> +	return ret;
> 
> Don't initialize ret to -ENODEV, rather return -ENODEV directly here.
> That makes it more readable.
> 
>> +}
>> +
>> +static int qcom_cpufreq_fw_driver_probe(struct platform_device *pdev)
>> +{
>> +	int rc = 0;
> 
> Don't need to initialize to 0 here.
> 
>> +
>> +	/* Get the bases of cpufreq for domains */
>> +	rc = qcom_resources_init(pdev);
>> +	if (rc) {
>> +		dev_err(&pdev->dev, "CPUFreq resource init failed\n");
>> +		return rc;
>> +	}
>> +
>> +	rc = cpufreq_register_driver(&cpufreq_qcom_fw_driver);
>> +	if (rc) {
>> +		dev_err(&pdev->dev, "CPUFreq FW driver failed to register\n");
>> +		return rc;
>> +	}
>> +
>> +	dev_info(&pdev->dev, "QCOM CPUFreq FW driver inited\n");
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id match_table[] = {
>> +	{ .compatible = "qcom,cpufreq-fw" },
>> +	{}
>> +};
>> +
>> +static struct platform_driver qcom_cpufreq_fw_driver = {
>> +	.probe = qcom_cpufreq_fw_driver_probe,
>> +	.driver = {
>> +		.name = "qcom-cpufreq-fw",
>> +		.of_match_table = match_table,
>> +		.owner = THIS_MODULE,
>> +	},
>> +};
>> +
>> +static int __init qcom_cpufreq_fw_init(void)
>> +{
>> +	return platform_driver_register(&qcom_cpufreq_fw_driver);
>> +}
>> +subsys_initcall(qcom_cpufreq_fw_init);
> 
> Why this for a driver which can be built as a module ? You really want
> it to be built as a module ?
> 
>> +
>> +static void __exit qcom_cpufreq_fw_exit(void)
>> +{
>> +	platform_driver_unregister(&qcom_cpufreq_fw_driver);
>> +}
> 
> But you don't unregister the cpufreq driver ?
> 
>> +module_exit(qcom_cpufreq_fw_exit);
>> +
>> +MODULE_DESCRIPTION("QCOM CPU Frequency FW");
>> +MODULE_LICENSE("GPL v2");
>> --
>> Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
>> of the Code Aurora Forum, hosted by the  Linux Foundation.
> 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--

^ permalink raw reply

* Re: [PATCH v8 09/24] ASoC: qdsp6: q6afe: Add q6afe driver
From: Mark Brown @ 2018-05-17 17:23 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: mark.rutland, devicetree, alsa-devel, bgoswami, rohkumar,
	linux-arm-msm, plai, spatakok, lgirdwood, tiwai, david.brown,
	robh+dt, linux-arm-kernel, gregkh, andy.gross, linux-kernel
In-Reply-To: <507b8b76-0846-a492-73e6-782b9953bc36@linaro.org>


[-- Attachment #1.1: Type: text/plain, Size: 1327 bytes --]

On Thu, May 17, 2018 at 06:10:49PM +0100, Srinivas Kandagatla wrote:
> On 17/05/18 07:55, Mark Brown wrote:
> > On Wed, May 09, 2018 at 01:56:20PM +0100, Srinivas Kandagatla wrote:

> > This lock only protects the list, it does nothing to ensure that the
> > port we look up is still valid by the time we return to the caller.
> > That means we won't crash during list traversal but does nothing to
> > ensure we won't crash immediately afterwards if the port is deallocated
> > just after we look it up.  What stops that happening?

> Each port is allocated and de-allocated in dai probe and remove calls
> respectively.

> Lets say... So for this case to happen the dai has to be removed (unload
> module) at the same time when the interrupt callback happens due to delayed
> response from previous commands.

> This case would be almost impossible because all the calls to afe service
> are synchronous with timeouts, if any of the previous calls times out the
> respective caller would get an error, this should prevent him from unloading
> the module in the first place.

The user can also trigger manual unbinds without unloading the module,
and to be honet the scenario where the DSP has stopped responding well
and is delaying responses sounds like exactly the sort of time when
users might try to reload the driver...

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH RFC 3/6] hwmon: Add support for RPi voltage sensor
From: Eric Anholt @ 2018-05-17 17:25 UTC (permalink / raw)
  To: Guenter Roeck, Stefan Wahren
  Cc: Mark Rutland, devicetree, Jean Delvare, Noralf Trønnes,
	Scott Branden, Ray Jui, Phil Elwell, Rob Herring,
	bcm-kernel-feedback-list, linux-rpi-kernel, Florian Fainelli,
	linux-hwmon, linux-arm-kernel
In-Reply-To: <20180517164320.GA30364@roeck-us.net>


[-- Attachment #1.1: Type: text/plain, Size: 1090 bytes --]

Guenter Roeck <linux@roeck-us.net> writes:

> On Wed, May 16, 2018 at 09:59:01PM +0200, Stefan Wahren wrote:
>> Hi Guenter,
>> 
>> > Guenter Roeck <linux@roeck-us.net> hat am 16. Mai 2018 um 20:21 geschrieben:
>> > 
>> > 
>> > On Wed, May 16, 2018 at 03:37:04PM +0200, Stefan Wahren wrote:
>> > > Currently there is no easy way to detect under-voltage conditions on a remote
>> > > Raspberry Pi. This hwmon driver retrieves the state of the under-voltage sensor
>> > > via mailbox interface. The handling based on Noralf's modifications to the
>> > > downstream firmware driver. In case of an under-voltage condition only an entry
>> > > is written to the kernel log.
>> > > 
>> > 
>> > My major concern is how this is displayed with the 'sensors' command.
>> > Can you test and report ?
>> 
>> I get the following output:
>> rpi_volt-isa-0000
>> Adapter: ISA adapter
>> in0:              N/A  
>> 
> Ok, that works.

Thanks for the quick review on this, Guenter!  This driver is going to
help save a lot of people debugging time on rpis in the upstream kernel.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v8 09/24] ASoC: qdsp6: q6afe: Add q6afe driver
From: Srinivas Kandagatla @ 2018-05-17 17:53 UTC (permalink / raw)
  To: Mark Brown
  Cc: andy.gross, linux-arm-msm, alsa-devel, robh+dt, bgoswami, gregkh,
	david.brown, mark.rutland, lgirdwood, plai, tiwai, perex,
	devicetree, linux-kernel, linux-arm-kernel, rohkumar, spatakok
In-Reply-To: <20180517172308.GX20254@sirena.org.uk>



On 17/05/18 18:23, Mark Brown wrote:
> On Thu, May 17, 2018 at 06:10:49PM +0100, Srinivas Kandagatla wrote:
>> On 17/05/18 07:55, Mark Brown wrote:
>>> On Wed, May 09, 2018 at 01:56:20PM +0100, Srinivas Kandagatla wrote:
> 
>>> This lock only protects the list, it does nothing to ensure that the
>>> port we look up is still valid by the time we return to the caller.
>>> That means we won't crash during list traversal but does nothing to
>>> ensure we won't crash immediately afterwards if the port is deallocated
>>> just after we look it up.  What stops that happening?
> 
>> Each port is allocated and de-allocated in dai probe and remove calls
>> respectively.
> 
>> Lets say... So for this case to happen the dai has to be removed (unload
>> module) at the same time when the interrupt callback happens due to delayed
>> response from previous commands.
> 
>> This case would be almost impossible because all the calls to afe service
>> are synchronous with timeouts, if any of the previous calls times out the
>> respective caller would get an error, this should prevent him from unloading
>> the module in the first place.
> 
> The user can also trigger manual unbinds without unloading the module,
> and to be honet the scenario where the DSP has stopped responding well
> and is delaying responses sounds like exactly the sort of time when
> users might try to reload the driver...Yes, that is one possible usecase!
ref-counting port should stop that from happening.
I will add this in next spin!

thanks,
srini

^ permalink raw reply

* Re: [PATCH v4 03/12] clk: imx7d: fix mipi dphy div parent
From: Stephen Boyd @ 2018-05-17 18:05 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Steve Longerbeam, mchehab,
	sakari.ailus
  Cc: devel, devicetree, Greg Kroah-Hartman, Ryan Harkin,
	Rui Miguel Silva, Fabio Estevam, Shawn Guo, linux-clk,
	linux-media
In-Reply-To: <20180517125033.18050-4-rui.silva@linaro.org>

Quoting Rui Miguel Silva (2018-05-17 05:50:24)
> Fix the mipi dphy root divider to mipi_dphy_pre_div, this would remove a orphan
> clock and set the correct parent.
> 
> before:
> cat clk_orphan_summary
>                                  enable  prepare  protect
>    clock                          count    count    count        rate   accuracy   phase
> ----------------------------------------------------------------------------------------
>  mipi_dphy_post_div                   1        1        0           0          0 0
>     mipi_dphy_root_clk                1        1        0           0          0 0
> 
> cat clk_dump | grep mipi_dphy
> mipi_dphy_post_div                    1        1        0           0          0 0
>     mipi_dphy_root_clk                1        1        0           0          0 0
> 
> after:
> cat clk_dump | grep mipi_dphy
>    mipi_dphy_src                     1        1        0    24000000          0 0
>        mipi_dphy_cg                  1        1        0    24000000          0 0
>           mipi_dphy_pre_div          1        1        0    24000000          0 0
>              mipi_dphy_post_div      1        1        0    24000000          0 0
>                 mipi_dphy_root_clk   1        1        0    24000000          0 0
> 
> Fixes: 8f6d8094b215 ("ARM: imx: add imx7d clk tree support")
> 
> Cc: linux-clk@vger.kernel.org
> Acked-by: Dong Aisheng <Aisheng.dong@nxp.com>
> Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
> ---

I only get two patches out of the 12 and I don't get a cover letter.
Did you want me to pick up these clk patches into clk-next? Where are
the other patches? Can you cc lkml on all your kernel emails so I can
easily find them?

^ permalink raw reply

* Re: [PATCH v6 6/9] dt-bindings: counter: Document stm32 quadrature encoder
From: William Breathitt Gray @ 2018-05-17 18:07 UTC (permalink / raw)
  To: Rob Herring
  Cc: Jonathan Cameron, Benjamin Gaignard, Fabrice Gasnier, linux-iio,
	linux-kernel@vger.kernel.org, devicetree,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Mark Rutland
In-Reply-To: <CAL_Jsq+a4s=5N6wUWifoHWQoornbDBY-UY2xrwj1kggNH4Q5pQ@mail.gmail.com>

On Thu, May 17, 2018 at 11:23:22AM -0500, Rob Herring wrote:
>On Wed, May 16, 2018 at 12:51 PM, William Breathitt Gray
><vilhelm.gray@gmail.com> wrote:
>> From: Benjamin Gaignard <benjamin.gaignard@st.com>
>
>v6? Where's v1-v5?

Hi Rob,

I apologize, I should have CC you on the rest of the patchset to give
you a better idea of the context of this particular patch. Benjamin
Gaignard authored this particular patch, so I'll leave it up to him to
respond to your inline comments, but I can at least provide a brief
history of the revisions of this patchset as a whole.

This patchset introduces a "Generic Counter" interface for drivers to
support various counter devices (tally counters, rotary encoders, etc.).
The v1 revision was submitted on 31 July 2017
(https://lkml.org/lkml/2017/7/31/514) as a wrapper over existing
IIO functionality. This implementation design was unsuitable for the
needs of Generic Counter API, so the v4 revision submitted on 14
December 2017 reimplemented the Generic Counter API as its own Counter
subsystem (https://lkml.org/lkml/2017/12/14/778).

The v5 revision was submitted on 9 March 2018
(https://lkml.org/lkml/2018/3/9/728) and introduced the STM32 Timer
quadrature encoder driver with Generic Counter interface support. I
should have CC you in that revision to comment on the dt-bindings patch,
but I overlooked it, so I made sure to CC you on this v6 revision.

William Breathitt Gray

>
>> Add bindings for STM32 Timer quadrature encoder.
>> It is a sub-node of STM32 Timer which implement the
>> counter part of the hardware.
>>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
>> ---
>>  .../bindings/counter/stm32-timer-cnt.txt      | 26 +++++++++++++++++++
>>  .../devicetree/bindings/mfd/stm32-timers.txt  |  7 +++++
>>  2 files changed, 33 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>>
>> diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> new file mode 100644
>> index 000000000000..377728128bef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> @@ -0,0 +1,26 @@
>> +STMicroelectronics STM32 Timer quadrature encoder
>> +
>> +STM32 Timer provides quadrature encoder counter mode to detect
>
>'mode' does not sound like a sub-block of the timers block.
>
>> +angular position and direction of rotary elements,
>> +from IN1 and IN2 input signals.
>> +
>> +Must be a sub-node of an STM32 Timer device tree node.
>> +See ../mfd/stm32-timers.txt for details about the parent node.
>> +
>> +Required properties:
>> +- compatible:          Must be "st,stm32-timer-counter".
>> +- pinctrl-names:       Set to "default".
>> +- pinctrl-0:           List of phandles pointing to pin configuration nodes,
>> +                       to set IN1/IN2 pins in mode of operation for Low-Power
>> +                       Timer input on external pin.
>> +
>> +Example:
>> +       timers@40010000  {
>> +               compatible = "st,stm32-timers";
>> +               ...
>> +               counter {
>> +                       compatible = "st,stm32-timer-counter";
>
>Is there only 1? How is the counter addressed?
>
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&tim1_in_pins>;
>> +               };
>> +       };

^ permalink raw reply

* Re: [PATCH 0/3] Add R8A77980 GEther support
From: David Miller @ 2018-05-17 18:53 UTC (permalink / raw)
  To: sergei.shtylyov
  Cc: netdev, devicetree, robh+dt, mark.rutland, linux-renesas-soc
In-Reply-To: <087c91a3-a451-6de7-5e0f-a835f8cc98f1@cogentembedded.com>

From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Wed, 16 May 2018 22:52:40 +0300

> Here's a set of 3 patches against DaveM's 'net-next.git' repo. They (gradually)
> add R8A77980 GEther support to the 'sh_eth' driver, starting with couple new
> register bits/values introduced with this chip, and ending with adding a new
> 'struct sh_eth_cpu_data' instance connected to the new DT "compatible" prop
> value...
> 
> [1/1] sh_eth: add RGMII support
> [2/3] sh_eth: add EDMR.NBST support
> [3/3] sh_eth: add R8A77980 support

Waiting for a respin of this, correcting the RGMII check in patch #1.

^ permalink raw reply

* Re: [PATCH v6 6/9] dt-bindings: counter: Document stm32 quadrature encoder
From: Benjamin Gaignard @ 2018-05-17 18:59 UTC (permalink / raw)
  To: Rob Herring
  Cc: William Breathitt Gray, Mark Rutland, devicetree,
	Benjamin Gaignard, linux-iio, linux-kernel@vger.kernel.org,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Fabrice Gasnier, Jonathan Cameron
In-Reply-To: <CAL_Jsq+a4s=5N6wUWifoHWQoornbDBY-UY2xrwj1kggNH4Q5pQ@mail.gmail.com>

2018-05-17 18:23 GMT+02:00 Rob Herring <robh+dt@kernel.org>:
> On Wed, May 16, 2018 at 12:51 PM, William Breathitt Gray
> <vilhelm.gray@gmail.com> wrote:
>> From: Benjamin Gaignard <benjamin.gaignard@st.com>
>
> v6? Where's v1-v5?
>
>> Add bindings for STM32 Timer quadrature encoder.
>> It is a sub-node of STM32 Timer which implement the
>> counter part of the hardware.
>>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
>> ---
>>  .../bindings/counter/stm32-timer-cnt.txt      | 26 +++++++++++++++++++
>>  .../devicetree/bindings/mfd/stm32-timers.txt  |  7 +++++
>>  2 files changed, 33 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>>
>> diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> new file mode 100644
>> index 000000000000..377728128bef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>> @@ -0,0 +1,26 @@
>> +STMicroelectronics STM32 Timer quadrature encoder
>> +
>> +STM32 Timer provides quadrature encoder counter mode to detect
>
> 'mode' does not sound like a sub-block of the timers block.

quadrature encoding is one of the counting modes of this hardware
block which is enable to count on other signals/triggers

>
>> +angular position and direction of rotary elements,
>> +from IN1 and IN2 input signals.
>> +
>> +Must be a sub-node of an STM32 Timer device tree node.
>> +See ../mfd/stm32-timers.txt for details about the parent node.
>> +
>> +Required properties:
>> +- compatible:          Must be "st,stm32-timer-counter".
>> +- pinctrl-names:       Set to "default".
>> +- pinctrl-0:           List of phandles pointing to pin configuration nodes,
>> +                       to set IN1/IN2 pins in mode of operation for Low-Power
>> +                       Timer input on external pin.
>> +
>> +Example:
>> +       timers@40010000  {
>> +               compatible = "st,stm32-timers";
>> +               ...
>> +               counter {
>> +                       compatible = "st,stm32-timer-counter";
>
> Is there only 1? How is the counter addressed?

Yes there is only one counter per hardware block.
Counter is addressed like the two others sub-nodes and the details
about parent mode are describe in stm32-timers.txt
Should I add them here too ? so example will be like that:
timers@40010000  {
  #address-cells = <1>;
  #size-cells = <0>;
  compatible = "st,stm32-timers";
  reg = <0x40010000 0x400>;
  clocks = <&rcc 0 160>;
  clock-names = "int";
  counter {
    compatible = "st,stm32-timer-counter";
    pinctrl-names = "default";
    pinctrl-0 = <&tim1_in_pins>;
    };
 };

Benjamin
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [v0 1/2] dt-bindings: clock: Introduce QCOM CPUFREQ FW bindings
From: Saravana Kannan @ 2018-05-17 19:17 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Taniya Das, robh, Rafael J. Wysocki, linux-kernel, linux-pm,
	Stephen Boyd, Rajendra Nayak, Amit Nischal, devicetree,
	amit.kucheria
In-Reply-To: <20180517101438.du7xihojuhjxq77l@vireshk-i7>

On 05/17/2018 03:14 AM, Viresh Kumar wrote:
> + Rob.
>
> On 17-05-18, 15:00, Taniya Das wrote:
>> Add QCOM cpufreq firmware device bindings for Qualcomm Technology Inc's
>> SoCs. This is required for managing the cpu frequency transitions which are
>> controlled by firmware.
>>
>> Signed-off-by: Taniya Das <tdas@codeaurora.org>
>> ---
>>   .../bindings/cpufreq/cpufreq-qcom-fw.txt           | 68 ++++++++++++++++++++++
>>   1 file changed, 68 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt

Isn't the prefix wrong? Shouldn't it be dt-bindings: cpufreq:?

-Saravana


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH] ARM: dts: imx51-zii-rdu1: add rave-sp subdevices
From: Nikita Yushchenko @ 2018-05-17 19:19 UTC (permalink / raw)
  To: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Rob Herring, Mark Rutland, Lucas Stach, Chris Healy,
	Andrey Smirnov, Marco Franchi
  Cc: linux-arm-kernel, devicetree, linux-kernel, Nikita Yushchenko

This adds rave-sp powerbutton and backlight devices to RDU1 device tree.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..98cc107098e0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -581,6 +581,14 @@
 		watchdog {
 			compatible = "zii,rave-sp-watchdog";
 		};
+
+		backlight {
+			compatible = "zii,rave-sp-backlight";
+		};
+
+		pwrbutton {
+			compatible = "zii,rave-sp-pwrbutton";
+		};
 	};
 };
 
-- 
2.11.0

^ permalink raw reply related

* Re: [v0 2/2] cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
From: Saravana Kannan @ 2018-05-17 19:25 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Taniya Das, Rafael J. Wysocki, linux-kernel, linux-pm,
	Stephen Boyd, Rajendra Nayak, Amit Nischal, devicetree,
	amit.kucheria
In-Reply-To: <20180517101405.23oxyqpmpjhauflx@vireshk-i7>

On 05/17/2018 03:14 AM, Viresh Kumar wrote:
> On 17-05-18, 15:00, Taniya Das wrote:
>> The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
>> for hanging the frequency of CPUs. The driver implements the cpufreq driver
>> interface for this firmware.
>>
>> Signed-off-by: Taniya Das <tdas@codeaurora.org>
>> ---
>>
>>   ##################################################################################
>> diff --git a/drivers/cpufreq/qcom-cpufreq-fw.c b/drivers/cpufreq/qcom-cpufreq-fw.c

>> +
>> +static int qcom_read_lut(struct platform_device *pdev,
>> +			struct cpufreq_qcom *c)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	u32 data, src, lval, i, core_count, prev_cc = 0;
>> +
>> +	c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
>> +				sizeof(*c->table), GFP_KERNEL);
>> +	if (!c->table)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
>> +		data = readl_relaxed(c->lut_base + i * LUT_ROW_SIZE);
>> +		src = ((data & GENMASK(31, 30)) >> 30);
>> +		lval = (data & GENMASK(7, 0));
>> +		core_count = CORE_COUNT_VAL(data);
>
> Why do you need this here ? And why do below in case this doesn't
> match max-cores count ?

This is how we detect boost frequencies.

>> +
>> +		if (!src)
>> +			c->table[i].frequency = INIT_RATE / 1000;
>> +		else
>> +			c->table[i].frequency = XO_RATE * lval / 1000;
>> +
>> +		c->table[i].driver_data = c->table[i].frequency;
>> +
>> +		dev_dbg(dev, "index=%d freq=%d, core_count %d\n",
>> +				i, c->table[i].frequency, core_count);
>> +
>> +		if (core_count != c->max_cores)
>> +			c->table[i].frequency = CPUFREQ_ENTRY_INVALID;

The FW might has some frequencies marked as "boost frequencies" when 
there are higher non-boost frequencies. So, we mark them as invalid.

>> +
>> +		/*
>> +		 * Two of the same frequencies with the same core counts means
>> +		 * end of table.
>> +		 */
>> +		if (i > 0 && c->table[i - 1].driver_data ==
>> +					c->table[i].driver_data
>> +					&& prev_cc == core_count) {
>> +			struct cpufreq_frequency_table *prev = &c->table[i - 1];
>> +
>> +			if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
>> +				prev->flags = CPUFREQ_BOOST_FREQ;
>> +				prev->frequency = prev->driver_data;
>> +			}
>> +
>> +			break;
>> +		}
>> +		prev_cc = core_count;
>> +	}
>> +	c->table[i].frequency = CPUFREQ_TABLE_END;
>> +
>> +	return 0;
>> +}
>> +
>> +static int qcom_get_related_cpus(struct device_node *np, struct cpumask *m)
>> +{
>> +	struct device_node *dev_phandle;
>> +	struct device *cpu_dev;
>> +	int cpu, i = 0, ret = -ENOENT;
>> +
>> +	dev_phandle = of_parse_phandle(np, "qcom,cpulist", i++);
>
> TBH, I am not a great fan of the CPU phandle list you have created
> here. Lets see what Rob has to say on this.
>

Neither do we, but this is the only real way of mapping the logical CPU 
numbers to the real CPUs in HW that belong to the same freq domain. 
Because boot CPU is always going to be CPU0 if I'm not mistaken.

>> +	while (dev_phandle) {
>> +		for_each_possible_cpu(cpu) {
>> +			cpu_dev = get_cpu_device(cpu);
>> +			if (cpu_dev && cpu_dev->of_node == dev_phandle) {
>> +				cpumask_set_cpu(cpu, m);
>> +				ret = 0;
>
> Maybe just remove this line ...
>
>> +				break;
>> +			}
>> +		}
>> +		dev_phandle = of_parse_phandle(np, "qcom,cpulist", i++);
>> +	}
>> +
>> +	return ret;


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH v5] Input: add bu21029 touch driver
From: Mark Jonas @ 2018-05-17 20:06 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Mark Rutland
  Cc: linux-input, devicetree, linux-kernel, hs, andy.shevchenko,
	Zhu Yi, Mark Jonas
In-Reply-To: <1521651874-15379-1-git-send-email-mark.jonas@de.bosch.com>

From: Zhu Yi <yi.zhu5@cn.bosch.com>

Add Rohm BU21029 resistive touch panel controller support with I2C
interface.

Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes in v5:
 - use usleep_range() and msleep() instead of atomic delays
 - drop #ifdef CONFIG_PM_SLEEP
 - annotate HW ID as big endian (sparse check finding)
---
Changes in v4:
 - remove potential kernel log spamming from irq handler
 - fix bug in endianess conversion of the chip's HW ID
 - simplify device tree reading
 - flag resume and suspend functions as potentially unused
---
Changes in v3:
 - reviewed by Rob Herring
---
Changes in v2:
 - make ABS_PRESSURE proportionally rising with finger pressure
 - fix race between interrupt and timer during shutdown
 - use infrastructure from include/linux/input/touchscreen.h
 - add SPDX tag for the driver
 - improve binding documentation
 - fix multi-line comments
---
 .../bindings/input/touchscreen/bu21029.txt         |  34 ++
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/bu21029_ts.c             | 474 +++++++++++++++++++++
 4 files changed, 521 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/bu21029.txt
 create mode 100644 drivers/input/touchscreen/bu21029_ts.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/bu21029.txt b/Documentation/devicetree/bindings/input/touchscreen/bu21029.txt
new file mode 100644
index 0000000..030a888
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/bu21029.txt
@@ -0,0 +1,34 @@
+* Rohm BU21029 Touch Screen Controller
+
+Required properties:
+ - compatible              : must be "rohm,bu21029"
+ - reg                     : i2c device address of the chip (0x40 or 0x41)
+ - interrupt-parent        : the phandle for the gpio controller
+ - interrupts              : (gpio) interrupt to which the chip is connected
+ - reset-gpios             : gpio pin to reset the chip (active low)
+ - rohm,x-plate-ohms       : x-plate resistance in Ohm
+
+Optional properties:
+ - touchscreen-size-x      : horizontal resolution of touchscreen (in pixels)
+ - touchscreen-size-y      : vertical resolution of touchscreen (in pixels)
+ - touchscreen-max-pressure: maximum pressure value
+
+Example:
+
+	&i2c1 {
+		/* ... */
+
+		bu21029: bu21029@40 {
+			compatible = "rohm,bu21029";
+			reg = <0x40>;
+			interrupt-parent = <&gpio1>;
+			interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+			reset-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;
+			rohm,x-plate-ohms = <600>;
+			touchscreen-size-x = <800>;
+			touchscreen-size-y = <480>;
+			touchscreen-max-pressure = <4095>;
+		};
+
+		/* ... */
+	};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4f15496..e09fe8f 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -151,6 +151,18 @@ config TOUCHSCREEN_BU21013
 	  To compile this driver as a module, choose M here: the
 	  module will be called bu21013_ts.
 
+config TOUCHSCREEN_BU21029
+	tristate "Rohm BU21029 based touch panel controllers"
+	depends on I2C
+	help
+	  Say Y here if you have a Rohm BU21029 touchscreen controller
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bu21029_ts.
+
 config TOUCHSCREEN_CHIPONE_ICN8318
 	tristate "chipone icn8318 touchscreen controller"
 	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index dddae79..f50624c 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C)	+= ar1021_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)	+= atmel_mxt_ts.o
 obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)	+= auo-pixcir-ts.o
 obj-$(CONFIG_TOUCHSCREEN_BU21013)	+= bu21013_ts.o
+obj-$(CONFIG_TOUCHSCREEN_BU21029)	+= bu21029_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318)	+= chipone_icn8318.o
 obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)	+= cy8ctmg110_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE)	+= cyttsp_core.o
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
new file mode 100644
index 0000000..5a72671
--- /dev/null
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rohm BU21029 touchscreen controller driver
+ *
+ * Copyright (C) 2015-2018 Bosch Sicherheitssysteme GmbH
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+
+/*
+ * HW_ID1 Register (PAGE=0, ADDR=0x0E, Reset value=0x02, Read only)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |                                 HW_IDH                                |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * HW_ID2 Register (PAGE=0, ADDR=0x0F, Reset value=0x29, Read only)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |                                 HW_IDL                                |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * HW_IDH: high 8bits of IC's ID
+ * HW_IDL: low  8bits of IC's ID
+ */
+#define BU21029_HWID_REG (0x0E << 3)
+#define SUPPORTED_HWID    0x0229
+
+/*
+ * CFR0 Register (PAGE=0, ADDR=0x00, Reset value=0x20)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   0    |   0    |  CALIB |  INTRM |   0    |   0    |   0    |   0    |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * CALIB: 0 = not to use calibration result (*)
+ *        1 = use calibration result
+ * INTRM: 0 = INT output depend on "pen down" (*)
+ *        1 = INT output always "0"
+ */
+#define BU21029_CFR0_REG (0x00 << 3)
+#define CFR0_VALUE        0x00
+
+/*
+ * CFR1 Register (PAGE=0, ADDR=0x01, Reset value=0xA6)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |  MAV   |         AVE[2:0]         |   0    |         SMPL[2:0]        |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * MAV:  0 = median average filter off
+ *       1 = median average filter on (*)
+ * AVE:  AVE+1 = number of average samples for MAV,
+ *               if AVE>SMPL, then AVE=SMPL (=3)
+ * SMPL: SMPL+1 = number of conversion samples for MAV (=7)
+ */
+#define BU21029_CFR1_REG (0x01 << 3)
+#define CFR1_VALUE        0xA6
+
+/*
+ * CFR2 Register (PAGE=0, ADDR=0x02, Reset value=0x04)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |          INTVL_TIME[3:0]          |          TIME_ST_ADC[3:0]         |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * INTVL_TIME: waiting time between completion of conversion
+ *             and start of next conversion, only usable in
+ *             autoscan mode (=20.480ms)
+ * TIME_ST_ADC: waiting time between application of voltage
+ *              to panel and start of A/D conversion (=100us)
+ */
+#define BU21029_CFR2_REG (0x02 << 3)
+#define CFR2_VALUE        0xC9
+
+/*
+ * CFR3 Register (PAGE=0, ADDR=0x0B, Reset value=0x72)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |  RM8   | STRETCH|  PU90K |  DUAL  |           PIDAC_OFS[3:0]          |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * RM8: 0 = coordinate resolution is 12bit (*)
+ *      1 = coordinate resolution is 8bit
+ * STRETCH: 0 = SCL_STRETCH function off
+ *          1 = SCL_STRETCH function on (*)
+ * PU90K: 0 = internal pull-up resistance for touch detection is ~50kohms (*)
+ *        1 = internal pull-up resistance for touch detection is ~90kohms
+ * DUAL: 0 = dual touch detection off (*)
+ *       1 = dual touch detection on
+ * PIDAC_OFS: dual touch detection circuit adjustment, it is not necessary
+ *            to change this from initial value
+ */
+#define BU21029_CFR3_REG (0x0B << 3)
+#define CFR3_VALUE        0x42
+
+/*
+ * LDO Register (PAGE=0, ADDR=0x0C, Reset value=0x00)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   0    |         PVDD[2:0]        |   0    |         AVDD[2:0]        |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * PVDD: output voltage of panel output regulator (=2.000V)
+ * AVDD: output voltage of analog circuit regulator (=2.000V)
+ */
+#define BU21029_LDO_REG  (0x0C << 3)
+#define LDO_VALUE         0x77
+
+/*
+ * Serial Interface Command Byte 1 (CID=1)
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   D7   |   D6   |   D5   |   D4   |   D3   |   D2   |   D1   |   D0   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * |   1    |                 CF                |  CMSK  |  PDM   |  STP   |
+ * +--------+--------+--------+--------+--------+--------+--------+--------+
+ * CF: conversion function, see table 3 in datasheet p6 (=0000, automatic scan)
+ * CMSK: 0 = executes convert function (*)
+ *       1 = reads the convert result
+ * PDM: 0 = power down after convert function stops (*)
+ *      1 = keep power on after convert function stops
+ * STP: 1 = abort current conversion and power down, set to "0" automatically
+ */
+#define BU21029_AUTOSCAN  0x80
+
+/*
+ * The timeout value needs to be larger than INTVL_TIME + tConv4 (sample and
+ * conversion time), where tConv4 is calculated by formula:
+ * tPON + tDLY1 + (tTIME_ST_ADC + (tADC * tSMPL) * 2 + tDLY2) * 3
+ * see figure 8 in datasheet p15 for details of each field.
+ */
+#define PEN_UP_TIMEOUT msecs_to_jiffies(50)
+
+#define STOP_DELAY_MIN_US 50
+#define STOP_DELAY_MAX_US 1000
+#define START_DELAY_MS    2
+#define BUF_LEN           8
+#define SCALE_12BIT       (1 << 12)
+#define MAX_12BIT         ((1 << 12) - 1)
+#define DRIVER_NAME       "bu21029"
+
+struct bu21029_ts_data {
+	struct i2c_client            *client;
+	struct input_dev             *in_dev;
+	struct timer_list             timer;
+	struct gpio_desc             *reset_gpios;
+	u32                           x_plate_ohms;
+	struct touchscreen_properties prop;
+};
+
+static int bu21029_touch_report(struct bu21029_ts_data *bu21029)
+{
+	struct i2c_client *i2c = bu21029->client;
+	u8 buf[BUF_LEN];
+	u16 x, y, z1, z2;
+	u32 rz;
+	s32 max_pressure = bu21029->in_dev->absinfo[ABS_PRESSURE].maximum;
+
+	/* read touch data and deassert INT (by restarting the autoscan mode) */
+	int error = i2c_smbus_read_i2c_block_data(i2c,
+						  BU21029_AUTOSCAN,
+						  BUF_LEN,
+						  buf);
+	if (error < 0)
+		return error;
+
+	/*
+	 * compose upper 8 and lower 4 bits into a 12bit value:
+	 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+	 * |            ByteH              |            ByteL              |
+	 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+	 * |b07|b06|b05|b04|b03|b02|b01|b00|b07|b06|b05|b04|b03|b02|b01|b00|
+	 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+	 * |v11|v10|v09|v08|v07|v06|v05|v04|v03|v02|v01|v00| 0 | 0 | 0 | 0 |
+	 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+	 */
+	x  = (buf[0] << 4) | (buf[1] >> 4);
+	y  = (buf[2] << 4) | (buf[3] >> 4);
+	z1 = (buf[4] << 4) | (buf[5] >> 4);
+	z2 = (buf[6] << 4) | (buf[7] >> 4);
+
+	if (z1 == 0 || z2 == 0)
+		return 0;
+
+	/*
+	 * calculate Rz (pressure resistance value) by equation:
+	 * Rz = Rx * (x/Q) * ((z2/z1) - 1), where
+	 * Rx is x-plate resistance,
+	 * Q  is the touch screen resolution (8bit = 256, 12bit = 4096)
+	 * x, z1, z2 are the measured positions.
+	 */
+	rz  = z2 - z1;
+	rz *= x;
+	rz *= bu21029->x_plate_ohms;
+	rz /= z1;
+	rz  = DIV_ROUND_CLOSEST(rz, SCALE_12BIT);
+	if (rz <= max_pressure) {
+		touchscreen_report_pos(bu21029->in_dev, &bu21029->prop,
+				       x, y, false);
+		input_report_abs(bu21029->in_dev, ABS_PRESSURE,
+				 max_pressure - rz);
+		input_report_key(bu21029->in_dev, BTN_TOUCH, 1);
+		input_sync(bu21029->in_dev);
+	}
+
+	return 0;
+}
+
+static void bu21029_touch_release(struct timer_list *t)
+{
+	struct bu21029_ts_data *bu21029 = from_timer(bu21029, t, timer);
+
+	input_report_abs(bu21029->in_dev, ABS_PRESSURE, 0);
+	input_report_key(bu21029->in_dev, BTN_TOUCH, 0);
+	input_sync(bu21029->in_dev);
+}
+
+static irqreturn_t bu21029_touch_soft_irq(int irq, void *data)
+{
+	struct bu21029_ts_data *bu21029 = data;
+
+	/*
+	 * report touch and deassert interrupt (will assert again after
+	 * INTVL_TIME + tConv4 for continuous touch)
+	 */
+	int error = bu21029_touch_report(bu21029);
+
+	if (error)
+		return IRQ_NONE;
+
+	/* reset timer for pen up detection */
+	mod_timer(&bu21029->timer, jiffies + PEN_UP_TIMEOUT);
+
+	return IRQ_HANDLED;
+}
+
+static void bu21029_stop_chip(struct input_dev *dev)
+{
+	struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
+
+	disable_irq(bu21029->client->irq);
+	del_timer_sync(&bu21029->timer);
+
+	/* put chip into reset */
+	gpiod_set_value_cansleep(bu21029->reset_gpios, 1);
+	usleep_range(STOP_DELAY_MIN_US, STOP_DELAY_MAX_US);
+}
+
+static int bu21029_start_chip(struct input_dev *dev)
+{
+	struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
+	struct i2c_client *i2c = bu21029->client;
+	struct {
+		u8 reg;
+		u8 value;
+	} init_table[] = {
+		{BU21029_CFR0_REG, CFR0_VALUE},
+		{BU21029_CFR1_REG, CFR1_VALUE},
+		{BU21029_CFR2_REG, CFR2_VALUE},
+		{BU21029_CFR3_REG, CFR3_VALUE},
+		{BU21029_LDO_REG,  LDO_VALUE}
+	};
+	int error, i;
+	__be16 hwid;
+
+	/* take chip out of reset */
+	gpiod_set_value_cansleep(bu21029->reset_gpios, 0);
+	msleep(START_DELAY_MS);
+
+	error = i2c_smbus_read_i2c_block_data(i2c,
+					      BU21029_HWID_REG,
+					      2,
+					      (u8 *)&hwid);
+	if (error < 0) {
+		dev_err(&i2c->dev, "failed to read HW ID\n");
+		goto out;
+	}
+
+	if (be16_to_cpu(hwid) != SUPPORTED_HWID) {
+		dev_err(&i2c->dev, "unsupported HW ID 0x%x\n", hwid);
+		error = -ENODEV;
+		goto out;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(init_table); ++i) {
+		error = i2c_smbus_write_byte_data(i2c,
+						  init_table[i].reg,
+						  init_table[i].value);
+		if (error < 0) {
+			dev_err(&i2c->dev,
+				"failed to write 0x%x to register 0x%x\n",
+				init_table[i].value,
+				init_table[i].reg);
+			goto out;
+		}
+	}
+
+	error = i2c_smbus_write_byte(i2c, BU21029_AUTOSCAN);
+	if (error < 0) {
+		dev_err(&i2c->dev, "failed to start autoscan\n");
+		goto out;
+	}
+
+	enable_irq(bu21029->client->irq);
+	return 0;
+
+out:
+	bu21029_stop_chip(dev);
+	return error;
+}
+
+static int bu21029_parse_dt(struct bu21029_ts_data *bu21029)
+{
+	struct device *dev = &bu21029->client->dev;
+	int error;
+
+	bu21029->reset_gpios = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(bu21029->reset_gpios)) {
+		error = PTR_ERR(bu21029->reset_gpios);
+		if (error != -EPROBE_DEFER)
+			dev_err(dev, "invalid 'reset-gpios':%d\n", error);
+		return error;
+	}
+
+	error = device_property_read_u32(dev, "rohm,x-plate-ohms",
+					 &bu21029->x_plate_ohms);
+	if (error) {
+		dev_err(dev, "invalid 'x-plate-ohms' supplied:%d\n", error);
+		return error;
+	}
+
+	touchscreen_parse_properties(bu21029->in_dev, false, &bu21029->prop);
+
+	return 0;
+}
+
+static int bu21029_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct bu21029_ts_data *bu21029;
+	struct input_dev *in_dev;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_WRITE_BYTE |
+				     I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+				     I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+		dev_err(&client->dev,
+			"i2c functionality support is not sufficient\n");
+		return -EIO;
+	}
+
+	bu21029 = devm_kzalloc(&client->dev, sizeof(*bu21029), GFP_KERNEL);
+	if (!bu21029)
+		return -ENOMEM;
+
+	in_dev = devm_input_allocate_device(&client->dev);
+	if (!in_dev) {
+		dev_err(&client->dev, "unable to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	bu21029->client = client;
+	bu21029->in_dev	= in_dev;
+	timer_setup(&bu21029->timer, bu21029_touch_release, 0);
+
+	in_dev->name       = DRIVER_NAME;
+	in_dev->id.bustype = BUS_I2C;
+	in_dev->open       = bu21029_start_chip;
+	in_dev->close      = bu21029_stop_chip;
+
+	input_set_capability(in_dev, EV_KEY, BTN_TOUCH);
+	input_set_abs_params(in_dev, ABS_X, 0, MAX_12BIT, 0, 0);
+	input_set_abs_params(in_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
+	input_set_abs_params(in_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
+
+	error = bu21029_parse_dt(bu21029);
+	if (error)
+		return error;
+
+	input_set_drvdata(in_dev, bu21029);
+
+	error = devm_request_threaded_irq(&client->dev,
+					  client->irq,
+					  NULL,
+					  bu21029_touch_soft_irq,
+					  IRQF_ONESHOT,
+					  DRIVER_NAME,
+					  bu21029);
+	if (error) {
+		dev_err(&client->dev, "unable to request touch irq\n");
+		return error;
+	}
+
+	bu21029_stop_chip(in_dev);
+
+	error = input_register_device(in_dev);
+	if (error) {
+		dev_err(&client->dev, "unable to register input device\n");
+		return error;
+	}
+
+	i2c_set_clientdata(client, bu21029);
+
+	return 0;
+}
+
+static int bu21029_remove(struct i2c_client *client)
+{
+	struct bu21029_ts_data *bu21029 = i2c_get_clientdata(client);
+
+	bu21029_stop_chip(bu21029->in_dev);
+
+	return 0;
+}
+
+static int __maybe_unused bu21029_suspend(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
+
+	mutex_lock(&bu21029->in_dev->mutex);
+	if (bu21029->in_dev->users)
+		bu21029_stop_chip(bu21029->in_dev);
+	mutex_unlock(&bu21029->in_dev->mutex);
+
+	return 0;
+}
+
+static int __maybe_unused bu21029_resume(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
+
+	mutex_lock(&bu21029->in_dev->mutex);
+	if (bu21029->in_dev->users)
+		bu21029_start_chip(bu21029->in_dev);
+	mutex_unlock(&bu21029->in_dev->mutex);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(bu21029_pm_ops, bu21029_suspend, bu21029_resume);
+
+static const struct i2c_device_id bu21029_ids[] = {
+	{DRIVER_NAME, 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, bu21029_ids);
+
+static struct i2c_driver bu21029_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.pm   = &bu21029_pm_ops,
+	},
+	.id_table = bu21029_ids,
+	.probe    = bu21029_probe,
+	.remove   = bu21029_remove,
+};
+module_i2c_driver(bu21029_driver);
+
+MODULE_AUTHOR("Zhu Yi <yi.zhu5@cn.bosch.com>");
+MODULE_DESCRIPTION("Rohm BU21029 touchscreen controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related

* AW: [PATCH v3] Input: add bu21029 touch driver
From: Jonas Mark (BT-FIR/ENG1) @ 2018-05-17 20:10 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Andy Shevchenko, Rob Herring, Mark Rutland, linux-input,
	devicetree, Linux Kernel Mailing List, Heiko Schocher,
	ZHU Yi (BT-FIR/ENG1-Zhu), Jonas Mark (BT-FIR/ENG1)
In-Reply-To: <20180516174357.GE21971@dtor-ws>

Hello Dmitry,

> > > > +static void bu21029_stop_chip(struct input_dev *dev)
> > > > +{
> > > > +       struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
> > > > +
> > > > +       disable_irq(bu21029->client->irq);
> > > > +       del_timer_sync(&bu21029->timer);
> > > > +
> > > > +       /* put chip into reset */
> > > > +       gpiod_set_value_cansleep(bu21029->reset_gpios, 1);
> > >
> > > > +       udelay(STOP_DELAY_US);
> > >
> > > udelay() ?!
> > >
> > > > +}
> >
> > According to the datasheet disabling the chip will take 30 microseconds.
> > In the defines we added a buffer of 20 microseconds and thus
> > STOP_DELAY_US is 50. The function guarantees that the chip is stopped
> > before it returns.
> >
> > We think that it is ok to use udelay() here because in normal operation
> > the chip is not stopped. It is only stopped when loading or unloading
> > the driver, or when the system suspends.
> >
> > We would like to keep it like it is.
> 
> The issue is not with having delay here, but the kind of delay you are
> using: udelay makes CPU spin for given amount of time; you really want
> msleep() or usleep_range() here.

Understood and changed.

> > > > +static int bu21029_start_chip(struct input_dev *dev)
> > > > +{
> > >
> > > > +       u16 hwid;
> > > > +
> > > > +       /* take chip out of reset */
> > > > +       gpiod_set_value_cansleep(bu21029->reset_gpios, 0);
> > >
> > > > +       mdelay(START_DELAY_MS);
> > >
> > > mdelay()?!
> 
> Same here - replace with msleep().

Replaced.

> > > Instead...
> > >
> > > > +static int bu21029_suspend(struct device *dev)
> > >
> > > ...use __maby_unused annotation.
> > >
> > > > +static int bu21029_resume(struct device *dev)
> > >
> > > Ditto.
> >
> > OK, added.
> 
> You also need to drop #ifdef CONFIG_SLEEP. That's the point: we want to
> reduce amount of conditionally compiled code and use __maybe_unused to
> shut off compiler warning about some functions not used in certain
> configurations. We rely on linker to eliminate dead functions from
> executable.

Done.

Greetings,
Mark

 Mark Jonas

Building Technologies, Panel Software Fire (BT-FIR/ENG1) 
Bosch Sicherheitssysteme GmbH | Postfach 11 11 | 85626 Grasbrunn | GERMANY | www.boschsecurity.com

Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart HRB 23118 
Aufsichtsratsvorsitzender: Stefan Hartung; Geschäftsführung: Gert van Iperen, Andreas Bartz, Thomas Quante, Bernhard Schuster

^ permalink raw reply

* [PATCH] arm64: dts: renesas: r8a77980: add SMP support
From: Sergei Shtylyov @ 2018-05-17 20:19 UTC (permalink / raw)
  To: Simon Horman, linux-renesas-soc, Rob Herring, devicetree,
	Catalin Marinas, Will Deacon
  Cc: Mark Rutland, Magnus Damm, linux-arm-kernel
In-Reply-To: <14666252.G84Ipxe6EL@wasted.cogentembedded.com>

Add the device nodes for 3 more Cortex-A53 CPU cores; adjust the interrupt
delivery masks for the ARM GIC and Architectured Timer.

Based on the original (and large) patch by Vladimir Barinov.

Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
The patch is against the 'renesas-devel-20180516v2-v4.17-rc5' tag of Simon
Horman's 'renesas.git' repo. Tested successfully on the V3M Starter Kit board
(except offlining CPU0 hangs the kernel).

 arch/arm64/boot/dts/renesas/r8a77980.dtsi |   40 ++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 5 deletions(-)

Index: renesas/arch/arm64/boot/dts/renesas/r8a77980.dtsi
===================================================================
--- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+++ renesas/arch/arm64/boot/dts/renesas/r8a77980.dtsi
@@ -30,6 +30,36 @@
 			enable-method = "psci";
 		};
 
+		a53_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53","arm,armv8";
+			reg = <1>;
+			clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+			power-domains = <&sysc R8A77980_PD_CA53_CPU1>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
+		a53_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53","arm,armv8";
+			reg = <2>;
+			clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+			power-domains = <&sysc R8A77980_PD_CA53_CPU2>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
+		a53_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53","arm,armv8";
+			reg = <3>;
+			clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+			power-domains = <&sysc R8A77980_PD_CA53_CPU3>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
 		L2_CA53: cache-controller {
 			compatible = "cache";
 			power-domains = <&sysc R8A77980_PD_CA53_SCU>;
@@ -408,7 +438,7 @@
 			      <0x0 0xf1020000 0 0x20000>,
 			      <0x0 0xf1040000 0 0x20000>,
 			      <0x0 0xf1060000 0 0x20000>;
-			interrupts = <GIC_PPI 9	(GIC_CPU_MASK_SIMPLE(1) |
+			interrupts = <GIC_PPI 9	(GIC_CPU_MASK_SIMPLE(4) |
 				      IRQ_TYPE_LEVEL_HIGH)>;
 			clocks = <&cpg CPG_MOD 408>;
 			clock-names = "clk";
@@ -424,13 +454,13 @@
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
 				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
 				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
 				       IRQ_TYPE_LEVEL_LOW)>,
-				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
 				       IRQ_TYPE_LEVEL_LOW)>;
 	};
 };

^ permalink raw reply

* Re: [PATCH] arm64: dts: renesas: r8a77980: add SMP support
From: Geert Uytterhoeven @ 2018-05-17 20:23 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Magnus Damm, Catalin Marinas, Will Deacon, Rob Herring,
	Linux-Renesas, Simon Horman, Linux ARM
In-Reply-To: <ec4c6905-23d1-8600-a1cc-4297fbd1ddaa@cogentembedded.com>

Hi Sergei,

On Thu, May 17, 2018 at 10:19 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Add the device nodes for 3 more Cortex-A53 CPU cores; adjust the interrupt
> delivery masks for the ARM GIC and Architectured Timer.
>
> Based on the original (and large) patch by Vladimir Barinov.
>
> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Thanks for your patch!

> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980.dtsi
> +++ renesas/arch/arm64/boot/dts/renesas/r8a77980.dtsi
> @@ -30,6 +30,36 @@
>                         enable-method = "psci";
>                 };
>
> +               a53_1: cpu@1 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a53","arm,armv8";

Please stop copying spaceless lists ;-)

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH RFC] ARM: dts: add Raspberry Pi Compute Module and IO board
From: Stefan Wahren @ 2018-05-17 20:44 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Eric Anholt
  Cc: Stefan Wahren, devicetree, Florian Fainelli, Scott Branden,
	Ray Jui, Phil Elwell, bcm-kernel-feedback-list, linux-rpi-kernel,
	linux-arm-kernel

The Raspberry Pi Compute Module (CM1) is a SoM which contains a
BCM2835 processor, 512 MB RAM and a 4 GB eMMC. There is also a carrier
board which is called Compute Module IO Board.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 arch/arm/boot/dts/Makefile                |  1 +
 arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts | 92 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi    | 34 ++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
 create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ec2024e..a9883e8 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
 	bcm2835-rpi-b-rev2.dtb \
 	bcm2835-rpi-b-plus.dtb \
 	bcm2835-rpi-a-plus.dtb \
+	bcm2835-rpi-cm1-io1.dtb \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb \
 	bcm2837-rpi-3-b-plus.dtb \
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
new file mode 100644
index 0000000..4d9aa22
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2835-rpi-cm1.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+	compatible = "raspberrypi,compute-module", "brcm,bcm2835";
+	model = "Raspberry Pi Compute Module IO board rev1";
+};
+
+&dsi1 {
+	status = "okay";
+};
+
+&gpio {
+	/*
+	 * This is based on the official GPU firmware DT blob.
+	 *
+	 * Legend:
+	 * "NC" = not connected (no rail from the SoC)
+	 * "FOO" = GPIO line named "FOO" on the schematic
+	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
+	 */
+	gpio-line-names = "GPIO0",
+			  "GPIO1",
+			  "GPIO2",
+			  "GPIO3",
+			  "GPIO4",
+			  "GPIO5",
+			  "GPIO6",
+			  "GPIO7",
+			  "GPIO8",
+			  "GPIO9",
+			  "GPIO10",
+			  "GPIO11",
+			  "GPIO12",
+			  "GPIO13",
+			  "GPIO14",
+			  "GPIO15",
+			  "GPIO16",
+			  "GPIO17",
+			  "GPIO18",
+			  "GPIO19",
+			  "GPIO20",
+			  "GPIO21",
+			  "GPIO22",
+			  "GPIO23",
+			  "GPIO24",
+			  "GPIO25",
+			  "GPIO26",
+			  "GPIO27",
+			  "GPIO28",
+			  "GPIO29",
+			  "GPIO30",
+			  "GPIO31",
+			  "GPIO32",
+			  "GPIO33",
+			  "GPIO34",
+			  "GPIO35",
+			  "GPIO36",
+			  "GPIO37",
+			  "GPIO38",
+			  "GPIO39",
+			  "GPIO40",
+			  "GPIO41",
+			  "GPIO42",
+			  "GPIO43",
+			  "GPIO44",
+			  "GPIO45",
+			  "HDMI_HPD_N",
+			  /* Also used as ACT LED */
+			  "EMMC_EN_N",
+			  /* Used by eMMC */
+			  "SD_CLK_R",
+			  "SD_CMD_R",
+			  "SD_DATA0_R",
+			  "SD_DATA1_R",
+			  "SD_DATA2_R",
+			  "SD_DATA3_R";
+
+	pinctrl-0 = <&gpioout &alt0>;
+};
+
+&hdmi {
+	hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_gpio14>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
new file mode 100644
index 0000000..ef22c2d
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2835.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+	leds {
+		act {
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	reg_3v3: fixed-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	reg_1v8: fixed-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+};
+
+&sdhost {
+	non-removable;
+	vmmc-supply = <&reg_3v3>;
+	vqmmc-supply = <&reg_1v8>;
+};
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH 1/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-05-17 20:48 UTC (permalink / raw)
  To: Mark Brown
  Cc: Stephen Boyd, lgirdwood, mark.rutland, robh+dt, linux-arm-msm,
	linux-arm-kernel, devicetree, linux-kernel, rnayak, ilina
In-Reply-To: <20180517060948.GI20254@sirena.org.uk>

On 05/16/2018 11:09 PM, Mark Brown wrote:
> On Tue, Apr 24, 2018 at 01:46:21PM -0700, David Collins wrote:
>> The RPMh hardware is aware of the parent-child connections between
>> regulators as well as minimum headroom to ensure stable LDO voltage output
>> for subregulated LDOs.  The intention of having the headroom be a
>> configurable property for processors is to support usecases in which
>> subregulated LDO loads are particularly sensitive to noise and require
>> additional headroom.  Such usecases are board dependent and beyond the
>> baseline configurations set in RPMh hardware.
> 
> So the hardware implementation is some hard coding stuff that doesn't
> really adequately reflect reality?  This seems unfortunate.  However do
> we really need to tell the hardware about the fact that we're adding
> extra headroom - are there actual interactions with non-Linux things
> here?

The RPMh hardware is configured by the boot loader.  The configuration
does reflect reality; however, it cannot handle all configurations at
initialization time.  Specific headroom management typically comes up in
modem usecases for RF supplies that are sensitive to noise.  This feature
allows RPMh masters (application processor, modem processor, etc) to make
requests only for the regulators that they directly care about without
having to worry about power grid parent-child details and setting the
voltage of parent regulators in order to ensure sufficient headroom.

If you really don't like having this feature present in the Linux RPMh
regulator driver, then I'd be ok removing it.  It is not required for
SDM845 which the driver is initially targeting.


>>>> XOB managed regulators physically cannot change voltage.  Therefore, do
>>>> you agree that it is reasonable to use fixed_uV for them?  Note that I
>>>> removed init_data->constraints.apply_uV manipulation in version 2 of this
>>>> patch.
> 
>>> If these regulators can't change voltage then surely we know what
>>> voltage they have without needing it to be specified in DT?
> 
>> In the case of XOB managed LDO regulators, the LDOs physically can be
>> configured to different voltages by the bootloader.  However, the RPMh
>> interface provides no mechanism for the application processor to read or
>> change that voltage.  Therefore, we need a way to specify such voltages in
>> a board specific (as opposed to driver specific) manner (i.e. device tree).
> 
> Is the kernel somehow prevented from varying these voltages?

Yes.  Physically, there exists no RPMh register to read or write the
voltage of LDOs managed via XOB.  Additionally, the kernel running on the
application processor is blocked from configuring the voltage via a direct
SPMI writes by access permissions that crash the system when violated.

Take care,
David

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH 1/3] ARM: dra762: hwmod: Add MCAN support
From: Tony Lindgren @ 2018-05-17 21:04 UTC (permalink / raw)
  To: Faiz Abbas
  Cc: linux-kernel, linux-omap, devicetree, bcousson, robh+dt,
	mark.rutland, paul, lokeshvutla, linux
In-Reply-To: <b3456763-2f82-9a0b-d166-ddf7965fc162@ti.com>

* Faiz Abbas <faiz_abbas@ti.com> [180517 08:14]:
> On Tuesday 15 May 2018 10:53 PM, Tony Lindgren wrote:
> > And I'm guessing the top level module with sysconfig related
> > registers is named "adc" :)
> > 
> 
> Yes. The MCAN clocks are controlled by the ADC_CLKCTRL register.
> Please see TRM:
> http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=spruie9&fileType=pdf
> page: 1530

Thanks that helps :) Looks like we have:

MCANSS_PID      rev             0
MCANSS_CTRL     sysconfig       0x4
MCANSS_STAT     sysstatus       0x8

With current Linux next, this should work with just ti-sysc if
we added yet another sysconfig layout.. See

Documentation/devicetree/bindings/bus/ti-sysc.txt

Looks like this is not quite "ti,sysc-omap4" as there are no
ti,sysc-midle or ti,sysc-sidle, and sysstatus reset bit is
inverted..

Anyways, I think the dts part should be similar to this with
the new sysconfig added (untested):

target-module@42c00000 {
	compatible ="ti,sysc-yet-to-be-determined";
	ti,hwmods = "mcan";
	reg = <0x42c00000 4>,
	      <0x42c00004 4>,
	      <0x42c00008 4>;
	reg-names = "rev", "sysc", "syss";
	clocks = <&wkupaon_clkctrl CM_WKUPAON_ADC_CLKCTRL>;
	clock-names = "fck";
	ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET | SYSC_DRA7_ENAWAKEUP)>;
	ti,syss-mask = <1>;
	#address-cells = <1>;
	#size-cells = <1>;
	ranges = <0 0x42c00000 0x2000>;

	mcan@0 {
		compatible = "bosch,m_can";
		reg = <0x1a00 0x4000>,
		      <0 0x18fc>;
		reg-names = "m_can", "message_ram";
		interrupt-parent = <&gic>;
		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
			     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-names = "int0", "int1";
		clocks = <&mcan_clk>, <&l3_iclk_div>;
		clock-names = "cclk", "hclk";
		bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
	};
};

You'd have to add a new struct sysc_regbits to ti-sysc.c similar
to sysc_regbits_omap4 for the .srst_shift = 0. Not sure if the same
register layout is used for other modules, but might be worth checking
the TRM. Also the clock node is missing for wkupaon_clkctrl from
include/dt-bindings/clock/dra7.h.

If the "message_ram" can operate independent of the driver,
it could be a separate child node under the target-module.

In the hwmod you still need the struct omap_hwmod for now,
but clocks should no longer be needed there.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 1/3] ARM: dra762: hwmod: Add MCAN support
From: Tony Lindgren @ 2018-05-17 21:09 UTC (permalink / raw)
  To: Faiz Abbas
  Cc: linux-kernel, linux-omap, devicetree, bcousson, robh+dt,
	mark.rutland, paul, lokeshvutla, linux
In-Reply-To: <1523181542-3770-2-git-send-email-faiz_abbas@ti.com>

* Faiz Abbas <faiz_abbas@ti.com> [180408 09:59]:
> From: Lokesh Vutla <lokeshvutla@ti.com>
> 
> Add MCAN hwmod data and register it for dra762 silicons.
> 
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 32 +++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> index 62352d1..a2cd7f8 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> @@ -1356,6 +1356,29 @@ static struct omap_hwmod dra7xx_mailbox13_hwmod = {
>  };
>  
>  /*
> + * 'mcan' class
> + *
> + */
> +static struct omap_hwmod_class dra76x_mcan_hwmod_class = {
> +	.name	= "mcan",
> +};
> +
> +/* mcan */
> +static struct omap_hwmod dra76x_mcan_hwmod = {
> +	.name		= "mcan",
> +	.class		= &dra76x_mcan_hwmod_class,
> +	.clkdm_name	= "wkupaon_clkdm",
> +	.main_clk	= "mcan_clk",
> +	.prcm = {
> +		.omap4 = {
> +			.clkctrl_offs = DRA7XX_CM_WKUPAON_ADC_CLKCTRL_OFFSET,
> +			.context_offs = DRA7XX_RM_WKUPAON_ADC_CONTEXT_OFFSET,
> +			.modulemode   = MODULEMODE_SWCTRL,
> +		},
> +	},
> +};

So based on the ti-sysc related dts comments, this patch should
work except you should be able to just leave out the clocks here
with the dts changes.

> +/*
>   * 'mcspi' class
>   *
>   */
> @@ -3818,6 +3841,14 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per2__epwmss2 = {
>  	.user		= OCP_USER_MPU,
>  };
>  
> +/* l3_main_1 -> mcan */
> +static struct omap_hwmod_ocp_if dra76x_l3_main_1__mcan = {
> +	.master		= &dra7xx_l3_main_1_hwmod,
> +	.slave		= &dra76x_mcan_hwmod,
> +	.clk		= "l3_iclk_div",
> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> +};
> +
>  static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
>  	&dra7xx_l3_main_1__dmm,
>  	&dra7xx_l3_main_2__l3_instr,
> @@ -3958,6 +3989,7 @@ static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = {
>  /* SoC variant specific hwmod links */
>  static struct omap_hwmod_ocp_if *dra76x_hwmod_ocp_ifs[] __initdata = {
>  	&dra7xx_l4_per3__usb_otg_ss4,
> +	&dra76x_l3_main_1__mcan,
>  	NULL,
>  };

So the omap_hwmod_class, omap_hwmod_ocp_if and entry on the
dra76x_hwmod_ocp_ifs list are still needed with ti-sysc for a
while. Eventually that data will just come from the dts interconnect
hierarchy. For struct omap_hwmod_class_sysconfig, ti-sysc will
allocate and it based on the dts data.

Regards,

Tony

^ 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