Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2,7/9] irqchip/ls-scfg-msi: add LS1046a MSI support
From: Marc Zyngier @ 2017-01-05 15:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483603837-4629-7-git-send-email-Minghuan.Lian@nxp.com>

On 05/01/17 08:10, Minghuan Lian wrote:
> LS1046a includes 4 MSIRs, each MSIR is assigned a dedicate GIC
> SPI interrupt and provides 32 MSI interrupts. Compared to previous
> MSI, LS1046a's IBS(interrupt bit select) shift is changed to 2 and
> total MSI interrupt number is changed to 128.
> 
> The patch adds structure 'ls_scfg_msir' to describe MSIR setting and
> 'ibs_shift' to store the different value between the SoCs.
> 
> Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> v2-v1:
> - MSI dts node change has been merged into the patch 6/9
> 
>  drivers/irqchip/irq-ls-scfg-msi.c | 161 +++++++++++++++++++++++++++++---------
>  1 file changed, 126 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
> index cef67cc..67547bd 100644
> --- a/drivers/irqchip/irq-ls-scfg-msi.c
> +++ b/drivers/irqchip/irq-ls-scfg-msi.c
> @@ -17,13 +17,24 @@
>  #include <linux/irq.h>
>  #include <linux/irqchip/chained_irq.h>
>  #include <linux/irqdomain.h>
> +#include <linux/of_irq.h>
>  #include <linux/of_pci.h>
>  #include <linux/of_platform.h>
>  #include <linux/spinlock.h>
>  
> -#define MSI_MAX_IRQS	32
> -#define MSI_IBS_SHIFT	3
> -#define MSIR		4
> +#define MSI_IRQS_PER_MSIR	32
> +#define MSI_MSIR_OFFSET		4
> +
> +struct ls_scfg_msi_cfg {
> +	u32 ibs_shift; /* Shift of interrupt bit select */
> +};
> +
> +struct ls_scfg_msir {
> +	struct ls_scfg_msi *msi_data;
> +	unsigned int index;
> +	unsigned int gic_irq;
> +	void __iomem *reg;
> +};
>  
>  struct ls_scfg_msi {
>  	spinlock_t		lock;
> @@ -32,8 +43,11 @@ struct ls_scfg_msi {
>  	struct irq_domain	*msi_domain;
>  	void __iomem		*regs;
>  	phys_addr_t		msiir_addr;
> -	int			irq;
> -	DECLARE_BITMAP(used, MSI_MAX_IRQS);
> +	struct ls_scfg_msi_cfg	*cfg;
> +	u32			msir_num;
> +	struct ls_scfg_msir	*msir;
> +	u32			irqs_num;
> +	unsigned long		*used;
>  };
>  
>  static struct irq_chip ls_scfg_msi_irq_chip = {
> @@ -55,7 +69,7 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
>  
>  	msg->address_hi = upper_32_bits(msi_data->msiir_addr);
>  	msg->address_lo = lower_32_bits(msi_data->msiir_addr);
> -	msg->data = data->hwirq << MSI_IBS_SHIFT;
> +	msg->data = data->hwirq;
>  }
>  
>  static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
> @@ -81,8 +95,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
>  	WARN_ON(nr_irqs != 1);
>  
>  	spin_lock(&msi_data->lock);
> -	pos = find_first_zero_bit(msi_data->used, MSI_MAX_IRQS);
> -	if (pos < MSI_MAX_IRQS)
> +	pos = find_first_zero_bit(msi_data->used, msi_data->irqs_num);
> +	if (pos < msi_data->irqs_num)
>  		__set_bit(pos, msi_data->used);
>  	else
>  		err = -ENOSPC;
> @@ -106,7 +120,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
>  	int pos;
>  
>  	pos = d->hwirq;
> -	if (pos < 0 || pos >= MSI_MAX_IRQS) {
> +	if (pos < 0 || pos >= msi_data->irqs_num) {
>  		pr_err("failed to teardown msi. Invalid hwirq %d\n", pos);
>  		return;
>  	}
> @@ -123,15 +137,17 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
>  
>  static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
>  {
> -	struct ls_scfg_msi *msi_data = irq_desc_get_handler_data(desc);
> +	struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
> +	struct ls_scfg_msi *msi_data = msir->msi_data;
>  	unsigned long val;
> -	int pos, virq;
> +	int pos, virq, hwirq;
>  
>  	chained_irq_enter(irq_desc_get_chip(desc), desc);
>  
> -	val = ioread32be(msi_data->regs + MSIR);
> -	for_each_set_bit(pos, &val, MSI_MAX_IRQS) {
> -		virq = irq_find_mapping(msi_data->parent, (31 - pos));
> +	val = ioread32be(msir->reg);
> +	for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) {
> +		hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index;
> +		virq = irq_find_mapping(msi_data->parent, hwirq);
>  		if (virq)
>  			generic_handle_irq(virq);
>  	}
> @@ -143,7 +159,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
>  {
>  	/* Initialize MSI domain parent */
>  	msi_data->parent = irq_domain_add_linear(NULL,
> -						 MSI_MAX_IRQS,
> +						 msi_data->irqs_num,
>  						 &ls_scfg_msi_domain_ops,
>  						 msi_data);
>  	if (!msi_data->parent) {
> @@ -164,16 +180,83 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
>  	return 0;
>  }
>  
> +static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
> +{
> +	struct ls_scfg_msir *msir;
> +	int virq, i, hwirq;
> +
> +	virq = platform_get_irq(msi_data->pdev, index);
> +	if (virq <= 0)
> +		return -ENODEV;
> +
> +	msir = &msi_data->msir[index];
> +	msir->index = index;
> +	msir->msi_data = msi_data;
> +	msir->gic_irq = virq;
> +	msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index;
> +
> +	irq_set_chained_handler_and_data(msir->gic_irq,
> +					 ls_scfg_msi_irq_handler,
> +					 msir);
> +
> +	/* Release the hwirqs corresponding to this MSIR */
> +	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
> +		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> +		bitmap_clear(msi_data->used, hwirq, 1);
> +	}
> +
> +	return 0;
> +}
> +
> +static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
> +{
> +	struct ls_scfg_msi *msi_data = msir->msi_data;
> +	int i, hwirq;
> +
> +	if (msir->gic_irq > 0)
> +		irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL);
> +
> +	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
> +		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> +		bitmap_set(msi_data->used, hwirq, 1);
> +	}
> +
> +	return 0;
> +}
> +
> +static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
> +	.ibs_shift = 3,
> +};
> +
> +static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
> +	.ibs_shift = 2,
> +};
> +
> +static const struct of_device_id ls_scfg_msi_id[] = {
> +	{ .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
> +	{ .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
> +	{ .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },

So after 3 patches adding compatibility between the fsl,1s10 and
fsl,ls10 names, you discard them? How does it work again with the old DTs?

> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, ls_scfg_msi_id);
> +
>  static int ls_scfg_msi_probe(struct platform_device *pdev)
>  {
> +	const struct of_device_id *match;
>  	struct ls_scfg_msi *msi_data;
>  	struct resource *res;
> -	int ret;
> +	int i, ret;
> +
> +	match = of_match_device(ls_scfg_msi_id, &pdev->dev);
> +	if (!match)
> +		return -ENODEV;
>  
>  	msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL);
>  	if (!msi_data)
>  		return -ENOMEM;
>  
> +	msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data;
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	msi_data->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(msi_data->regs)) {
> @@ -182,23 +265,37 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
>  	}
>  	msi_data->msiir_addr = res->start;
>  
> -	msi_data->irq = platform_get_irq(pdev, 0);
> -	if (msi_data->irq <= 0) {
> -		dev_err(&pdev->dev, "failed to get MSI irq\n");
> -		return -ENODEV;
> -	}
> -
>  	msi_data->pdev = pdev;
>  	spin_lock_init(&msi_data->lock);
>  
> +	msi_data->irqs_num = MSI_IRQS_PER_MSIR *
> +			     (1 << msi_data->cfg->ibs_shift);
> +	msi_data->used = devm_kcalloc(&pdev->dev,
> +				    BITS_TO_LONGS(msi_data->irqs_num),
> +				    sizeof(*msi_data->used),
> +				    GFP_KERNEL);
> +	if (!msi_data->used)
> +		return -ENOMEM;
> +	/*
> +	 * Reserve all the hwirqs
> +	 * The available hwirqs will be released in ls1_msi_setup_hwirq()
> +	 */
> +	bitmap_set(msi_data->used, 0, msi_data->irqs_num);
> +
> +	msi_data->msir_num = of_irq_count(pdev->dev.of_node);
> +	msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
> +				      sizeof(*msi_data->msir),
> +				      GFP_KERNEL);
> +	if (!msi_data->msir)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < msi_data->msir_num; i++)
> +		ls_scfg_msi_setup_hwirq(msi_data, i);
> +
>  	ret = ls_scfg_msi_domains_init(msi_data);
>  	if (ret)
>  		return ret;
>  
> -	irq_set_chained_handler_and_data(msi_data->irq,
> -					 ls_scfg_msi_irq_handler,
> -					 msi_data);
> -
>  	platform_set_drvdata(pdev, msi_data);
>  
>  	return 0;
> @@ -207,8 +304,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
>  static int ls_scfg_msi_remove(struct platform_device *pdev)
>  {
>  	struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev);
> +	int i;
>  
> -	irq_set_chained_handler_and_data(msi_data->irq, NULL, NULL);
> +	for (i = 0; i < msi_data->msir_num; i++)
> +		ls_scfg_msi_teardown_hwirq(&msi_data->msir[i]);
>  
>  	irq_domain_remove(msi_data->msi_domain);
>  	irq_domain_remove(msi_data->parent);
> @@ -218,14 +317,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> -static const struct of_device_id ls_scfg_msi_id[] = {
> -	{ .compatible = "fsl,1s1021a-msi", }, /* a typo */
> -	{ .compatible = "fsl,1s1043a-msi", }, /* a typo */
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
these entries definitely need to be restored.

Also, please make sure you have a cover letter at the beginning of the
series. I flag series to review by flagging the cover letter, and I
suspect many of us are doing something similar. Not doing so is likely
to leave your series unreviewed...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH 15/20] ARM/hw_breakpoint: Convert to hotplug state machine
From: Linus Walleij @ 2017-01-05 15:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170104135644.GA29212@leverpostej>

On Wed, Jan 4, 2017 at 2:56 PM, Mark Rutland <mark.rutland@arm.com> wrote:

> I've just reproduced this locally on my dragonboard APQ8060.

Sweet!

> It looks like the write_wb_reg() call that's exploding is from
> get_max_wp_len(), which we call immediately after registering the
> dbg_reset_online callback. Clearing DBGPRSR.SPD before the write_wb_reg() hides
> the problem, so I suspect we're seeing the issue I mentioned above -- it just
> so happens that we go idle in a new place.
>
> The below hack allows boot to continue, but is not a real fix. I'm not
> immediately sure what to do.

Me neither. But Will's suggestion to simply blacklist this chip might be
best.

> Linus, I wasn't able to get ethernet working. Do I need anything on top
> of v4.10-rc2 && multi_v7_defconfig?

I haven't tried it with multi_v7 but I should probably try that and patch
up the defconfigs, those are probably the root of the problem.

I do this on top of qcom_defconfig:

scripts/config --file .config \
        --enable QCOM_EBI2 \
        --enable ETHERNET \
        --enable NET_VENDOR_SMSC \
        --enable SMSC911X

Maybe you are missing the EBI2 config?

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v2,9/9] irqchip/ls-scfg-msi: add MSI affinity support
From: Marc Zyngier @ 2017-01-05 15:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483603837-4629-9-git-send-email-Minghuan.Lian@nxp.com>

On 05/01/17 08:10, Minghuan Lian wrote:
> For LS1046a and LS1043a v1.1, the MSI controller has 4 MSIRs and 4
> CPUs. A GIC SPI interrupt of MSIR can be associated with a CPU.
> When changing MSI interrupt affinity, this MSI will be moved to the
> corresponding MSIR and MSI message data will be changed according to
> MSIR. when requesting a MSI, the bits of all 4 MSIR will be reserved.
> The parameter 'msi_affinity_flag' is provide to change this mode.
> "lsmsi=no-affinity" will disable affinity, all MSI can only be
> associated with CPU 0.
> 
> Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> ---
> v2-v1:
> - None
> 
>  drivers/irqchip/irq-ls-scfg-msi.c | 75 ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 70 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
> index dc19569..753fe39 100644
> --- a/drivers/irqchip/irq-ls-scfg-msi.c
> +++ b/drivers/irqchip/irq-ls-scfg-msi.c
> @@ -40,6 +40,7 @@ struct ls_scfg_msir {
>  	unsigned int gic_irq;
>  	unsigned int bit_start;
>  	unsigned int bit_end;
> +	unsigned int srs; /* Shared interrupt register select */
>  	void __iomem *reg;
>  };
>  
> @@ -70,6 +71,19 @@ struct ls_scfg_msi {
>  	.chip	= &ls_scfg_msi_irq_chip,
>  };
>  
> +static int msi_affinity_flag = 1;
> +
> +static int __init early_parse_ls_scfg_msi(char *p)
> +{
> +	if (p && strncmp(p, "no-affinity", 11) == 0)
> +		msi_affinity_flag = 0;
> +	else
> +		msi_affinity_flag = 1;
> +
> +	return 0;
> +}
> +early_param("lsmsi", early_parse_ls_scfg_msi);

What is the point of this option? If feels like an unnecessary complexity.

> +
>  static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
>  {
>  	struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(data);
> @@ -77,12 +91,43 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
>  	msg->address_hi = upper_32_bits(msi_data->msiir_addr);
>  	msg->address_lo = lower_32_bits(msi_data->msiir_addr);
>  	msg->data = data->hwirq;
> +
> +	if (msi_affinity_flag) {
> +		u32 msir_index;
> +
> +		msir_index = cpumask_first(data->common->affinity);
> +		if (msir_index >= msi_data->msir_num)
> +			msir_index = 0;

How can this happen?

> +
> +		msg->data |= msir_index;

How do you guarantee that the low bits were clear? Please document the
way you encode your MSI payload.

> +	}
>  }
>  
>  static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
>  				    const struct cpumask *mask, bool force)
>  {
> -	return -EINVAL;
> +	struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(irq_data);
> +	u32 cpu;
> +
> +	if (!msi_affinity_flag)
> +		return -EINVAL;
> +
> +	if (!force)
> +		cpu = cpumask_any_and(mask, cpu_online_mask);
> +	else
> +		cpu = cpumask_first(mask);
> +
> +	if (cpu >= msi_data->msir_num)
> +		return -EINVAL;
> +
> +	if (msi_data->msir[cpu].gic_irq <= 0) {
> +		pr_warn("cannot bind the irq to cpu%d\n", cpu);

Please don't. Returning an error is enough. If you really want to have
something, turn it into a proper debug message.

> +		return -EINVAL;
> +	}
> +
> +	cpumask_copy(irq_data->common->affinity, mask);
> +
> +	return IRQ_SET_MASK_OK;
>  }
>  
>  static struct irq_chip ls_scfg_msi_parent_chip = {
> @@ -158,7 +203,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
>  
>  	for_each_set_bit_from(pos, &val, size) {
>  		hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
> -			msir->index;
> +			msir->srs;
>  		virq = irq_find_mapping(msi_data->parent, hwirq);
>  		if (virq)
>  			generic_handle_irq(virq);
> @@ -221,10 +266,19 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
>  					 ls_scfg_msi_irq_handler,
>  					 msir);
>  
> +	if (msi_affinity_flag) {
> +		/* Associate MSIR interrupt to the cpu */
> +		irq_set_affinity(msir->gic_irq, get_cpu_mask(index));
> +		msir->srs = 0; /* This value is determined by the CPU */
> +	} else
> +		msir->srs = index;
> +
>  	/* Release the hwirqs corresponding to this MSIR */
> -	for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
> -		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> -		bitmap_clear(msi_data->used, hwirq, 1);
> +	if (!msi_affinity_flag || msir->index == 0) {
> +		for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
> +			hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> +			bitmap_clear(msi_data->used, hwirq, 1);
> +		}
>  	}
>  
>  	return 0;
> @@ -316,6 +370,17 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
>  	bitmap_set(msi_data->used, 0, msi_data->irqs_num);
>  
>  	msi_data->msir_num = of_irq_count(pdev->dev.of_node);
> +
> +	if (msi_affinity_flag) {
> +		u32 cpu_num;
> +
> +		cpu_num = num_possible_cpus();
> +		if (msi_data->msir_num >= cpu_num)
> +			msi_data->msir_num = cpu_num;
> +		else
> +			msi_affinity_flag = 0;
> +	}
> +
>  	msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
>  				      sizeof(*msi_data->msir),
>  				      GFP_KERNEL);
> 

This is a very confusing patch. Please get rid of this useless option
and document how you encode the routing in the hwirq.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH 02/10] iommu/of: Prepare for deferred IOMMU configuration
From: Lorenzo Pieralisi @ 2017-01-05 15:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7cd7bcfb-abae-2948-c3f8-230c0d9c9db6@arm.com>

On Thu, Jan 05, 2017 at 01:52:29PM +0000, Robin Murphy wrote:

[...]

> > Question: I had a look into this and instead of fiddling about with the
> > linker script entries in ACPI (ie IORT_ACPI_DECLARE - which I hope this
> > patchset would help remove entirely), I think that the only check we
> > need in IORT is, depending on what type of SMMU a given device is
> > connected to, to check if the respective SMMU driver is compiled in the
> > kernel and it will be probed, _eventually_.
> > 
> > As Robin said, by the time a device is probed the respective SMMU
> > devices are already created and registered with IORT kernel code or
> > they will never be, so to understand if we should defer probing
> > SMMU device creation is _not_ really a problem in ACPI.
> > 
> > To check if a SMMU driver is enabled, do we really need a linker
> > table ?
> > 
> > Would not a check based on eg:
> > 
> > /**
> >  * @type: IOMMU IORT node type of the IOMMU a device is connected to
> >  */
> > static bool iort_iommu_driver_enabled(u8 type)
> > {
> > 	switch (type) {
> > 	case ACPI_IORT_SMMU_V3:
> > 		return IS_ENABLED(CONFIG_ARM_SMMU_V3);
> 
> IS_BUILTIN(...)

Yep right, it is currently equivalent but that does not mean it
will always be.

> > 	case ACPI_IORT_SMMU:
> > 		return IS_ENABLED(CONFIG_ARM_SMMU);
> > 	default:
> > 		pr_warn("Unknown IORT SMMU type\n");
> 
> Might displaying the actual value be helfpul for debugging a broken IORT
> table?

Yes I will do.

> > 		return false;
> > 	}
> > }
> > 
> > be sufficient (it is a bit gross, agreed, but it is to understand if
> > that's all we need) ? Is there anything I am missing ?
> > 
> > Let me know, I will put together a patch for you I really do not
> > want to block your series for this trivial niggle.
> 
> Other than that, though, I like it :) IORT has a small, strictly
> bounded, set of supported devices, so I really don't see the need to go
> overboard putting it on parity with DT when something this neat and
> simple will suffice.

Ok, patch coming, which will also allow Sricharan to get rid of the
IORT linker script infrastructure altogether (and more than that,
I can write the patches on top of Sricharan series that I managed
to rebase against v4.10-rc2).

Thanks,
Lorenzo

^ permalink raw reply

* [PATCH v2 9/9] ARM: sunxi: Convert pinctrl nodes to generic bindings
From: Maxime Ripard @ 2017-01-05 15:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <58723369-50ad-1792-9be1-c277eb719044@arm.com>

On Wed, Jan 04, 2017 at 02:16:23AM +0000, Andr? Przywara wrote:
> So can I ask that we start taking this seriously and stop doing things
> which prevent Allwinner boards from being supported properly?
> Which would first involve dropping this very patch?

The driver still supports the old binding.

> Having done breakage in the past (with "allwinner,sun7i-a20-mmc", for
> instance) is no excuse for doing it again.

I'm not sure which breakage we introduced with a new compatible: the
old compatible is working just like it used to, and the new one is
working like we need it to.

> And especially I want to avoid this habit creeping into the arm64
> world (thinking about the H5 here, which may be impacted by this
> very patch, for instance).

And again, if you looked at the entire serie, you would have seen that
I took this into account.

Maxime

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

^ permalink raw reply

* [PATCH 1/6] ARM: dts: am335x-phycore-som: Update NAND partition table
From: Tony Lindgren @ 2017-01-05 15:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483627851-17996-2-git-send-email-t.remmet@phytec.de>

* Teresa Remmet <t.remmet@phytec.de> [170105 06:57]:
> To improve NAND safety we updated the partition layout.
> Added barebox backup partition and removed kernel and oftree
> partition. They are kept in ubi now.

What about the users with earlier partition tables?

Please read about "flag day" changes, typically they are not
acceptable.

Regards,

Tony

^ permalink raw reply

* [PATCH] arm64: dts: msm8996: Add required memory carveouts
From: Bjorn Andersson @ 2017-01-05 15:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482357822-20823-1-git-send-email-andy.gross@linaro.org>

On Wed 21 Dec 14:03 PST 2016, Andy Gross wrote:

> From: Stephen Boyd <sboyd@codeaurora.org>
> 
> This patch adds required memory carveouts so that the kernel does not
> access memory that is in use or has been reserved for use by other remote
> processors.
> 
> Signed-off-by: Andy Gross <andy.gross@linaro.org>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Regards,
Bjorn

> ---
>  arch/arm64/boot/dts/qcom/msm8996.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> index cde4114..25e11dc 100644
> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> @@ -64,6 +64,16 @@
>  			reg = <0x0 0x86000000 0x0 0x200000>;
>  			no-map;
>  		};
> +
> +		memory at 85800000 {
> +			reg = <0x0 0x85800000 0x0 0x800000>;
> +			no-map;
> +		};
> +
> +		memory at 86200000 {
> +			reg = <0x0 0x86200000 0x0 0x2600000>;
> +			no-map;
> +		};
>  	};
>  
>  	cpus {
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 15/20] ARM/hw_breakpoint: Convert to hotplug state machine
From: Mark Rutland @ 2017-01-05 15:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170104143205.GG18193@arm.com>

On Wed, Jan 04, 2017 at 02:32:06PM +0000, Will Deacon wrote:
> On Wed, Jan 04, 2017 at 01:56:44PM +0000, Mark Rutland wrote:
> > On Tue, Jan 03, 2017 at 09:33:36AM +0000, Mark Rutland wrote:
> > > On Mon, Jan 02, 2017 at 09:15:29PM +0100, Linus Walleij wrote:
> > > > On Mon, Jan 2, 2017 at 4:00 PM, Russell King - ARM Linux
> > > > <linux@armlinux.org.uk> wrote:
> > > > > On Mon, Jan 02, 2017 at 03:34:32PM +0100, Linus Walleij wrote:
> > > > >> in the first line of arch_hw_breakpoint_init() in
> > > > >> arch/arm/kernel/hw_breakpoint.c
> > > > >>
> > > > >> I suspect that is not an accepable solution ...
> > > > >>
> > > > >> It hangs at PC is at write_wb_reg+0x20c/0x330
> > > > >> Which is c03101dc, and looks like this in objdump -d:
> > > > >>
> > > > >> c031020c:       ee001eba        mcr     14, 0, r1, cr0, cr10, {5}
> > > > >> c0310210:       eaffffb3        b       c03100e4 <write_wb_reg+0x114>
> > > > >
> > > > > ... and this is several instructions after the address you mention above.
> > > > > Presumably c03101dc is accessing a higher numbered register?
> > > > 
> > > > Ah sorry. It looks like this:
> > > > 
> > > > c03101dc:       ee001ed0        mcr     14, 0, r1, cr0, cr0, {6}
> > > > c03101e0:       eaffffbf        b       c03100e4 <write_wb_reg+0x114>
> > > > c03101e4:       ee001ebf        mcr     14, 0, r1, cr0, cr15, {5}
> > > > c03101e8:       eaffffbd        b       c03100e4 <write_wb_reg+0x114>
> > > > c03101ec:       ee001ebe        mcr     14, 0, r1, cr0, cr14, {5}
> > > > c03101f0:       eaffffbb        b       c03100e4 <write_wb_reg+0x114>
> > > > c03101f4:       ee001ebd        mcr     14, 0, r1, cr0, cr13, {5}
> > > > c03101f8:       eaffffb9        b       c03100e4 <write_wb_reg+0x114>
> > > 
> > > FWIW, I was tracking an issue in this area before the holiday.
> > > 
> > > It looked like DBGPRSR.SPD is set unexpectedly over the default idle
> > > path (i.e. WFI), causing the (otherwise valid) register accesses above
> > > to be handled as undefined.
> > > 
> > > I haven't looked at the patch in detail, but I guess that it allows idle
> > > to occur between reset_ctrl_regs() and arch_hw_breakpoint_init().
> > 
> > I've just reproduced this locally on my dragonboard APQ8060.
> > 
> > It looks like the write_wb_reg() call that's exploding is from
> > get_max_wp_len(), which we call immediately after registering the
> > dbg_reset_online callback. Clearing DBGPRSR.SPD before the write_wb_reg() hides
> > the problem, so I suspect we're seeing the issue I mentioned above -- it just
> > so happens that we go idle in a new place.
> 
> When you say "go idle", are we just executing a WFI, 

>From my prior experiments, just executing a WFI as we happen to do in
the default cpu_v7_do_idle. I tried passing cpuidle.off=1, but that
didn't help. NOPing the WFI in cpu_v7_do_idle did mask the issue, from
what I recall.

> or is the power controller coming into play and we're actually
> powering down the non-debug logic?

As far as I can see, that isn't happening. We don't save/restore any
other CPU state in the default idle path, and the kernel is otherwise
happy.

> In the case of the latter, the PM notifier should clear SPD in
> reset_ctrl_regs, so this sounds like a hardware bug where the SPD bit is
> set unconditionally on WFI.
> 
> In that case, this code has always been dodgy -- what happens if you try
> to use hardware breakpoints in GDB in the face of WFI-based idle?

The kernel blows up similiarly to Linus's original report when the
kernel tries to program the breakpoint registers.

I also believe this has always been dodgy.

> > The below hack allows boot to continue, but is not a real fix. I'm not
> > immediately sure what to do.
> 
> If it's never worked, I suggest we blacklist the MIDR until somebody from
> Qualcomm can help us further.

I'll see about putting a patch together.

Thanks,
Mark.

> 
> Will

^ permalink raw reply

* [PATCH 0/2] media: rc: add support for IR receiver on MT7623 SoC
From: sean.wang at mediatek.com @ 2017-01-05 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Sean Wang <sean.wang@mediatek.com>

This patchset introduces Consumer IR (CIR) support for MT7623 SoC 
or other similar SoC and implements raw mode for more compatibility
with different protocols. The driver simply reports the duration of 
pulses and spaces to rc core logic to decode.

Sean Wang (2):
  Documentation: devicetree: Add document bindings for mtk-cir
  media: rc: add driver for IR remote receiver on MT7623 SoC

 .../devicetree/bindings/media/mtk-cir.txt          |  23 ++
 drivers/media/rc/Kconfig                           |  10 +
 drivers/media/rc/Makefile                          |   1 +
 drivers/media/rc/mtk-cir.c                         | 319 +++++++++++++++++++++
 4 files changed, 353 insertions(+)
 create mode 100644 linux-4.8.rc1_p0/Documentation/devicetree/bindings/media/mtk-cir.txt
 create mode 100644 linux-4.8.rc1_p0/drivers/media/rc/mtk-cir.c

-- 
1.9.1

^ permalink raw reply

* [PATCH 1/2] Documentation: devicetree: Add document bindings for mtk-cir
From: sean.wang at mediatek.com @ 2017-01-05 16:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483632384-8107-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds documentation for devicetree bindings for
Mediatek IR controller.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 .../devicetree/bindings/media/mtk-cir.txt          | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 linux-4.8.rc1_p0/Documentation/devicetree/bindings/media/mtk-cir.txt

diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
new file mode 100644
index 0000000..bbedd71
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mtk-cir.txt
@@ -0,0 +1,23 @@
+Device-Tree bindings for Mediatek IR controller found in Mediatek SoC family
+
+Required properties:
+- compatible	    : "mediatek,mt7623-ir"
+- clocks	    : list of clock specifiers, corresponding to
+		      entries in clock-names property;
+- clock-names	    : should contain "clk" entries;
+- interrupts	    : should contain IR IRQ number;
+- reg		    : should contain IO map address for IR.
+
+Optional properties:
+- linux,rc-map-name : Remote control map name.
+
+Example:
+
+cir: cir at 0x10013000 {
+	compatible = "mediatek,mt7623-ir";
+	reg = <0 0x10013000 0 0x1000>;
+	interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
+	clocks = <&infracfg CLK_INFRA_IRRX>;
+	clock-names = "clk";
+	linux,rc-map-name = "rc-rc6-mce";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: sean.wang at mediatek.com @ 2017-01-05 16:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483632384-8107-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds driver for IR controller on
Mediatek MT7623 SoC. Currently testing successfully
on NEC and SONY remote controller only but it should
work on others (lirc, rc-5 and rc-6).

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/media/rc/Kconfig   |  10 ++
 drivers/media/rc/Makefile  |   1 +
 drivers/media/rc/mtk-cir.c | 319 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 330 insertions(+)
 create mode 100644 linux-4.8.rc1_p0/drivers/media/rc/mtk-cir.c

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 370e16e..626c500 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -389,4 +389,14 @@ config IR_SUNXI
 	   To compile this driver as a module, choose M here: the module will
 	   be called sunxi-ir.
 
+config IR_MTK
+	tristate "Mediatek IR remote control"
+	depends on RC_CORE
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	---help---
+	   Say Y if you want to use Mediatek internal IR Controller
+
+	   To compile this driver as a module, choose M here: the module will
+	   be called mtk-cir.
+
 endif #RC_DEVICES
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 379a5c0..505908d 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
 obj-$(CONFIG_RC_ST) += st_rc.o
 obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
 obj-$(CONFIG_IR_IMG) += img-ir/
+obj-$(CONFIG_IR_MTK) += mtk-cir.o
diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
new file mode 100644
index 0000000..4fa4cab
--- /dev/null
+++ b/drivers/media/rc/mtk-cir.c
@@ -0,0 +1,319 @@
+/*
+ * Driver for Mediatek MT7623 IR Receiver Controller
+ *
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+#include <media/rc-core.h>
+
+#define MTK_IR_DEV "mtk-ir"
+
+/* Register to enable PWM and IR */
+#define MTK_CONFIG_HIGH_REG       0x0c
+/* Enable IR pulse width detection */
+#define MTK_PWM_EN		  BIT(13)
+/* Enable IR hardware function */
+#define MTK_IR_EN		  BIT(0)
+
+/* Register to setting sample period */
+#define MTK_CONFIG_LOW_REG        0x10
+/* Field to set sample period */
+#define CHK_PERIOD		  0xC00
+#define MTK_CHK_PERIOD            (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
+#define MTK_CHK_PERIOD_MASK	  (GENMASK(20, 8))
+
+/* Register to clear state of state machine */
+#define MTK_IRCLR_REG             0x20
+/* Bit to restart IR receiving */
+#define MTK_IRCLR		  BIT(0)
+
+/* Register containing pulse width data */
+#define MTK_CHKDATA_REG(i)        (0x88 + 4 * i)
+
+/* Register to enable IR interrupt */
+#define MTK_IRINT_EN_REG          0xcc
+/* Bit to enable interrupt */
+#define MTK_IRINT_EN		  BIT(0)
+
+/* Register to ack IR interrupt */
+#define MTK_IRINT_CLR_REG         0xd0
+/* Bit to clear interrupt status */
+#define MTK_IRINT_CLR		  BIT(0)
+
+/* Number of registers to record the pulse width */
+#define MTK_CHKDATA_SZ		  17
+/* Required frequency */
+#define MTK_IR_BASE_CLK		  273000000
+/* Frequency after IR internal divider */
+#define MTK_IR_CLK		  (MTK_IR_BASE_CLK / 4)
+/* Sample period in ns */
+#define MTK_IR_SAMPLE		  (((1000000000ul / MTK_IR_CLK) * CHK_PERIOD))
+/* Indicate the end of IR data*/
+#define MTK_IR_END(v)		  (v == 0xff)
+
+/* struct mtk_ir -	This is the main datasructure for holding the state
+ *			of the driver
+ * @dev:		The device pointer
+ * @ir_lock:		Make sure that synchronization between remove and ISR
+ * @rc:			The rc instrance
+ * @base:		The mapped register i/o base
+ * @irq:		The IRQ that we are using
+ * @clk:		The clock that we are using
+ * @map_name:		The name for keymap lookup
+ */
+struct mtk_ir {
+	struct device   *dev;
+	/*Protect concurrency between driver removal and ISR*/
+	spinlock_t      ir_lock;
+	struct rc_dev   *rc;
+	void __iomem    *base;
+	int             irq;
+	struct clk      *clk;
+	const char      *map_name;
+};
+
+static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
+{
+	u32 tmp;
+
+	tmp = __raw_readl(ir->base + reg);
+	tmp = (tmp & ~mask) | val;
+	__raw_writel(tmp, ir->base + reg);
+}
+
+static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
+{
+	__raw_writel(val, ir->base + reg);
+}
+
+static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
+{
+	return __raw_readl(ir->base + reg);
+}
+
+static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
+{
+	u32 val;
+
+	val = mtk_r32(ir, MTK_IRINT_EN_REG);
+	mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
+}
+
+static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
+{
+	u32 val;
+
+	val = mtk_r32(ir, MTK_IRINT_EN_REG);
+	mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
+}
+
+static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
+{
+	struct mtk_ir *ir = dev_id;
+	u8  wid = 0;
+	u32 i, j, val;
+	DEFINE_IR_RAW_EVENT(rawir);
+
+	spin_lock(&ir->ir_lock);
+
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+
+	/* Reset decoder state machine */
+	ir_raw_event_reset(ir->rc);
+
+	/* First message must be pulse */
+	rawir.pulse = false;
+
+	/* Handle pulse and space until end of message */
+	for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
+		val = mtk_r32(ir, MTK_CHKDATA_REG(i));
+		dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
+
+		for (j = 0 ; j < 4 ; j++) {
+			wid = (val & (0xff << j * 8)) >> j * 8;
+			rawir.pulse = !rawir.pulse;
+			rawir.duration = wid * (MTK_IR_SAMPLE + 1);
+			ir_raw_event_store_with_filter(ir->rc, &rawir);
+
+			if (MTK_IR_END(wid))
+				goto end_msg;
+		}
+	}
+end_msg:
+	/* Restart the next receive */
+	mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
+
+	ir_raw_event_set_idle(ir->rc, true);
+	ir_raw_event_handle(ir->rc);
+
+	/* Clear interrupt status */
+	mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
+
+	/* Enable interrupt */
+	mtk_irq_enable(ir, MTK_IRINT_EN);
+
+	spin_unlock(&ir->ir_lock);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_ir_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *dn = dev->of_node;
+	struct resource *res;
+	struct mtk_ir *ir;
+	u32 val;
+	int ret = 0;
+
+	ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
+	if (!ir)
+		return -ENOMEM;
+
+	spin_lock_init(&ir->ir_lock);
+
+	ir->dev = dev;
+
+	if (!of_device_is_compatible(dn, "mediatek,mt7623-ir"))
+		return -ENODEV;
+
+	ir->clk = devm_clk_get(dev, "clk");
+	if (IS_ERR(ir->clk)) {
+		dev_err(dev, "failed to get a ir clock.\n");
+		return PTR_ERR(ir->clk);
+	}
+
+	if (clk_prepare_enable(ir->clk)) {
+		dev_err(dev, "try to enable ir_clk failed\n");
+		ret = -EINVAL;
+		goto exit_clkdisable_clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ir->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ir->base)) {
+		dev_err(dev, "failed to map registers\n");
+		ret = PTR_ERR(ir->base);
+		goto exit_clkdisable_clk;
+	}
+
+	ir->rc = rc_allocate_device();
+	if (!ir->rc) {
+		dev_err(dev, "failed to allocate device\n");
+		ret = -ENOMEM;
+		goto exit_clkdisable_clk;
+	}
+
+	ir->rc->priv = ir;
+	ir->rc->input_name = MTK_IR_DEV;
+	ir->rc->input_phys = "mtk-ir/input0";
+	ir->rc->input_id.bustype = BUS_HOST;
+	ir->rc->input_id.vendor = 0x0001;
+	ir->rc->input_id.product = 0x0001;
+	ir->rc->input_id.version = 0x0001;
+	ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
+	ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
+	ir->rc->dev.parent = dev;
+	ir->rc->driver_type = RC_DRIVER_IR_RAW;
+	ir->rc->driver_name = MTK_IR_DEV;
+	ir->rc->allowed_protocols = RC_BIT_ALL;
+	ir->rc->rx_resolution = MTK_IR_SAMPLE;
+
+	ret = rc_register_device(ir->rc);
+	if (ret) {
+		dev_err(dev, "failed to register rc device\n");
+		goto exit_free_dev;
+	}
+
+	platform_set_drvdata(pdev, ir);
+
+	ir->irq = platform_get_irq(pdev, 0);
+	if (ir->irq < 0) {
+		dev_err(dev, "no irq resource\n");
+		ret = ir->irq;
+		goto exit_free_dev;
+	}
+
+	ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
+	if (ret) {
+		dev_err(dev, "failed request irq\n");
+		goto exit_free_dev;
+	}
+
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+
+	val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
+	val |= MTK_PWM_EN | MTK_IR_EN;
+	mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
+
+	/* Setting sample period */
+	mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
+		     MTK_CONFIG_LOW_REG);
+
+	mtk_irq_enable(ir, MTK_IRINT_EN);
+
+	dev_info(dev, "initialized MT7623 IR driver\n");
+	return 0;
+
+exit_free_dev:
+	rc_free_device(ir->rc);
+exit_clkdisable_clk:
+	clk_disable_unprepare(ir->clk);
+
+	return ret;
+}
+
+static int mtk_ir_remove(struct platform_device *pdev)
+{
+	unsigned long flags;
+
+	struct mtk_ir *ir = platform_get_drvdata(pdev);
+
+	spin_lock_irqsave(&ir->ir_lock, flags);
+
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+
+	clk_disable_unprepare(ir->clk);
+
+	spin_unlock_irqrestore(&ir->ir_lock, flags);
+
+	rc_unregister_device(ir->rc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_ir_match[] = {
+	{ .compatible = "mediatek,mt7623-ir" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_ir_match);
+
+static struct platform_driver mtk_ir_driver = {
+	.probe          = mtk_ir_probe,
+	.remove         = mtk_ir_remove,
+	.driver = {
+		.name = MTK_IR_DEV,
+		.of_match_table = mtk_ir_match,
+	},
+};
+
+module_platform_driver(mtk_ir_driver);
+
+MODULE_DESCRIPTION("Mediatek MT7623 IR Receiver Controller Driver");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
1.9.1

^ permalink raw reply related

* [PATCH] n900 device tree: cleanup
From: Tony Lindgren @ 2017-01-05 16:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201612141328.27244@pali>

* Pali Roh?r <pali.rohar@gmail.com> [161214 04:28]:
> On Wednesday 07 December 2016 04:10:48 Sebastian Reichel wrote:
> > Hi Tony,
> > 
> > It looks like this fell through the cracks. Apart from inconsistent
> > patch subject:
> > 
> > Reviewed-By: Sebastian Reichel <sre@kernel.org>
> 
> Fine for me too. Reviewed-By: Pali Roh?r <pali.rohar@gmail.com>

Fixing subject line to use "ARM: dts: n900: cleanup" and applying into
omap-for-v4.11/dt.

Tony

^ permalink raw reply

* [PATCH 10/12] ARM: dts: socfpga: add base fpga region and fpga bridges
From: Alan Tull @ 2017-01-05 16:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483575694-29599-11-git-send-email-dinguyen@kernel.org>

On Wed, Jan 4, 2017 at 6:21 PM, Dinh Nguyen <dinguyen@kernel.org> wrote:
> From: Alan Tull <atull@opensource.altera.com>
>
> Add h2f and lwh2f bridges.
> Add base FPGA Region to support DT overlays for FPGA programming.
> Add l3regs.
>
> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
> ---
>  arch/arm/boot/dts/socfpga.dtsi | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
>
> diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
> index de29172..dccc281 100644
> --- a/arch/arm/boot/dts/socfpga.dtsi
> +++ b/arch/arm/boot/dts/socfpga.dtsi
> @@ -93,6 +93,16 @@
>                         };
>                 };
>
> +               base_fpga_region {
> +                       compatible = "fpga-region";
> +                       fpga-mgr = <&fpgamgr0>;
> +                       fpga-bridges = <&fpga_bridge0>, <&fpga_bridge1>;

Hi Dinh,

We want to get rid of the 'fpga-bridges' line.

> +
> +                       #address-cells = <0x1>;
> +                       #size-cells = <0x1>;
> +                       ranges = <0 0xff200000 0x100000>;

Should get rid of the ranges line here too.  The 'fpga-bridges' and
'ranges' line can be added in the overlay.

Alan

> +               };
> +
>                 can0: can at ffc00000 {
>                         compatible = "bosch,d_can";
>                         reg = <0xffc00000 0x1000>;
> @@ -513,6 +523,22 @@
>                                 };
>                 };
>
> +               fpga_bridge0: fpga_bridge at ff400000 {
> +                       compatible = "altr,socfpga-lwhps2fpga-bridge";
> +                       reg = <0xff400000 0x100000>;
> +                       resets = <&rst LWHPS2FPGA_RESET>;
> +                       reset-names = "lwhps2fpga";
> +                       clocks = <&l4_main_clk>;
> +               };
> +
> +               fpga_bridge1: fpga_bridge at ff500000 {
> +                       compatible = "altr,socfpga-hps2fpga-bridge";
> +                       reg = <0xff500000 0x10000>;
> +                       resets = <&rst HPS2FPGA_RESET>;
> +                       reset-names = "hps2fpga";
> +                       clocks = <&l4_main_clk>;
> +               };
> +
>                 fpgamgr0: fpgamgr at ff706000 {
>                         compatible = "altr,socfpga-fpga-mgr";
>                         reg = <0xff706000 0x1000
> @@ -694,6 +720,11 @@
>                         arm,prefetch-offset = <7>;
>                 };
>
> +               l3regs at 0xff800000 {
> +                       compatible = "altr,l3regs", "syscon";
> +                       reg = <0xff800000 0x1000>;
> +               };
> +
>                 mmc: dwmmc0 at ff704000 {
>                         compatible = "altr,socfpga-dw-mshc";
>                         reg = <0xff704000 0x1000>;
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 2/2] dt-bindings: Add DT bindings info for FlexRM ring manager
From: Rob Herring @ 2017-01-05 16:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483614475-3442-3-git-send-email-anup.patel@broadcom.com>

On Thu, Jan 5, 2017 at 5:07 AM, Anup Patel <anup.patel@broadcom.com> wrote:
> This patch adds device tree bindings document for the FlexRM
> ring manager found on Broadcom iProc SoCs.
>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Anup Patel <anup.patel@broadcom.com>
> ---
>  .../bindings/mailbox/brcm,iproc-flexrm-mbox.txt    | 59 ++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/brcm,iproc-flexrm-mbox.txt

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH 10/12] ARM: dts: socfpga: add base fpga region and fpga bridges
From: Alan Tull @ 2017-01-05 16:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANk1AXSbqohp73xHpp7e9-37d61ZB-dRAPAFc2eQGRYUnvB+0w@mail.gmail.com>

On Thu, Jan 5, 2017 at 10:28 AM, Alan Tull <atull@kernel.org> wrote:
> On Wed, Jan 4, 2017 at 6:21 PM, Dinh Nguyen <dinguyen@kernel.org> wrote:
>> From: Alan Tull <atull@opensource.altera.com>
>>
>> Add h2f and lwh2f bridges.
>> Add base FPGA Region to support DT overlays for FPGA programming.
>> Add l3regs.
>>
>> Signed-off-by: Alan Tull <atull@opensource.altera.com>
>> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
>> ---
>>  arch/arm/boot/dts/socfpga.dtsi | 31 +++++++++++++++++++++++++++++++
>>  1 file changed, 31 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
>> index de29172..dccc281 100644
>> --- a/arch/arm/boot/dts/socfpga.dtsi
>> +++ b/arch/arm/boot/dts/socfpga.dtsi
>> @@ -93,6 +93,16 @@
>>                         };
>>                 };
>>
>> +               base_fpga_region {
>> +                       compatible = "fpga-region";
>> +                       fpga-mgr = <&fpgamgr0>;
>> +                       fpga-bridges = <&fpga_bridge0>, <&fpga_bridge1>;
>
> Hi Dinh,
>
> We want to get rid of the 'fpga-bridges' line.
>
>> +
>> +                       #address-cells = <0x1>;
>> +                       #size-cells = <0x1>;
>> +                       ranges = <0 0xff200000 0x100000>;
>
> Should get rid of the ranges line here too.  The 'fpga-bridges' and
> 'ranges' line can be added in the overlay.
>
> Alan
>
>> +               };
>> +
>>                 can0: can at ffc00000 {
>>                         compatible = "bosch,d_can";
>>                         reg = <0xffc00000 0x1000>;
>> @@ -513,6 +523,22 @@
>>                                 };
>>                 };
>>
>> +               fpga_bridge0: fpga_bridge at ff400000 {
>> +                       compatible = "altr,socfpga-lwhps2fpga-bridge";
>> +                       reg = <0xff400000 0x100000>;
>> +                       resets = <&rst LWHPS2FPGA_RESET>;
>> +                       reset-names = "lwhps2fpga";

The driver doesn't need 'reset-names' here or below for fpga_bridge1.

>> +                       clocks = <&l4_main_clk>;
>> +               };
>> +
>> +               fpga_bridge1: fpga_bridge at ff500000 {
>> +                       compatible = "altr,socfpga-hps2fpga-bridge";
>> +                       reg = <0xff500000 0x10000>;
>> +                       resets = <&rst HPS2FPGA_RESET>;
>> +                       reset-names = "hps2fpga";
>> +                       clocks = <&l4_main_clk>;
>> +               };
>> +
>>                 fpgamgr0: fpgamgr at ff706000 {
>>                         compatible = "altr,socfpga-fpga-mgr";
>>                         reg = <0xff706000 0x1000
>> @@ -694,6 +720,11 @@
>>                         arm,prefetch-offset = <7>;
>>                 };
>>
>> +               l3regs at 0xff800000 {
>> +                       compatible = "altr,l3regs", "syscon";
>> +                       reg = <0xff800000 0x1000>;
>> +               };
>> +
>>                 mmc: dwmmc0 at ff704000 {
>>                         compatible = "altr,socfpga-dw-mshc";
>>                         reg = <0xff704000 0x1000>;
>> --
>> 2.7.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
From: Rob Herring @ 2017-01-05 16:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <C246CAC1457055469EF09E3A7AC4E11A4A660958@XAP-PVEXMBX01.xlnx.xilinx.com>

On Wed, Jan 4, 2017 at 11:00 AM, Appana Durga Kedareswara Rao
<appana.durga.rao@xilinx.com> wrote:
> Hi Rob,
>
>         Thanks for the review....
>
>> On Wed, Jan 04, 2017 at 07:05:53PM +0530, Kedareswara rao Appana wrote:
>> > When VDMA is configured for more than one frame in the h/w for example
>> > h/w is configured for n number of frames and user Submits n number of
>> > frames and triggered the DMA using issue_pending API.
>> > In the current driver flow we are submitting one frame at a time but
>> > we should submit all the n number of frames at one time as the h/w Is
>> > configured for n number of frames.
>>
>> Please fix run-on sentences, capitalization, and word wrapping.
>
> Sure will fix in the next version....
>
> [Snip]
> -- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
>> > +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
>> > @@ -66,6 +66,8 @@ Optional child node properties:
>> >  Optional child node properties for VDMA:
>> >  - xlnx,genlock-mode: Tells Genlock synchronization is
>> >     enabled/disabled in hardware.
>> > +- xlnx,fstore-config: Tells Whether Frame Store Configuration is
>> > +   enabled/disabled in hardware.
>>
>> What's the default (when not present)? That should be the most common case.
>> Looks like the code treats this as bool, but that's not clear here. The name is not
>> clear what it is doing. Enabling or disabling the feature?
>
> Default value is zero...
> When this property is present it tells hardware is configured for frame store configuration.

So most people will not want "frame store configuration"?

> Will fix the explanation part in the next version like below.
>  xlnx,fstore-config: Tells hardware is configured for frame store configuration.
> Is the above explanation clear???

No, I mean make it obvious from the name of the property:
xlnx,fstore-config-enable or xlnx,fstore-enable

And the description needs to say it is boolean.

Rob

^ permalink raw reply

* [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
From: Maxime Ripard @ 2017-01-05 16:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-2-quentin.schulz@free-electrons.com>

On Mon, Jan 02, 2017 at 05:37:01PM +0100, Quentin Schulz wrote:
> The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
> battery voltage, battery charge and discharge currents, AC-in and VBUS
> voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
> 
> This adds the device tree binding documentation for the X-Powers AXP20X
> and AXP22X PMICs ADCs.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>

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

Thanks,
Maxime

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

^ permalink raw reply

* [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Maxime Ripard @ 2017-01-05 16:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cf4590d1-5381-f1da-7271-e6e7fee0c479@free-electrons.com>

On Thu, Jan 05, 2017 at 10:50:33AM +0100, Quentin Schulz wrote:
> >>>> +static int axp20x_remove(struct platform_device *pdev)
> >>>> +{
> >>>> +       struct axp20x_adc_iio *info;
> >>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >>>> +
> >>>> +       info = iio_priv(indio_dev);
> >>>
> >>> Nit: you could just reverse the 2 declarations above and join this
> >>> line after struct axp20x_adc_iio *info;
> >>>
> >>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> >>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> >>>
> >>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
> >>> and does not check them later on. This means if one were to remove this
> >>> axp20x-adc module, the voltage/current readings in the VBUS power supply
> >>> would be invalid. Some sort of workaround would be needed here in this
> >>> driver of the VBUS driver.
> >>>
> >>
> >> That would be one reason to migrate the VBUS driver to use the IIO
> >> channels, wouldn't it?
> > 
> > It is, preferably without changing the device tree.
> > 
> 
> Yes, of course.

Note that you can have something like a test for the iio channel
property in the VBUS driver, and keep the old behaviour in the case
where we wouldn't have it.

Maxime

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

^ permalink raw reply

* [PATCH V9 3/3] irqchip: qcom: Add IRQ combiner driver
From: Marc Zyngier @ 2017-01-05 16:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481753438-3905-4-git-send-email-agustinv@codeaurora.org>

Hi Agustin,

On 14/12/16 22:10, Agustin Vega-Frias wrote:
> Driver for interrupt combiners in the Top-level Control and Status
> Registers (TCSR) hardware block in Qualcomm Technologies chips.
> 
> An interrupt combiner in this block combines a set of interrupts by
> OR'ing the individual interrupt signals into a summary interrupt
> signal routed to a parent interrupt controller, and provides read-
> only, 32-bit registers to query the status of individual interrupts.
> The status bit for IRQ n is bit (n % 32) within register (n / 32)
> of the given combiner. Thus, each combiner can be described as a set
> of register offsets and the number of IRQs managed.
> 
> Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
> ---
>  drivers/irqchip/Kconfig             |   9 +
>  drivers/irqchip/Makefile            |   1 +
>  drivers/irqchip/qcom-irq-combiner.c | 322 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 332 insertions(+)
>  create mode 100644 drivers/irqchip/qcom-irq-combiner.c
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index bc0af33..3e3430c 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -279,3 +279,12 @@ config EZNPS_GIC
>  config STM32_EXTI
>  	bool
>  	select IRQ_DOMAIN
> +
> +config QCOM_IRQ_COMBINER
> +	bool "QCOM IRQ combiner support"
> +	depends on ARCH_QCOM && ACPI
> +	select IRQ_DOMAIN
> +	select IRQ_DOMAIN_HIERARCHY
> +	help
> +	  Say yes here to add support for the IRQ combiner devices embedded
> +	  in Qualcomm Technologies chips.
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index e4dbfc8..1818a0b 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -74,3 +74,4 @@ obj-$(CONFIG_LS_SCFG_MSI)		+= irq-ls-scfg-msi.o
>  obj-$(CONFIG_EZNPS_GIC)			+= irq-eznps.o
>  obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-vic.o
>  obj-$(CONFIG_STM32_EXTI) 		+= irq-stm32-exti.o
> +obj-$(CONFIG_QCOM_IRQ_COMBINER)		+= qcom-irq-combiner.o
> diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c
> new file mode 100644
> index 0000000..0055e08
> --- /dev/null
> +++ b/drivers/irqchip/qcom-irq-combiner.c
> @@ -0,0 +1,322 @@
> +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +/*
> + * Driver for interrupt combiners in the Top-level Control and Status
> + * Registers (TCSR) hardware block in Qualcomm Technologies chips.
> + * An interrupt combiner in this block combines a set of interrupts by
> + * OR'ing the individual interrupt signals into a summary interrupt
> + * signal routed to a parent interrupt controller, and provides read-
> + * only, 32-bit registers to query the status of individual interrupts.
> + * The status bit for IRQ n is bit (n % 32) within register (n / 32)
> + * of the given combiner. Thus, each combiner can be described as a set
> + * of register offsets and the number of IRQs managed.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/platform_device.h>
> +
> +#define REG_SIZE 32
> +
> +struct combiner_reg {
> +	void __iomem *addr;
> +	unsigned long mask;
> +};
> +
> +struct combiner {
> +	struct irq_domain   *domain;
> +	int                 parent_irq;
> +	u32                 nirqs;
> +	u32                 nregs;
> +	struct combiner_reg regs[0];
> +};
> +
> +static inline u32 irq_register(int irq)
> +{
> +	return irq / REG_SIZE;
> +}
> +
> +static inline u32 irq_bit(int irq)
> +{
> +	return irq % REG_SIZE;
> +
> +}
> +
> +static inline int irq_nr(u32 reg, u32 bit)
> +{
> +	return reg * REG_SIZE + bit;
> +}
> +
> +/*
> + * Handler for the cascaded IRQ.
> + */
> +static void combiner_handle_irq(struct irq_desc *desc)
> +{
> +	struct combiner *combiner = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	u32 reg;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	for (reg = 0; reg < combiner->nregs; reg++) {
> +		int virq;
> +		int hwirq;
> +		u32 bit;
> +		u32 status;
> +
> +		if (combiner->regs[reg].mask == 0)
> +			continue;

I'm a bit worried by this. If I understand it well, this is a pure
software construct (controlled from combiner_irq_chip_{un,}mask_irq) and
there is nothing that actually masks the interrupt at the HW level.

So if a device asserts its interrupt line, what mechanism do we have to
make sure that we don't end-up with the CPU pegged in interrupt context?

> +
> +		status = readl_relaxed(combiner->regs[reg].addr);
> +		status &= combiner->regs[reg].mask;
> +
> +		while (status) {
> +			bit = __ffs(status);
> +			status &= ~(1 << bit);
> +			hwirq = irq_nr(reg, bit);
> +			virq = irq_find_mapping(combiner->domain, hwirq);
> +			if (virq >= 0)

Small bug: virq == 0 shouldn't happen, since this would be an indication
that the hwirq doesn't have a mapping.

> +				generic_handle_irq(virq);
> +
> +		}
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +/*
> + * irqchip callbacks
> + */
> +
> +static void combiner_irq_chip_mask_irq(struct irq_data *data)
> +{
> +	struct combiner *combiner = irq_data_get_irq_chip_data(data);
> +	struct combiner_reg *reg = combiner->regs + irq_register(data->hwirq);
> +
> +	clear_bit(irq_bit(data->hwirq), &reg->mask);
> +}
> +
> +static void combiner_irq_chip_unmask_irq(struct irq_data *data)
> +{
> +	struct combiner *combiner = irq_data_get_irq_chip_data(data);
> +	struct combiner_reg *reg = combiner->regs + irq_register(data->hwirq);
> +
> +	set_bit(irq_bit(data->hwirq), &reg->mask);
> +}
> +
> +static struct irq_chip irq_chip = {
> +	.irq_mask = combiner_irq_chip_mask_irq,
> +	.irq_unmask = combiner_irq_chip_unmask_irq,
> +	.name = "qcom-irq-combiner"
> +};
> +
> +/*
> + * irq_domain_ops callbacks
> + */
> +
> +static int combiner_irq_map(struct irq_domain *domain, unsigned int irq,
> +				   irq_hw_number_t hwirq)
> +{
> +	struct combiner *combiner = domain->host_data;
> +
> +	if (hwirq >= combiner->nirqs)
> +		return -EINVAL;

Given that this should have come from the translate function, can we
move the check there instead, so that we validate everything early?

> +
> +	irq_set_chip_and_handler(irq, &irq_chip, handle_level_irq);
> +	irq_set_chip_data(irq, combiner);
> +	irq_set_noprobe(irq);
> +	return 0;
> +}
> +
> +static void combiner_irq_unmap(struct irq_domain *domain, unsigned int irq)
> +{
> +	struct irq_data *data = irq_get_irq_data(irq);
> +
> +	if (WARN_ON(!data))
> +		return;

Can this happen?

> +	irq_domain_reset_irq_data(data);
> +}
> +
> +static int combiner_irq_translate(struct irq_domain *d, struct irq_fwspec *fws,
> +				  unsigned long *hwirq, unsigned int *type)
> +{
> +	if (is_acpi_node(fws->fwnode)) {
> +		if (WARN_ON((fws->param_count != 2) ||
> +			    (fws->param[1] & IORESOURCE_IRQ_LOWEDGE) ||
> +			    (fws->param[1] & IORESOURCE_IRQ_HIGHEDGE)))
> +			return -EINVAL;
> +
> +		*hwirq = fws->param[0];
> +		*type = fws->param[1];
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct irq_domain_ops domain_ops = {
> +	.map = combiner_irq_map,
> +	.unmap = combiner_irq_unmap,
> +	.translate = combiner_irq_translate
> +};
> +
> +/*
> + * Device probing
> + */
> +
> +static acpi_status count_registers_cb(struct acpi_resource *ares, void *context)
> +{
> +	int *count = context;
> +
> +	if (ares->type == ACPI_RESOURCE_TYPE_GENERIC_REGISTER)
> +		++(*count);
> +	return AE_OK;
> +}
> +
> +static int count_registers(struct platform_device *pdev)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
> +	acpi_status status;
> +	int count = 0;
> +
> +	if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
> +		return -EINVAL;
> +
> +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +				     count_registers_cb, &count);
> +	if (ACPI_FAILURE(status))
> +		return -EINVAL;
> +	return count;
> +}
> +
> +struct get_registers_context {
> +	struct device *dev;
> +	struct combiner *combiner;
> +	int err;
> +};
> +
> +static acpi_status get_registers_cb(struct acpi_resource *ares, void *context)
> +{
> +	struct get_registers_context *ctx = context;
> +	struct acpi_resource_generic_register *reg;
> +	phys_addr_t paddr;
> +	void __iomem *vaddr;
> +
> +	if (ares->type != ACPI_RESOURCE_TYPE_GENERIC_REGISTER)
> +		return AE_OK;
> +
> +	reg = &ares->data.generic_reg;
> +	paddr = reg->address;
> +	if ((reg->space_id != ACPI_SPACE_MEM) ||
> +	    (reg->bit_offset != 0) ||
> +	    (reg->bit_width > REG_SIZE)) {
> +		dev_err(ctx->dev, "Bad register resource @%pa\n", &paddr);
> +		ctx->err = -EINVAL;
> +		return AE_ERROR;
> +	}
> +
> +	vaddr = devm_ioremap(ctx->dev, reg->address, REG_SIZE);
> +	if (IS_ERR(vaddr)) {
> +		dev_err(ctx->dev, "Can't map register @%pa\n", &paddr);
> +		ctx->err = PTR_ERR(vaddr);
> +		return AE_ERROR;
> +	}
> +
> +	ctx->combiner->regs[ctx->combiner->nregs].addr = vaddr;
> +	ctx->combiner->nirqs += reg->bit_width;
> +	ctx->combiner->nregs++;
> +	return AE_OK;
> +}
> +
> +static int get_registers(struct platform_device *pdev, struct combiner *comb)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
> +	acpi_status status;
> +	struct get_registers_context ctx;
> +
> +	if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
> +		return -EINVAL;
> +
> +	ctx.dev = &pdev->dev;
> +	ctx.combiner = comb;
> +	ctx.err = 0;
> +
> +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +				     get_registers_cb, &ctx);
> +	if (ACPI_FAILURE(status))
> +		return ctx.err;
> +	return 0;
> +}
> +
> +static int __init combiner_probe(struct platform_device *pdev)
> +{
> +	struct combiner *combiner;
> +	size_t alloc_sz;
> +	u32 nregs;
> +	int err;
> +
> +	nregs = count_registers(pdev);
> +	if (nregs <= 0) {
> +		dev_err(&pdev->dev, "Error reading register resources\n");
> +		return -EINVAL;
> +	}
> +
> +	alloc_sz = sizeof(*combiner) + sizeof(struct combiner_reg) * nregs;
> +	combiner = devm_kzalloc(&pdev->dev, alloc_sz, GFP_KERNEL);
> +	if (!combiner)
> +		return -ENOMEM;
> +
> +	err = get_registers(pdev, combiner);
> +	if (err < 0)
> +		return err;
> +
> +	combiner->parent_irq = platform_get_irq(pdev, 0);
> +	if (combiner->parent_irq <= 0) {
> +		dev_err(&pdev->dev, "Error getting IRQ resource\n");
> +		return -EPROBE_DEFER;
> +	}
> +
> +	combiner->domain = irq_domain_create_linear(pdev->dev.fwnode, combiner->nirqs,
> +						    &domain_ops, combiner);
> +	if (!combiner->domain)
> +		/* Errors printed by irq_domain_create_linear */
> +		return -ENODEV;
> +
> +	irq_set_chained_handler_and_data(combiner->parent_irq,
> +					 combiner_handle_irq, combiner);
> +
> +	dev_info(&pdev->dev, "Initialized with [p=%d,n=%d,r=%p]\n",
> +		 combiner->parent_irq, combiner->nirqs, combiner->regs[0].addr);
> +	return 0;
> +}
> +
> +static const struct acpi_device_id qcom_irq_combiner_acpi_match[] = {
> +	{ "QCOM80B1", },
> +	{ }
> +};
> +
> +static struct platform_driver qcom_irq_combiner_probe = {
> +	.driver = {
> +		.name = "qcom-irq-combiner",
> +		.owner = THIS_MODULE,
> +		.acpi_match_table = ACPI_PTR(qcom_irq_combiner_acpi_match),
> +	},
> +	.probe = combiner_probe,
> +};
> +
> +static int __init register_qcom_irq_combiner(void)
> +{
> +	return platform_driver_register(&qcom_irq_combiner_probe);
> +}
> +device_initcall(register_qcom_irq_combiner);
> 

Other than the questions I have above, this now looks in a much better
shape. Hopefully Rafael will soon come back will his conclusions on the
first two patches, as I'd like to see this code to get some -next for a
while.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Maxime Ripard @ 2017-01-05 16:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-4-quentin.schulz@free-electrons.com>

On Mon, Jan 02, 2017 at 05:37:03PM +0100, Quentin Schulz wrote:
> +	switch (axp20x_id) {
> +	case AXP209_ID:
> +		indio_dev->info = &axp20x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> +		indio_dev->channels = axp20x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> +		/* Enable GPIO0/1 and internal temperature ADCs */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> +				   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
> +		break;
> +
> +	case AXP221_ID:
> +		indio_dev->info = &axp22x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> +		indio_dev->channels = axp22x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}

I'm not a big fan of those IDs. It always ends up with a ever
increasing list of cases without any consolidation.

In this case, the only thing you need is a list of pointers and values
that can definitely be stored in a structure.

Maxime

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

^ permalink raw reply

* [PATCH v2 0/3] ARM: dts: dra7-evm: pinmuxing updates
From: Tony Lindgren @ 2017-01-05 16:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1481628266.git.nsekhar@ti.com>

* Sekhar Nori <nsekhar@ti.com> [161213 03:30]:
> Hi,
> 
> This patch series drops most of the pinmuxing from dra7-evm
> to satisfy erratum i869 and adds missing eMMC and SD card pinmuxing.
> 
> The patches apply to latest linux-next. Tested on DRA74x EVM Rev H
> using U-Boot 2016.11. Boot tested using NFS and basic testing carried
> out on SD card, eMMC, Audio capture and playback.
> 
> NAND on DRA72 EVM is already unusable due to a similar patch. A patch
> included here disables the GPMC node.
> 
> v1 -> v2:
> - Add a patch to disable GPMC node on DRA72x EVM
> - Disable GPMC node on DRA74x EVM
> 
> Kishon Vijay Abraham I (1):
>   ARM: dts: dra7-evm: add pinmux configuration for mmc1/2
> 
> Sekhar Nori (2):
>   ARM: dts: dra7-evm: Remove pinmux configurations for erratum i869
>   ARM: dts: dra72-evm: drop NAND support
> 
>  arch/arm/boot/dts/dra7-evm.dts          | 282 ++++----------------------------
>  arch/arm/boot/dts/dra72-evm-common.dtsi |   7 +-
>  2 files changed, 35 insertions(+), 254 deletions(-)

Applying all into omap-for-v4.11/dt thanks.

Tony

^ permalink raw reply

* [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Maxime Ripard @ 2017-01-05 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-18-quentin.schulz@free-electrons.com>

On Mon, Jan 02, 2017 at 05:37:17PM +0100, Quentin Schulz wrote:
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives ?V.
> +		 */
> +		val->intval *= 1000;

s/gives/wants/ ?

> +static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +					  int val)
> +{
> +	switch (val) {
> +	case 4100000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_1V);
> +	case 4150000:
> +		if (axp20x_batt->axp_id == AXP221_ID)
> +			return -EINVAL;
> +
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_15V);
> +	case 4200000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_2V);
> +	default:
> +		/*
> +		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
> +		 * can be set to 4.22V and 4.24V, but these voltages are too
> +		 * high for Lithium based batteries (AXP PMICs are supposed to
> +		 * be used with these kinds of battery).
> +		 */
> +		return -EINVAL;
> +	}

Since all your calls to regmap are the same, something like:

case 4100000:
	val = AXP20X_CHRG_CTRL1_TGT_4_1V;
	break;

case 4150000:
	val = AXP20X_CHRG_CTRL1_TGT_4_15V;
	break;

regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
		   AXP20X_CHRG_CTRL1_TGT_VOLT, val);


It would also get rid of your warnings in checkpatch.

Maxime

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

^ permalink raw reply

* [PATCH v3 1/9] arm64: cpufeature: treat unknown fields as RES0
From: Catalin Marinas @ 2017-01-05 17:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483552147-9605-2-git-send-email-suzuki.poulose@arm.com>

On Wed, Jan 04, 2017 at 05:48:59PM +0000, Suzuki K. Poulose wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> Any fields not defined in an arm64_ftr_bits entry are propagated to the
> system-wide register value in init_cpu_ftr_reg(), and while we require
> that these strictly match for the sanity checks, we don't update them in
> update_cpu_ftr_reg().
> 
> Generally, the lack of an arm64_ftr_bits entry indicates that the bits
> are currently RES0 (as is the case for the upper 32 bits of all
> supposedly 32-bit registers).
> 
> A better default would be to use zero for the system-wide value of
> unallocated bits, making all register checking consistent, and allowing
> for subsequent simplifications to the arm64_ftr_bits arrays.
> 
> This patch updates init_cpu_ftr_reg() to treat unallocated bits as RES0
> for the purpose of the system-wide safe value. These bits will still be
> sanity checked with strict match requirements, as is currently the case.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v3 2/9] arm64: cpufeature: remove explicit RAZ fields
From: Catalin Marinas @ 2017-01-05 17:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483552147-9605-3-git-send-email-suzuki.poulose@arm.com>

On Wed, Jan 04, 2017 at 05:49:00PM +0000, Suzuki K. Poulose wrote:
> From: Mark Rutland <mark.rutland@arm.com>
> 
> We currently have some RAZ fields described explicitly in our
> arm64_ftr_bits arrays. These are inconsistently commented, grouped,
> and/or applied, and maintaining these is error-prone.
> 
> Luckily, we don't need these at all. We'll never need to inspect RAZ
> fields to determine feature support, and init_cpu_ftr_reg() will ensure
> that any bits without a corresponding arm64_ftr_bits entry are treated
> as RES0 with strict matching requirements. In check_update_ftr_reg()
> we'll then compare these bits from the relevant cpuinfo_arm64
> structures, and need not store them in a arm64_ftr_reg.
> 
> This patch removes the unnecessary arm64_ftr_bits entries for RES0 bits.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v2 4/4] ARM: dts: keystone: Add "ti, da830-uart" compatible string
From: Santosh Shilimkar @ 2017-01-05 17:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <824238e0-b710-7146-b67b-b2135c2a8bd2@ti.com>

On 1/5/2017 1:04 AM, Sekhar Nori wrote:
> Hi Santosh,
>
> On Thursday 05 January 2017 03:30 AM, Santosh Shilimkar wrote:
>> On 1/4/2017 12:30 PM, David Lechner wrote:
>>> The TI Keystone SoCs have extra UART registers beyond the standard 8250
>>> registers, so we need a new compatible string to indicate this. Also, at
>>> least one of these registers uses the full 32 bits, so we need to specify
>>> reg-io-width in addition to reg-shift.
>>>
>>> "ns16550a" is left in the compatible specification since it does work as
>>> long as the bootloader configures the SoC UART power management
>>> registers.
>>>
>> NAK!!
>> We can't break the booting boards with existing boot loaders.
>
> Sorry, but it not clear to me how this breaks booting with older
> bootloaders? If older DTB is ROM'ed, it will continue to work because of
> match with ns16550a.
>
> I just verified boot on K2E with these patches applied and using 2016.05
> based U-Boot from a TI release.
>
> http://pastebin.ubuntu.com/23744719/
>
Thanks for test. As long as it doesn't break the boot, am fine
with it.

>> I suggest you to first get the driver updated to take care of
>> the UART PM register and then enable the support for it.
>
> Isn't that what patch 2/4 is doing?
>
I see that now. Thanks for clarifying.

Serial patch needs to go via Greg's tree. I will pick up the
DTS bits.

Regards,
Santosh

^ 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