Devicetree
 help / color / mirror / Atom feed
* Re: [PATCHv1 0/2] Convert rx51-battery to IIO API and add DT support
From: Sebastian Reichel @ 2014-02-26 17:51 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Dmitry Eremin-Solenikov, David Woodhouse, Jonathan Cameron,
	Marek Belisko, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, LKML,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-iio-u79uwXL29TY76Z2rM5mHXA, Ivajlo Dimitrov
In-Reply-To: <CAHYPw2EeEnDn2FUYSMWbywprmhJmcRRyaTPn1YZK0xPvuiJQFw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2803 bytes --]

Hi Pali,

On Wed, Feb 26, 2014 at 08:40:54AM +0100, Pali Rohár wrote:
> I would like to ask other kernel developers what do you think about
> moving ADC channel numbers from rx51_battery.ko driver code to DT.
> Driver rx51_battery.ko is platform specific for Nokia RX-51 (N900) so
> it is usefull only for this one device.
> 
> Before this patch all driver data (look-up tables, adc channel
> numbers, etc...) were in driver code. Now after this patch adc channel
> numbers were moved to DT. What do you think? It is better to have all
> data in one place (driver code) or some in DT and some in driver code?
> 
> For me it does not make sense to move these numbers to DT, because
> driver is rx51 device specific and chaning it in DT does not make
> sense. And I think it is better to have add driver data in one place
> and not in two...
> 
> Sebastian already wrote me that this is normal to have numbers in DT
> and other code in driver. But I think that driver which can be used
> only in one device (so specified only in one DT file) does not need to
> have configuration (via DT or board files).
>
> Or do you think that driver specified only for one device needs to
> have ADC numbers configuration via DT?

I think the problem is, that you think of ADC channel numbers as
configuration data. This means you think of rx51-battery as an
alternative driver for the twl4030-madc.

I think of rx51-battery as its own platform device, which makes use
of the ADC similar to a button making use of a GPIO chip.
For me the ADC channel numbers are not configuration data, but an
inter-device resource reference, like e.g. GPIO references.
This is exactly the data you would put into the device tree.

Now let's take the rx51-audio device as another example for an n900
specific device (not yet in mainline kernel). It does not need ADC
channels, but GPIO lines:

	sound: n900-audio {
		/* ... some more references ... */
		nokia,tvout-selection-gpio = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */
		nokia,jack-detection-gpio = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */
		nokia,eci-switch-gpio = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */
		nokia,speaker-amplifier-gpio = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
	};

Since GPIO numbers are not guaranteed to be consistent in DT boot
mode at least the GPIO chip must be referenced. Do you really think
it's a good idea to leave out the exact GPIO number just because
the driver knows it needs the 8th GPIO from the second GPIO chip?
IMHO this is really ugly, since it splits the information, which
GPIO is used into two parts - one living in the DT and one living
in the driver with no advantage at all. So it does make sense to
specify inter-device resources via DT even for platform specific
devices.

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCHv2 14/16] ARM: OMAP3: hwmod data: cleanup data for IOMMUs
From: Tony Lindgren @ 2014-02-26 17:18 UTC (permalink / raw)
  To: Suman Anna
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Laurent Pinchart, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	Florian Vaussard
In-Reply-To: <1392315347-32967-15-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>

* Suman Anna <s-anna-l0cyMroinI0@public.gmane.org> [140213 10:19]:
> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> 
> The irq numbers, ocp address space and device attribute data
> have all been cleaned up for OMAP3 IOMMUs. All this data is
> populated via the corresponding dt node.
> 
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>

This will need to wait until we've made omap3 to be DT only
as this will break idling of things for the legacy booting.

Regards,

Tony

> ---
>  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 46 ------------------------------
>  1 file changed, 46 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index 9c7e23a..d68c131 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -24,7 +24,6 @@
>  #include "l4_3xxx.h"
>  #include <linux/platform_data/asoc-ti-mcbsp.h>
>  #include <linux/platform_data/spi-omap2-mcspi.h>
> -#include <linux/platform_data/iommu-omap.h>
>  #include <linux/platform_data/mailbox-omap.h>
>  #include <plat/dmtimer.h>
>  
> @@ -2991,83 +2990,39 @@ static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = {
>  
>  /* mmu isp */
>  
> -static struct omap_mmu_dev_attr mmu_isp_dev_attr = {
> -	.da_start	= 0x0,
> -	.da_end		= 0xfffff000,
> -	.nr_tlb_entries = 8,
> -};
> -
>  static struct omap_hwmod omap3xxx_mmu_isp_hwmod;
> -static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = {
> -	{ .irq = 24 + OMAP_INTC_START, },
> -	{ .irq = -1 }
> -};
> -
> -static struct omap_hwmod_addr_space omap3xxx_mmu_isp_addrs[] = {
> -	{
> -		.pa_start	= 0x480bd400,
> -		.pa_end		= 0x480bd47f,
> -		.flags		= ADDR_TYPE_RT,
> -	},
> -	{ }
> -};
>  
>  /* l4_core -> mmu isp */
>  static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmu_isp = {
>  	.master		= &omap3xxx_l4_core_hwmod,
>  	.slave		= &omap3xxx_mmu_isp_hwmod,
> -	.addr		= omap3xxx_mmu_isp_addrs,
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
>  static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
>  	.name		= "mmu_isp",
>  	.class		= &omap3xxx_mmu_hwmod_class,
> -	.mpu_irqs	= omap3xxx_mmu_isp_irqs,
>  	.main_clk	= "cam_ick",
> -	.dev_attr	= &mmu_isp_dev_attr,
>  	.flags		= HWMOD_NO_IDLEST,
>  };
>  
>  /* mmu iva */
>  
> -static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
> -	.da_start	= 0x11000000,
> -	.da_end		= 0xfffff000,
> -	.nr_tlb_entries = 32,
> -};
> -
>  static struct omap_hwmod omap3xxx_mmu_iva_hwmod;
> -static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = {
> -	{ .irq = 28 + OMAP_INTC_START, },
> -	{ .irq = -1 }
> -};
> -
>  static struct omap_hwmod_rst_info omap3xxx_mmu_iva_resets[] = {
>  	{ .name = "mmu", .rst_shift = 1, .st_shift = 9 },
>  };
>  
> -static struct omap_hwmod_addr_space omap3xxx_mmu_iva_addrs[] = {
> -	{
> -		.pa_start	= 0x5d000000,
> -		.pa_end		= 0x5d00007f,
> -		.flags		= ADDR_TYPE_RT,
> -	},
> -	{ }
> -};
> -
>  /* l3_main -> iva mmu */
>  static struct omap_hwmod_ocp_if omap3xxx_l3_main__mmu_iva = {
>  	.master		= &omap3xxx_l3_main_hwmod,
>  	.slave		= &omap3xxx_mmu_iva_hwmod,
> -	.addr		= omap3xxx_mmu_iva_addrs,
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
>  static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
>  	.name		= "mmu_iva",
>  	.class		= &omap3xxx_mmu_hwmod_class,
> -	.mpu_irqs	= omap3xxx_mmu_iva_irqs,
>  	.clkdm_name	= "iva2_clkdm",
>  	.rst_lines	= omap3xxx_mmu_iva_resets,
>  	.rst_lines_cnt	= ARRAY_SIZE(omap3xxx_mmu_iva_resets),
> @@ -3080,7 +3035,6 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
>  			.idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
>  		},
>  	},
> -	.dev_attr	= &mmu_iva_dev_attr,
>  	.flags		= HWMOD_NO_IDLEST,
>  };
>  
> -- 
> 1.8.5.3
> 

^ permalink raw reply

* Re: [PATCHv2 10/16] ARM: OMAP2+: use pdata quirks for iommu reset lines
From: Tony Lindgren @ 2014-02-26 17:17 UTC (permalink / raw)
  To: Suman Anna
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Laurent Pinchart, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	Florian Vaussard
In-Reply-To: <1392315347-32967-11-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>

* Suman Anna <s-anna-l0cyMroinI0@public.gmane.org> [140213 10:19]:
> The OMAP iommu driver performs the reset management for the
> iommu instances in processor sub-systems using the omap_device
> API which are currently supplied as platform data ops. Use pdata
> quirks to maintain the functionality as the OMAP iommu driver
> gets converted to use DT nodes, until the reset portions are
> decoupled from omap_hwmod/omap_device into a separate reset
> driver.
> 
> This patch adds the pdata quirks for the reset management of
> iommus within the DSP (OMAP3 & OMAP4) and IPU subsystems (OMAP4).
> 
> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>

Looks OK, but I suggest you separate out the remaining patches in
this series into another clean-up series. Then the clean-up series
can be merged later on as these have a good chance of conflicting
with other stuff.

Tony

> ---
>  arch/arm/mach-omap2/pdata-quirks.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
> index 3d5b24d..74e094a 100644
> --- a/arch/arm/mach-omap2/pdata-quirks.c
> +++ b/arch/arm/mach-omap2/pdata-quirks.c
> @@ -16,12 +16,14 @@
>  #include <linux/wl12xx.h>
>  
>  #include <linux/platform_data/pinctrl-single.h>
> +#include <linux/platform_data/iommu-omap.h>
>  
>  #include "am35xx.h"
>  #include "common.h"
>  #include "common-board-devices.h"
>  #include "dss-common.h"
>  #include "control.h"
> +#include "omap_device.h"
>  
>  struct pdata_init {
>  	const char *compatible;
> @@ -92,6 +94,12 @@ static void __init hsmmc2_internal_input_clk(void)
>  	omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1);
>  }
>  
> +static struct iommu_platform_data omap3_iommu_pdata = {
> +	.reset_name = "mmu",
> +	.assert_reset = omap_device_assert_hardreset,
> +	.deassert_reset = omap_device_deassert_hardreset,
> +};
> +
>  static int omap3_sbc_t3730_twl_callback(struct device *dev,
>  					   unsigned gpio,
>  					   unsigned ngpio)
> @@ -185,6 +193,12 @@ static void __init omap4_panda_legacy_init(void)
>  	legacy_init_ehci_clk("auxclk3_ck");
>  	legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53);
>  }
> +
> +static struct iommu_platform_data omap4_iommu_pdata = {
> +	.reset_name = "mmu_cache",
> +	.assert_reset = omap_device_assert_hardreset,
> +	.deassert_reset = omap_device_deassert_hardreset,
> +};
>  #endif
>  
>  #ifdef CONFIG_SOC_OMAP5
> @@ -240,6 +254,8 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
>  #ifdef CONFIG_ARCH_OMAP3
>  	OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
>  	OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
> +	OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
> +		       &omap3_iommu_pdata),
>  	/* Only on am3517 */
>  	OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
>  	OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
> @@ -248,6 +264,10 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
>  #ifdef CONFIG_ARCH_OMAP4
>  	OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
>  	OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
> +	OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
> +		       &omap4_iommu_pdata),
> +	OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
> +		       &omap4_iommu_pdata),
>  #endif
>  	{ /* sentinel */ },
>  };
> -- 
> 1.8.5.3
> 

^ permalink raw reply

* Re: [PATCHv2 08/16] ARM: OMAP3: remove deprecated CONFIG_OMAP_IOMMU_IVA2
From: Tony Lindgren @ 2014-02-26 17:15 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Suman Anna, Joerg Roedel, Florian Vaussard, iommu, devicetree,
	linux-omap, linux-arm-kernel, Paul Walmsley
In-Reply-To: <1488816.z8hE0Kk16e@avalon>

* Laurent Pinchart <laurent.pinchart@ideasonboard.com> [140225 13:18]:
> On Thursday 13 February 2014 12:15:39 Suman Anna wrote:
> > From: Florian Vaussard <florian.vaussard@epfl.ch>
> > 
> > CONFIG_OMAP_IOMMU_IVA2 was defined originally to avoid conflicting
> > usage by tidspbridge and other iommu users. The same can be achieved
> > by marking the DT node disabled, so remove this obsolete flag and
> > the corresponding hwmod data can be enabled.
> > 
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
> > [s-anna@ti.com: revise commit log]
> > Signed-off-by: Suman Anna <s-anna@ti.com>
> 
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply

* Re: [PATCHv2 08/16] ARM: OMAP3: remove deprecated CONFIG_OMAP_IOMMU_IVA2
From: Tony Lindgren @ 2014-02-26 17:09 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Suman Anna, Joerg Roedel, Florian Vaussard, iommu, devicetree,
	linux-omap, linux-arm-kernel, Paul Walmsley
In-Reply-To: <1488816.z8hE0Kk16e@avalon>

* Laurent Pinchart <laurent.pinchart@ideasonboard.com> [140225 13:18]:
> On Thursday 13 February 2014 12:15:39 Suman Anna wrote:
> > From: Florian Vaussard <florian.vaussard@epfl.ch>
> > 
> > CONFIG_OMAP_IOMMU_IVA2 was defined originally to avoid conflicting
> > usage by tidspbridge and other iommu users. The same can be achieved
> > by marking the DT node disabled, so remove this obsolete flag and
> > the corresponding hwmod data can be enabled.
> > 
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
> > [s-anna@ti.com: revise commit log]
> > Signed-off-by: Suman Anna <s-anna@ti.com>
> 
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply

* Re: [PATCHv2 04/16] iommu/omap: add devicetree support
From: Tony Lindgren @ 2014-02-26 17:08 UTC (permalink / raw)
  To: Suman Anna
  Cc: Joerg Roedel, Florian Vaussard, Laurent Pinchart, iommu,
	devicetree, linux-omap, linux-arm-kernel
In-Reply-To: <1392315347-32967-5-git-send-email-s-anna@ti.com>

* Suman Anna <s-anna@ti.com> [140213 10:19]:
> From: Florian Vaussard <florian.vaussard@epfl.ch>
> 
> As OMAP2+ is moving to a full DT boot for all SoC families, commit
> 7ce93f3 "ARM: OMAP2+: Fix more missing data for omap3.dtsi file"
> adds basic DT bits for OMAP3. But the driver is not yet converted,
> so this will not work and driver will not be probed. Convert it!
> 
> Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
> [s-anna@ti.com: dev_name adaptation and improved error checking]
> Signed-off-by: Suman Anna <s-anna@ti.com>

Best that this gets merged along with the other iommu patches, so
for the arch/arm/*omap* parts:

Acked-by: Tony Lindgren <tony@atomide.com>

> ---
>  arch/arm/mach-omap2/omap-iommu.c |  5 +++++
>  drivers/iommu/omap-iommu.c       | 41 ++++++++++++++++++++++++++++++++++++----
>  2 files changed, 42 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
> index f6daae8..f1fab56 100644
> --- a/arch/arm/mach-omap2/omap-iommu.c
> +++ b/arch/arm/mach-omap2/omap-iommu.c
> @@ -10,6 +10,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/of.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/err.h>
> @@ -58,6 +59,10 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
>  
>  static int __init omap_iommu_init(void)
>  {
> +	/* If dtb is there, the devices will be created dynamically */
> +	if (of_have_populated_dt())
> +		return -ENODEV;
> +
>  	return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
>  }
>  /* must be ready before omap3isp is probed */
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index 6272c36..4329ab1 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -23,6 +23,9 @@
>  #include <linux/spinlock.h>
>  #include <linux/io.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/of.h>
> +#include <linux/of_iommu.h>
> +#include <linux/of_irq.h>
>  
>  #include <asm/cacheflush.h>
>  
> @@ -937,20 +940,41 @@ static int omap_iommu_probe(struct platform_device *pdev)
>  {
>  	int err = -ENODEV;
>  	int irq;
> +	size_t len;
>  	struct omap_iommu *obj;
>  	struct resource *res;
>  	struct iommu_platform_data *pdata = pdev->dev.platform_data;
> +	struct device_node *of = pdev->dev.of_node;
>  
>  	obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
>  	if (!obj)
>  		return -ENOMEM;
>  
> -	obj->nr_tlb_entries = pdata->nr_tlb_entries;
> -	obj->name = pdata->name;
> +	if (of) {
> +		obj->name = dev_name(&pdev->dev);
> +		obj->nr_tlb_entries = 32;
> +		err = of_property_read_u32(of, "ti,#tlb-entries",
> +					   &obj->nr_tlb_entries);
> +		if (err && err != -EINVAL)
> +			return err;
> +		if (obj->nr_tlb_entries != 32 && obj->nr_tlb_entries != 8)
> +			return -EINVAL;
> +		err = of_get_dma_window(of, NULL, 0, NULL, &obj->da_start,
> +					&len);
> +		if (err != 0)
> +			return err;
> +		obj->da_end = obj->da_start + len;
> +	} else {
> +		obj->nr_tlb_entries = pdata->nr_tlb_entries;
> +		obj->name = pdata->name;
> +		obj->da_start = pdata->da_start;
> +		obj->da_end = pdata->da_end;
> +	}
> +	if (obj->da_end <= obj->da_start)
> +		return -EINVAL;
> +
>  	obj->dev = &pdev->dev;
>  	obj->ctx = (void *)obj + sizeof(*obj);
> -	obj->da_start = pdata->da_start;
> -	obj->da_end = pdata->da_end;
>  
>  	spin_lock_init(&obj->iommu_lock);
>  	mutex_init(&obj->mmap_lock);
> @@ -991,11 +1015,20 @@ static int omap_iommu_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static struct of_device_id omap_iommu_of_match[] = {
> +	{ .compatible = "ti,omap2-iommu" },
> +	{ .compatible = "ti,omap4-iommu" },
> +	{ .compatible = "ti,dra7-iommu"	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, omap_iommu_of_match);
> +
>  static struct platform_driver omap_iommu_driver = {
>  	.probe	= omap_iommu_probe,
>  	.remove	= omap_iommu_remove,
>  	.driver	= {
>  		.name	= "omap-iommu",
> +		.of_match_table = of_match_ptr(omap_iommu_of_match),
>  	},
>  };
>  
> -- 
> 1.8.5.3
> 

^ permalink raw reply

* Re: [Patch v7 2/2] dmaengine: add Qualcomm BAM dma driver
From: Andy Gross @ 2014-02-26 17:06 UTC (permalink / raw)
  To: Stanimir Varbanov
  Cc: Vinod Koul, Dan Williams, dmaengine, linux-kernel,
	linux-arm-kernel, linux-arm-msm, devicetree
In-Reply-To: <530E1BAB.6040609@mm-sol.com>

On Wed, Feb 26, 2014 at 06:51:55PM +0200, Stanimir Varbanov wrote:
> > +	/* read revision and configuration information */
> > +	val = readl_relaxed(bdev->regs + BAM_REVISION) & NUM_EES_MASK;
> > +
> 
> The ees shit is not zero and you got wrong ee. Could you add the line
> below or something similar:
> 
> val = (val >> NUM_EES_SHIFT) & NUM_EES_MASK;
> 

Good catch.  I missed the shift when I reworked and got lucky that the revision
is in the lower 8 bits and is non-zero.

-- 
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* Re: [PATCHv2 03/16] Documentation: dt: add OMAP iommu bindings
From: Suman Anna @ 2014-02-26 17:02 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Rob Herring,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Kumar Gala,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1552997.8jd4jgn3Ze@avalon>

Hi Laurent,

On 02/25/2014 08:13 PM, Laurent Pinchart wrote:
> Hi Suman,
>
> On Tuesday 25 February 2014 17:02:35 Suman Anna wrote:
>> On 02/25/2014 03:26 PM, Laurent Pinchart wrote:
>>> On Thursday 13 February 2014 12:15:34 Suman Anna wrote:
>>>> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>>>
>>>> This patch adds the iommu bindings for all OMAP2+ SoCs. Apart from
>>>> the standard bindings used by OMAP peripherals, this patch uses a
>>>> 'dma-window' (already used by Tegra SMMU) and adds two OMAP custom
>>>> bindings - 'ti,#tlb-entries' and 'ti,iommu-bus-err-back'.
>>>>
>>>> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>>> [s-anna-l0cyMroinI0@public.gmane.org: split bindings document, add dra7 and bus error back]
>>>> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
>>>> ---
>>>>
>>>>    .../devicetree/bindings/iommu/ti,omap-iommu.txt    | 28
>>>>    +++++++++++++++++++
>>>>    1 file changed, 28 insertions(+)
>>>>    create mode 100644
>>>>    Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>>>> b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt new file mode
>>>> 100644
>>>> index 0000000..116492d
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>>>> @@ -0,0 +1,28 @@
>>>> +OMAP2+ IOMMU
>>>> +
>>>> +Required properties:
>>>> +- compatible : Should be one of,
>>>> +		"ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances
>>>> +		"ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances
>>>> +		"ti,dra7-iommu" for DRA7xx IOMMU instances
>>>> +- ti,hwmods  : Name of the hwmod associated with the IOMMU instance
>>>> +- reg        : Address space for the configuration registers
>>>> +- interrupts : Interrupt specifier for the IOMMU instance
>>>> +- dma-window : IOVA start address and length
>>>
>>> Isn't the dma window more of a system configuration property than a
>>> hardware property ? How do you expect it to be set?
>>
>> We are setting it based on the addressable range for the MMU.
>
> A quick look at the ISP and IVA IOMMUs in the OMAP3 shows that both support
> the full 4GB VA space. Why do you need to restrict it ?

I should have rephrased it better when I said addressable range. While 
the MMUs are capable of programming the full 4GB space, there are some 
address ranges that are private from the processor view. This window is 
currently used to set the range for the omap-iovmm driver (which only 
OMAP3 ISP is using atm), and there is no point in allowing the 
omap-iovmm driver the full range when the processor could never 
reach/access those addresses.

>
>> We are reusing the existing defined property and it allows us to get rid of
>> the IOVA start and end addresses defined in the pre-DT OMAP iommu platform
>> data.
>>
>>>> +Optional properties:
>>>> +- ti,#tlb-entries : Number of entries in the translation look-aside
>>>> buffer. +                    Should be either 8 or 32 (default: 32)
>>>> +- ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing
>>>> +		          back a bus error response on MMU faults.
>>>
>>> Do these features vary per IOMMU instance or per IOMMU model ? In the
>>> latter case they could be inferred from the compatible string by the
>>> driver without requiring them to be explicit in DT (whether you want to
>>> do so is left to you though).
>>
>> Well, these are fixed features given an IOMMU instance, like the OMAP3
>> ISP is the only one that has 8 TLB entries, all the remaining ones have
>> 32, and the IPU iommu instances are the only ones that support the bus
>> error response back. I have no preference to any particular way, and
>> sure the driver can infer these easily based on unique compatible
>> strings per subsystem per SoC. I just happened to go with defining
>> compatible strings per SoC, with the optional properties differentiating
>> the fixed behavior between different IOMMU instances on that SoC. This
>> is where I was looking for some inputs/guidance from the DT bindings
>> maintainers on what is the preferred method.
>
> I think you've made the right choice. I wasn't sure whether those parameters
> varied across IOMMU instances of compatible devices (from a compatible string
> point of view) or were constant. As they vary they should be expressed in DT.

Yeah, I wasn't sure if these qualify as features (as per 
Documentation/devicetree/bindings/ABI.txt section II.2).

regards
Suman

>
>>>> +Example:
>>>> +	/* OMAP3 ISP MMU */
>>>> +	mmu_isp: mmu@480bd400 {
>>>> +		compatible = "ti,omap2-iommu";
>>>> +		reg = <0x480bd400 0x80>;
>>>> +		interrupts = <24>;
>>>> +		ti,hwmods = "mmu_isp";
>>>> +		ti,#tlb-entries = <8>;
>>>> +		dma-window = <0 0xfffff000>;
>>>> +	};
>

^ permalink raw reply

* Re: [PATCH RESEND v11 6/7] ARM: OMAP: enable SYSCON and REGULATOR_PBIAS in omap2plus_defconfig
From: Tony Lindgren @ 2014-02-26 17:01 UTC (permalink / raw)
  To: Balaji T K; +Cc: linux-omap, bcousson, devicetree, linux-mmc, chris, broonie
In-Reply-To: <1392821801-29673-7-git-send-email-balajitk@ti.com>

* Balaji T K <balajitk@ti.com> [140219 07:00]:
> Enable REGULATOR_PBIAS needed for SD card on most OMAPs.
> 
> Signed-off-by: Balaji T K <balajitk@ti.com>

I belive this is the only one missing my ack:

Acked-by: Tony Lindgren <tony@atomide.com>

Probably best that this all gets queued along with other MMC related
patches by Balaji and Chris.

> ---
>  arch/arm/configs/omap2plus_defconfig |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
> index 3a0b53d..e4fec1c 100644
> --- a/arch/arm/configs/omap2plus_defconfig
> +++ b/arch/arm/configs/omap2plus_defconfig
> @@ -169,6 +169,7 @@ CONFIG_DRA752_THERMAL=y
>  CONFIG_WATCHDOG=y
>  CONFIG_OMAP_WATCHDOG=y
>  CONFIG_TWL4030_WATCHDOG=y
> +CONFIG_MFD_SYSCON=y
>  CONFIG_MFD_PALMAS=y
>  CONFIG_MFD_TPS65217=y
>  CONFIG_MFD_TPS65910=y
> @@ -180,6 +181,7 @@ CONFIG_REGULATOR_TPS6507X=y
>  CONFIG_REGULATOR_TPS65217=y
>  CONFIG_REGULATOR_TPS65910=y
>  CONFIG_REGULATOR_TWL4030=y
> +CONFIG_REGULATOR_PBIAS=y
>  CONFIG_FB=y
>  CONFIG_FIRMWARE_EDID=y
>  CONFIG_FB_MODE_HELPERS=y
> -- 
> 1.7.5.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] ARM: at91: sama5d3: get rid of atmel_tsadcc driver
From: Alexandre Belloni @ 2014-02-26 17:00 UTC (permalink / raw)
  To: ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plagnioj-sclMFOaUSTBWk0Htik3J/w,
	nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1393432190-8799-1-git-send-email-ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2544 bytes --]

On 26/02/2014 at 17:29:50 +0100, Ludovic Desroches wrote :
> From: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
> 
> Touchscreen support for at91_adc has been introduced so we can get rid of
> atmel_tsadcc.
> 
> Signed-off-by: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

Acked-by: Alexandre Belloni <alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

> ---
>  arch/arm/boot/dts/sama5d3.dtsi    |   14 +-------------
>  arch/arm/boot/dts/sama5d3xdm.dtsi |    7 +++----
>  2 files changed, 4 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
> index 3d5faf8..26d7ed5 100644
> --- a/arch/arm/boot/dts/sama5d3.dtsi
> +++ b/arch/arm/boot/dts/sama5d3.dtsi
> @@ -239,7 +239,7 @@
>  			};
>  
>  			adc0: adc@f8018000 {
> -				compatible = "atmel,at91sam9260-adc";
> +				compatible = "atmel,at91sam9x5-adc";
>  				reg = <0xf8018000 0x100>;
>  				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
>  				pinctrl-names = "default";
> @@ -295,18 +295,6 @@
>  				};
>  			};
>  
> -			tsadcc: tsadcc@f8018000 {
> -				compatible = "atmel,at91sam9x5-tsadcc";
> -				reg = <0xf8018000 0x4000>;
> -				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
> -				atmel,tsadcc_clock = <300000>;
> -				atmel,filtering_average = <0x03>;
> -				atmel,pendet_debounce = <0x08>;
> -				atmel,pendet_sensitivity = <0x02>;
> -				atmel,ts_sample_hold_time = <0x0a>;
> -				status = "disabled";
> -			};
> -
>  			i2c2: i2c@f801c000 {
>  				compatible = "atmel,at91sam9x5-i2c";
>  				reg = <0xf801c000 0x4000>;
> diff --git a/arch/arm/boot/dts/sama5d3xdm.dtsi b/arch/arm/boot/dts/sama5d3xdm.dtsi
> index f9bdde5..0b8f5d1 100644
> --- a/arch/arm/boot/dts/sama5d3xdm.dtsi
> +++ b/arch/arm/boot/dts/sama5d3xdm.dtsi
> @@ -23,10 +23,9 @@
>  			};
>  
>  			adc0: adc@f8018000 {
> -				status = "disabled";
> -			};
> -
> -			tsadcc: tsadcc@f8018000 {
> +				atmel,adc-clock-rate = <1000000>;
> +				atmel,adc-ts-wires = <4>;
> +				atmel,adc-ts-pressure-threshold = <10000>;
>  				status = "okay";
>  			};
>  
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [Patch v7 2/2] dmaengine: add Qualcomm BAM dma driver
From: Stanimir Varbanov @ 2014-02-26 16:51 UTC (permalink / raw)
  To: Andy Gross
  Cc: Vinod Koul, Dan Williams, dmaengine, linux-kernel,
	linux-arm-kernel, linux-arm-msm, devicetree
In-Reply-To: <1393283500-18599-3-git-send-email-agross@codeaurora.org>

Hi Andy,

Thanks for the patch.

On 02/25/2014 01:11 AM, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
> 
> Each BAM DMA device is associated with a specific on-chip peripheral.  Each
> channel provides a uni-directional data transfer engine that is capable of
> transferring data between the peripheral and system memory (System mode), or
> between two peripherals (BAM2BAM).
> 
> The initial release of this driver only supports slave transfers between
> peripherals and system memory.
> 
> Signed-off-by: Andy Gross <agross@codeaurora.org>
> ---
>  drivers/dma/Kconfig        |    9 +
>  drivers/dma/Makefile       |    1 +
>  drivers/dma/qcom_bam_dma.c | 1106 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1116 insertions(+)
>  create mode 100644 drivers/dma/qcom_bam_dma.c

<snip>

> +
> +/**
> + * bam_init
> + * @bdev: bam device
> + *
> + * Initialization helper for global bam registers
> + */
> +static int bam_init(struct bam_device *bdev)
> +{
> +	u32 val;
> +
> +	/* read revision and configuration information */
> +	val = readl_relaxed(bdev->regs + BAM_REVISION) & NUM_EES_MASK;
> +

The ees shit is not zero and you got wrong ee. Could you add the line
below or something similar:

val = (val >> NUM_EES_SHIFT) & NUM_EES_MASK;

> +	/* check that configured EE is within range */
> +	if (bdev->ee >= val)
> +		return -EINVAL;
> +

regards,
Stan

^ permalink raw reply

* Re: [PATCH v2 RESEND] pwm: Add CLPS711X PWM support
From: Alexander Shiyan @ 2014-02-26 16:50 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Arnd Bergmann, linux-pwm@vger.kernel.org, Thierry Reding,
	devicetree@vger.kernel.org, Rob Herring, Pawel Moll, Ian Campbell,
	Kumar Gala, grant.likely@linaro.org
In-Reply-To: <20140226160046.GD29659@e106331-lin.cambridge.arm.com>

Hello.

Среда, 26 февраля 2014, 16:00 UTC от Mark Rutland <mark.rutland@arm.com>:
> On Tue, Feb 25, 2014 at 03:50:32PM +0000, Arnd Bergmann wrote:
> > On Tuesday 25 February 2014 19:47:57 Alexander Shiyan wrote:
> > > Вторник, 25 февраля 2014, 16:33 +01:00 от Arnd Bergmann <arnd@arndb.de>:
> > > > On Tuesday 25 February 2014 19:27:47 Alexander Shiyan wrote:
> > => > 
> > > > We really want to avoid wildcards in compatible strings. Can you call this
> > > > "cirrus,cs89712-pwm" to match the first SoC that came with this hardware?
> > > > Obviously if there was some chip before that (I'm not familiar with the
> > > > model numbers), use that instead.
> > > > 
> > > > You can either list all chips you know that have this in the driver,
> > > > or you use "cirrus,cs89712-pwm" as the fallback, and use the name of
> > > > the SoC you have as the more specific string.
> > > 
> > > It seems that in this case we will need to modify the compatibility string
> > > for other drivers that are already available in the kernel...
> > 
> > Ah, right. I missed the binding for gpio and serial going in.
> > 
> > DT maintainers, any suggestion on how we should proceed here?
> > 
> > AFAICT, clps711x platform support is still work-in-progress, so we don't
> > have any upstream users to worry about yet, but changing them is still
> > going to be slightly messy.
> 
> When allocating any new compatible strings, as Arnd says, we should
> avoid wildcards as they're usually far too encompassing and end up
> causing more trouble than they're worth.
> 
> In this case how problematic are the wildcard strings?
> 
> I assume we still have specific strings earlier in any compatible list
> in any case? If not, and there are possible differences, that should be
> fixed right away.
> 
> We have a few options:
> 
> a) Update the docs only.
> 
>    Note in the docs that "cirrus,clps711x-$UNIT" means anything
>    compatible with the $UNIT in the cs89712. This may be
>    counter-intuitive, and if a new clps711x platform comes out with an
>    incompatible $UNIT it should omit "cirrus,clps711x-$UNIT" from its
>    compatible list, but otherwise no harm done.
> 
> b) Deprecate the existing string.
>   
>    Add "cirrus,cs89712-$UNIT" to the binding docs and driver. Mark
>    "cirrus,clps711x-$UNIT" as deprecated in the binding document.
>    Replace "cirrus,clps711x-$UNIT" with "cirrus,cs89712-$UNIT" in all
>    DTs.
> 
>    This will mean new DTBs won't work with an older kernel, but as
>    support is a work in progress that might not matter. Old DTBs will
>    continue to function.
> 
>    Iff you can guarantee that the old string is not possibly being used
>    by anyone, it can be dropped from the driver. If not it has to remain
>    (though can be commented to be deprecated), so that old DTBs
>    function. It's probably best to leave it there.
>   
> c) Deprecate, maintaining (forwards) compatibility.
> 
>    As above, but rather than replacing "cirrus,clps711x-$UNIT" with
>    "cirrus,cs89712-$UNIT" in DTs, place "cirrus,cs89712-$UNIT" before
>    "cirrus,clps711x-$UNIT" in DTs. This allows new DTBs to work with
>    older kernels too. Depending on what level of support you have in
>    mainline currently this may or may not be an important consideration.

If I understood correctly, in the variant "a", we change nothing.
Ie compatibility string is a global to entire platform, and in case of any
CPU differences, we simply add the additional compatibility string fully
meets the CPU name, for example for Cirrus Logic EP7312 this will be
like: "cirrus,ep7312-hw", "cirrus,clps711x-hw".
Correct?

Thanks.
---

^ permalink raw reply

* Re: [PATCHv2 02/16] iommu/omap: omap_iommu_attach() should return ENODEV, not NULL
From: Suman Anna @ 2014-02-26 16:45 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <18584919.CMGx44dZjC@avalon>

Hi Laurent,

> On Tuesday 25 February 2014 16:32:03 Suman Anna wrote:
>> On 02/25/2014 03:13 PM, Laurent Pinchart wrote:
>>> On Thursday 13 February 2014 12:15:33 Suman Anna wrote:
>>>> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>>>
>>>> omap_iommu_attach() returns NULL or ERR_PTR in case of error, but
>>>> omap_iommu_attach_dev() only checks for IS_ERR. Thus a NULL return value
>>>> (in case driver_find_device fails) will cause the kernel to panic when
>>>> omap_iommu_attach_dev() dereferences the pointer.
>>>>
>>>> In such case, omap_iommu_attach() should return ENODEV, not NULL.
>>>>
>>>> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>>> Acked-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
>>>> ---
>>>>
>>>>    drivers/iommu/omap-iommu.c | 4 ++--
>>>>    1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
>>>> index fff2ffd..6272c36 100644
>>>> --- a/drivers/iommu/omap-iommu.c
>>>> +++ b/drivers/iommu/omap-iommu.c
>>>> @@ -863,7 +863,7 @@ static int device_match_by_alias(struct device *dev,
>>>> void *data) **/
>>>>
>>>>    static struct omap_iommu *omap_iommu_attach(const char *name, u32
>>>>    *iopgd)
>>>>    {
>>>> -	int err = -ENOMEM;
>>>> +	int err = -ENODEV;
>>>>    	struct device *dev;
>>>>    	struct omap_iommu *obj;
>>>>
>>>> @@ -871,7 +871,7 @@ static struct omap_iommu *omap_iommu_attach(const
>>>> char *name, u32 *iopgd)
>>>>    				(void *)name,
>>>>    				device_match_by_alias);
>>>>    	if (!dev)
>>>> -		return NULL;
>>>> +		return ERR_PTR(err);
>>>
>>> I would return ERR_PTR(-ENODEV) here, and remove the initialization at
>>> declaration of err above.
>>
>> The initialization at the beginning is also serving one another exit
>> path (a check for try_module_get), where err is not being set. If the
>> initialization is removed, then the err has to be set explicitly at the
>> other place. Let me know if you still want this changed.
>
> The return value of iommu_enable() is unconditionally stored in err before the
> try_module_get() call, so that code patch is buggy anyway and should be fixed.
> I would still remove the initialization at declaration and assign -ENODEV to
> err explicitly when try_module_get() fails before the goto err_module.

OK, I will fix this up.

regards
Suman

^ permalink raw reply

* [PATCH] ARM: at91: sama5d3: get rid of atmel_tsadcc driver
From: ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w @ 2014-02-26 16:29 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
	plagnioj-sclMFOaUSTBWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Ludovic Desroches

From: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

Touchscreen support for at91_adc has been introduced so we can get rid of
atmel_tsadcc.

Signed-off-by: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/sama5d3.dtsi    |   14 +-------------
 arch/arm/boot/dts/sama5d3xdm.dtsi |    7 +++----
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 3d5faf8..26d7ed5 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -239,7 +239,7 @@
 			};
 
 			adc0: adc@f8018000 {
-				compatible = "atmel,at91sam9260-adc";
+				compatible = "atmel,at91sam9x5-adc";
 				reg = <0xf8018000 0x100>;
 				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
@@ -295,18 +295,6 @@
 				};
 			};
 
-			tsadcc: tsadcc@f8018000 {
-				compatible = "atmel,at91sam9x5-tsadcc";
-				reg = <0xf8018000 0x4000>;
-				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
-				atmel,tsadcc_clock = <300000>;
-				atmel,filtering_average = <0x03>;
-				atmel,pendet_debounce = <0x08>;
-				atmel,pendet_sensitivity = <0x02>;
-				atmel,ts_sample_hold_time = <0x0a>;
-				status = "disabled";
-			};
-
 			i2c2: i2c@f801c000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf801c000 0x4000>;
diff --git a/arch/arm/boot/dts/sama5d3xdm.dtsi b/arch/arm/boot/dts/sama5d3xdm.dtsi
index f9bdde5..0b8f5d1 100644
--- a/arch/arm/boot/dts/sama5d3xdm.dtsi
+++ b/arch/arm/boot/dts/sama5d3xdm.dtsi
@@ -23,10 +23,9 @@
 			};
 
 			adc0: adc@f8018000 {
-				status = "disabled";
-			};
-
-			tsadcc: tsadcc@f8018000 {
+				atmel,adc-clock-rate = <1000000>;
+				atmel,adc-ts-wires = <4>;
+				atmel,adc-ts-pressure-threshold = <10000>;
 				status = "okay";
 			};
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH] ARM: at91: sama5d3: get rid of atmel_tsadcc driver
From: ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w @ 2014-02-26 16:19 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
	plagnioj-sclMFOaUSTBWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Ludovic Desroches

From: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>

Touchscreen support for at91_adc has been introduced so we can get rid of
atmel_tsadcc.

Signed-off-by: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/sama5d3.dtsi    |   14 +-------------
 arch/arm/boot/dts/sama5d3xdm.dtsi |    7 +++----
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 3d5faf8..26d7ed5 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -239,7 +239,7 @@
 			};
 
 			adc0: adc@f8018000 {
-				compatible = "atmel,at91sam9260-adc";
+				compatible = "atmel,at91sam9x5-adc";
 				reg = <0xf8018000 0x100>;
 				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
@@ -295,18 +295,6 @@
 				};
 			};
 
-			tsadcc: tsadcc@f8018000 {
-				compatible = "atmel,at91sam9x5-tsadcc";
-				reg = <0xf8018000 0x4000>;
-				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
-				atmel,tsadcc_clock = <300000>;
-				atmel,filtering_average = <0x03>;
-				atmel,pendet_debounce = <0x08>;
-				atmel,pendet_sensitivity = <0x02>;
-				atmel,ts_sample_hold_time = <0x0a>;
-				status = "disabled";
-			};
-
 			i2c2: i2c@f801c000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf801c000 0x4000>;
diff --git a/arch/arm/boot/dts/sama5d3xdm.dtsi b/arch/arm/boot/dts/sama5d3xdm.dtsi
index f9bdde5..0b8f5d1 100644
--- a/arch/arm/boot/dts/sama5d3xdm.dtsi
+++ b/arch/arm/boot/dts/sama5d3xdm.dtsi
@@ -23,10 +23,9 @@
 			};
 
 			adc0: adc@f8018000 {
-				status = "disabled";
-			};
-
-			tsadcc: tsadcc@f8018000 {
+				atmel,adc-clock-rate = <1000000>;
+				atmel,adc-ts-wires = <4>;
+				atmel,adc-ts-pressure-threshold = <10000>;
 				status = "okay";
 			};
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 2/2] ASoC: cirrus: clps711x: Add bindings documentation for the CLPS711X DAI
From: Alexander Shiyan @ 2014-02-26 16:07 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Arnd Bergmann, Olof Johansson, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Grant Likely, Alexander Shiyan

This patch adds the devicetree documentation for the Cirrus Logic
CLPS711X Digital Audio Interface (DAI).

Signed-off-by: Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org>
---
 .../bindings/sound/cirrus,clps711x-dai.txt           | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/cirrus,clps711x-dai.txt

diff --git a/Documentation/devicetree/bindings/sound/cirrus,clps711x-dai.txt b/Documentation/devicetree/bindings/sound/cirrus,clps711x-dai.txt
new file mode 100644
index 0000000..718599e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cirrus,clps711x-dai.txt
@@ -0,0 +1,20 @@
+* Cirrus Logic CLPS711X Digital Audio Interface (DAI)
+
+Required properties:
+- compatible: Should be "cirrus,clps711x-dai".
+- reg: Should contain registers location and length.
+- clocks: A clock specifier for the CPU PLL clock.
+- clock-names: The CPU PLL clock should be named "pll".
+- interrupts: Should contain DAI interrupt number.
+- syscon: phandle to syscon device node which control DAI (SYSCON3).
+
+Example:
+	dai: dai@80002000 {
+		#sound-dai-cells = <0>;
+		compatible = "cirrus,clps711x-dai";
+		reg = <0x80002000 0x604>;
+		clocks = <&clks 3>;
+		clock-names = "pll";
+		interrupts = <32>;
+		syscon = <&syscon3>;
+	};
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH v12] gpio: add a driver for the Synopsys DesignWare APB GPIO block
From: Dinh Nguyen @ 2014-02-26 16:02 UTC (permalink / raw)
  To: delicious quinoa
  Cc: Linus Walleij, linux-kernel, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, Jamie Iles, devicetree@vger.kernel.org,
	Rob Herring, Grant Likely, Mark Rutland, Steffen Trumtrar,
	Sebastian Hesselbarth, Heiko Stuebner, Alan Tull, Dinh Nguyen,
	Yves Vandervennet
In-Reply-To: <CANk1AXRg7DPSMAZytfu=wwiWi+-PEqsNPeS_9zirfDXsOWQK=g@mail.gmail.com>

Hi Alan,

On Wed, 2014-02-26 at 09:53 -0600, delicious quinoa wrote:
> On Tue, Feb 25, 2014 at 5:01 PM, Alan Tull <delicious.quinoa@gmail.com> wrote:
> > From: Jamie Iles <jamie@jamieiles.com>
> >
> > The Synopsys DesignWare block is used in some ARM devices (picoxcell)
> > and can be configured to provide multiple banks of GPIO pins.
> >
> > Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> > Signed-off-by: Alan Tull <atull@altera.com>
> > Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> >
> > v12: - Add irq_startup/shutdown
> >      - do irq_create_mapping() in probe, irq_find_mapping() in to_irq()
> >      - Adjust mappings to show support for 1 gpio per port.
> >      - gpio-cells = <1>
> > v11: - Use NULL when checking existence of 'interrupts' property
> >      - Bindings descriptions cleanup
> > v10: - in documentation nr-gpio -> nr-gpios
> > v9:  - cleanup in dt bindings doc
> >      - use of_get_child_count()
> > v8:  - remove socfpga.dtsi changes
> >      - minor cleanup in devicetree documentation
> > v7:  - use irq_generic_chip
> >      - support one irq per gpio line or one irq for many
> >      - s/bank/port/ and other cleanup
> > v6:  - (atull) squash the set of patches
> >      - use linear irq domain
> >      - build fixes. Original driver was reviewed on v3.2.
> >      - Fix setting irq edge type for 'rising' and 'both'.
> >      - Support as a loadable module.
> >      - Use bgpio_chip's spinlock during register access.
> >      - Clean up register names to match spec
> >      - s/bank/port/ because register names use the word 'port'
> >      - s/nr-gpio/nr-gpios/
> >      - don't get/put the of_node
> >      - remove signoffs/acked-by's because of changes
> >      - other cleanup
> > v5:  - handle sparse bank population correctly
> > v3:  - depend on rather than select IRQ_DOMAIN
> >      - split IRQ support into a separate patch
> > v2:  - use Rob Herring's irqdomain in generic irq chip patches
> >      - use reg property to indicate bank index
> >      - support irqs on both edges based on LinusW's u300 driver
> > ---
> >  .../devicetree/bindings/gpio/snps-dwapb-gpio.txt   |   57 +++
> >  drivers/gpio/Kconfig                               |    9 +
> >  drivers/gpio/Makefile                              |    1 +
> >  drivers/gpio/gpio-dwapb.c                          |  438 ++++++++++++++++++++
> >  4 files changed, 505 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
> >  create mode 100644 drivers/gpio/gpio-dwapb.c
> >
> > diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
> > new file mode 100644
> > index 0000000..0934950
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
> > @@ -0,0 +1,57 @@
> > +* Synopsys DesignWare APB GPIO controller
> > +
> > +Required properties:
> > +- compatible : Should contain "snps,dw-apb-gpio"
> > +- reg : Address and length of the register set for the device.
> > +- #address-cells : should be 1 (for addressing port subnodes).
> > +- #size-cells : should be 0 (port subnodes).
> > +
> > +The GPIO controller has a configurable number of ports, each of which are
> > +represented as child nodes with the following properties:
> > +
> > +Required properties:
> > +- compatible : "snps,dw-apb-gpio-port"
> > +- gpio-controller : Marks the device node as a gpio controller.
> > +- #gpio-cells : Should be 1.  It is the pin number.
> > +- reg : The integer port index of the port, a single cell.
> > +
> > +Optional properties:
> > +- interrupt-controller : The first port may be configured to be an interrupt
> > +controller.
> > +- #interrupt-cells : Specifies the number of cells needed to encode an
> > +  interrupt.  Shall be set to 2.  The first cell defines the interrupt number,
> > +  the second encodes the triger flags encoded as described in
> > +  Documentation/devicetree/bindings/interrupts.txt
> > +- interrupt-parent : The parent interrupt controller.
> > +- interrupts : The interrupt to the parent controller raised when GPIOs
> > +  generate the interrupts.
> > +- snps,nr-gpios : The number of pins in the port, a single cell.
> > +
> > +Example:
> > +
> > +gpio: gpio@20000 {
> > +       compatible = "snps,dw-apb-gpio";
> > +       reg = <0x20000 0x1000>;
> > +       #address-cells = <1>;
> > +       #size-cells = <0>;
> > +
> > +       porta: gpio-controller@0 {
> > +               compatible = "snps,dw-apb-gpio-port";
> > +               gpio-controller;
> > +               #gpio-cells = <1>;
> > +               snps,nr-gpios = <8>;
> > +               reg = <0>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +               interrupt-parent = <&vic1>;
> > +               interrupts = <0>;
> > +       };
> > +
> > +       portb: gpio-controller@1 {
> > +               compatible = "snps,dw-apb-gpio-port";
> > +               gpio-controller;
> > +               #gpio-cells = <1>;
> > +               snps,nr-gpios = <8>;
> > +               reg = <1>;
> > +       };
> > +};
> 
> Hi Rob,
> 
> Are these bindings acceptable?

In the future, I think you should split out the DTS documentation into a
separate patch. As recommended in :

Documentation/devicetree/bindings/submitting-patches.txt

Dinh
> 
> Alan
> 
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index 903f24d..9979017 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -128,6 +128,15 @@ config GPIO_GENERIC_PLATFORM
> >         help
> >           Say yes here to support basic platform_device memory-mapped GPIO controllers.
> >
> > +config GPIO_DWAPB
> > +       tristate "Synopsys DesignWare APB GPIO driver"
> > +       select GPIO_GENERIC
> > +       select GENERIC_IRQ_CHIP
> > +       depends on OF_GPIO && IRQ_DOMAIN
> > +       help
> > +         Say Y or M here to build support for the Synopsys DesignWare APB
> > +         GPIO block.
> > +
> >  config GPIO_IT8761E
> >         tristate "IT8761E GPIO support"
> >         depends on X86  # unconditional access to IO space.
> > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> > index 5d50179..2d09f04 100644
> > --- a/drivers/gpio/Makefile
> > +++ b/drivers/gpio/Makefile
> > @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_CS5535)     += gpio-cs5535.o
> >  obj-$(CONFIG_GPIO_DA9052)      += gpio-da9052.o
> >  obj-$(CONFIG_GPIO_DA9055)      += gpio-da9055.o
> >  obj-$(CONFIG_GPIO_DAVINCI)     += gpio-davinci.o
> > +obj-$(CONFIG_GPIO_DWAPB)       += gpio-dwapb.o
> >  obj-$(CONFIG_GPIO_EM)          += gpio-em.o
> >  obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
> >  obj-$(CONFIG_GPIO_F7188X)      += gpio-f7188x.o
> > diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
> > new file mode 100644
> > index 0000000..2797fbb
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-dwapb.c
> > @@ -0,0 +1,438 @@
> > +/*
> > + * Copyright (c) 2011 Jamie Iles
> > + *
> > + * 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.
> > + *
> > + * All enquiries to support@picochip.com
> > + */
> > +#include <linux/basic_mmio_gpio.h>
> > +#include <linux/err.h>
> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/ioport.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +
> > +#define GPIO_SWPORTA_DR                0x00
> > +#define GPIO_SWPORTA_DDR       0x04
> > +#define GPIO_SWPORTB_DR                0x0c
> > +#define GPIO_SWPORTB_DDR       0x10
> > +#define GPIO_SWPORTC_DR                0x18
> > +#define GPIO_SWPORTC_DDR       0x1c
> > +#define GPIO_SWPORTD_DR                0x24
> > +#define GPIO_SWPORTD_DDR       0x28
> > +#define GPIO_INTEN             0x30
> > +#define GPIO_INTMASK           0x34
> > +#define GPIO_INTTYPE_LEVEL     0x38
> > +#define GPIO_INT_POLARITY      0x3c
> > +#define GPIO_INTSTATUS         0x40
> > +#define GPIO_PORTA_EOI         0x4c
> > +#define GPIO_EXT_PORTA         0x50
> > +#define GPIO_EXT_PORTB         0x54
> > +#define GPIO_EXT_PORTC         0x58
> > +#define GPIO_EXT_PORTD         0x5c
> > +
> > +#define DWAPB_MAX_PORTS                4
> > +#define GPIO_EXT_PORT_SIZE     (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
> > +#define GPIO_SWPORT_DR_SIZE    (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
> > +#define GPIO_SWPORT_DDR_SIZE   (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
> > +
> > +struct dwapb_gpio;
> > +
> > +struct dwapb_gpio_port {
> > +       struct bgpio_chip       bgc;
> > +       bool                    is_registered;
> > +       struct dwapb_gpio       *gpio;
> > +};
> > +
> > +struct dwapb_gpio {
> > +       struct  device          *dev;
> > +       void __iomem            *regs;
> > +       struct dwapb_gpio_port  *ports;
> > +       unsigned int            nr_ports;
> > +       struct irq_domain       *domain;
> > +};
> > +
> > +static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> > +{
> > +       struct bgpio_chip *bgc = to_bgpio_chip(gc);
> > +       struct dwapb_gpio_port *port = container_of(bgc, struct
> > +                                                   dwapb_gpio_port, bgc);
> > +       struct dwapb_gpio *gpio = port->gpio;
> > +
> > +       return irq_find_mapping(gpio->domain, offset);
> > +}
> > +
> > +static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
> > +{
> > +       u32 v = readl(gpio->regs + GPIO_INT_POLARITY);
> > +
> > +       if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs))
> > +               v &= ~BIT(offs);
> > +       else
> > +               v |= BIT(offs);
> > +
> > +       writel(v, gpio->regs + GPIO_INT_POLARITY);
> > +}
> > +
> > +static void dwapb_irq_handler(u32 irq, struct irq_desc *desc)
> > +{
> > +       struct dwapb_gpio *gpio = irq_get_handler_data(irq);
> > +       struct irq_chip *chip = irq_desc_get_chip(desc);
> > +       u32 irq_status = readl_relaxed(gpio->regs + GPIO_INTSTATUS);
> > +
> > +       while (irq_status) {
> > +               int hwirq = fls(irq_status) - 1;
> > +               int gpio_irq = irq_find_mapping(gpio->domain, hwirq);
> > +
> > +               generic_handle_irq(gpio_irq);
> > +               irq_status &= ~BIT(hwirq);
> > +
> > +               if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK)
> > +                       == IRQ_TYPE_EDGE_BOTH)
> > +                       dwapb_toggle_trigger(gpio, hwirq);
> > +       }
> > +
> > +       if (chip->irq_eoi)
> > +               chip->irq_eoi(irq_desc_get_irq_data(desc));
> > +}
> > +
> > +static void dwapb_irq_enable(struct irq_data *d)
> > +{
> > +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> > +       struct dwapb_gpio *gpio = igc->private;
> > +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> > +       unsigned long flags;
> > +       u32 val;
> > +
> > +       spin_lock_irqsave(&bgc->lock, flags);
> > +       val = readl(gpio->regs + GPIO_INTEN);
> > +       val |= BIT(d->hwirq);
> > +       writel(val, gpio->regs + GPIO_INTEN);
> > +       spin_unlock_irqrestore(&bgc->lock, flags);
> > +}
> > +
> > +static void dwapb_irq_disable(struct irq_data *d)
> > +{
> > +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> > +       struct dwapb_gpio *gpio = igc->private;
> > +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> > +       unsigned long flags;
> > +       u32 val;
> > +
> > +       spin_lock_irqsave(&bgc->lock, flags);
> > +       val = readl(gpio->regs + GPIO_INTEN);
> > +       val &= ~BIT(d->hwirq);
> > +       writel(val, gpio->regs + GPIO_INTEN);
> > +       spin_unlock_irqrestore(&bgc->lock, flags);
> > +}
> > +
> > +static unsigned int dwapb_irq_startup(struct irq_data *d)
> > +{
> > +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> > +       struct dwapb_gpio *gpio = igc->private;
> > +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> > +
> > +       if (gpio_lock_as_irq(&bgc->gc, irqd_to_hwirq(d)))
> > +               dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n",
> > +                       irqd_to_hwirq(d));
> > +       dwapb_irq_enable(d);
> > +       return 0;
> > +}
> > +
> > +static void dwapb_irq_shutdown(struct irq_data *d)
> > +{
> > +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> > +       struct dwapb_gpio *gpio = igc->private;
> > +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> > +
> > +       dwapb_irq_disable(d);
> > +       gpio_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d));
> > +}
> > +
> > +static int dwapb_irq_set_type(struct irq_data *d, u32 type)
> > +{
> > +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> > +       struct dwapb_gpio *gpio = igc->private;
> > +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> > +       int bit = d->hwirq;
> > +       unsigned long level, polarity, flags;
> > +
> > +       if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
> > +                    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
> > +               return -EINVAL;
> > +
> > +       spin_lock_irqsave(&bgc->lock, flags);
> > +       level = readl(gpio->regs + GPIO_INTTYPE_LEVEL);
> > +       polarity = readl(gpio->regs + GPIO_INT_POLARITY);
> > +
> > +       switch (type) {
> > +       case IRQ_TYPE_EDGE_BOTH:
> > +               level |= BIT(bit);
> > +               dwapb_toggle_trigger(gpio, bit);
> > +               break;
> > +       case IRQ_TYPE_EDGE_RISING:
> > +               level |= BIT(bit);
> > +               polarity |= BIT(bit);
> > +               break;
> > +       case IRQ_TYPE_EDGE_FALLING:
> > +               level |= BIT(bit);
> > +               polarity &= ~BIT(bit);
> > +               break;
> > +       case IRQ_TYPE_LEVEL_HIGH:
> > +               level &= ~BIT(bit);
> > +               polarity |= BIT(bit);
> > +               break;
> > +       case IRQ_TYPE_LEVEL_LOW:
> > +               level &= ~BIT(bit);
> > +               polarity &= ~BIT(bit);
> > +               break;
> > +       }
> > +
> > +       writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
> > +       writel(polarity, gpio->regs + GPIO_INT_POLARITY);
> > +       spin_unlock_irqrestore(&bgc->lock, flags);
> > +
> > +       return 0;
> > +}
> > +
> > +static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
> > +                                struct dwapb_gpio_port *port)
> > +{
> > +       struct gpio_chip *gc = &port->bgc.gc;
> > +       struct device_node *node =  gc->of_node;
> > +       struct irq_chip_generic *irq_gc;
> > +       unsigned int hwirq, ngpio = gc->ngpio;
> > +       struct irq_chip_type *ct;
> > +       int err, irq;
> > +
> > +       irq = irq_of_parse_and_map(node, 0);
> > +       if (!irq) {
> > +               dev_warn(gpio->dev, "no irq for bank %s\n",
> > +                       port->bgc.gc.of_node->full_name);
> > +               return;
> > +       }
> > +
> > +       gpio->domain = irq_domain_add_linear(node, ngpio,
> > +                                            &irq_generic_chip_ops, gpio);
> > +       if (!gpio->domain)
> > +               return;
> > +
> > +       err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1,
> > +                                            "gpio-dwapb", handle_level_irq,
> > +                                            IRQ_NOREQUEST, 0,
> > +                                            IRQ_GC_INIT_NESTED_LOCK);
> > +       if (err) {
> > +               dev_info(gpio->dev, "irq_alloc_domain_generic_chips failed\n");
> > +               irq_domain_remove(gpio->domain);
> > +               gpio->domain = NULL;
> > +               return;
> > +       }
> > +
> > +       irq_gc = irq_get_domain_generic_chip(gpio->domain, 0);
> > +       if (!irq_gc) {
> > +               irq_domain_remove(gpio->domain);
> > +               gpio->domain = NULL;
> > +               return;
> > +       }
> > +
> > +       irq_gc->reg_base = gpio->regs;
> > +       irq_gc->private = gpio;
> > +
> > +       ct = irq_gc->chip_types;
> > +       ct->chip.irq_ack = irq_gc_ack_set_bit;
> > +       ct->chip.irq_mask = irq_gc_mask_set_bit;
> > +       ct->chip.irq_unmask = irq_gc_mask_clr_bit;
> > +       ct->chip.irq_set_type = dwapb_irq_set_type;
> > +       ct->chip.irq_enable = dwapb_irq_enable;
> > +       ct->chip.irq_disable = dwapb_irq_disable;
> > +       ct->chip.irq_startup = dwapb_irq_startup;
> > +       ct->chip.irq_shutdown = dwapb_irq_shutdown;
> > +       ct->regs.ack = GPIO_PORTA_EOI;
> > +       ct->regs.mask = GPIO_INTMASK;
> > +
> > +       irq_setup_generic_chip(irq_gc, IRQ_MSK(port->bgc.gc.ngpio),
> > +                       IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
> > +
> > +       irq_set_chained_handler(irq, dwapb_irq_handler);
> > +       irq_set_handler_data(irq, gpio);
> > +
> > +       for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
> > +               irq_create_mapping(gpio->domain, hwirq);
> > +
> > +       port->bgc.gc.to_irq = dwapb_gpio_to_irq;
> > +}
> > +
> > +static void dwapb_irq_teardown(struct dwapb_gpio *gpio)
> > +{
> > +       struct dwapb_gpio_port *port = &gpio->ports[0];
> > +       struct gpio_chip *gc = &port->bgc.gc;
> > +       unsigned int ngpio = gc->ngpio;
> > +       irq_hw_number_t hwirq;
> > +
> > +       if (!gpio->domain)
> > +               return;
> > +
> > +       for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
> > +               irq_dispose_mapping(irq_find_mapping(gpio->domain, hwirq));
> > +
> > +       irq_domain_remove(gpio->domain);
> > +       gpio->domain = NULL;
> > +}
> > +
> > +static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
> > +                              struct device_node *port_np,
> > +                              unsigned int offs)
> > +{
> > +       struct dwapb_gpio_port *port;
> > +       u32 port_idx, ngpio;
> > +       void __iomem *dat, *set, *dirout;
> > +       int err;
> > +
> > +       if (of_property_read_u32(port_np, "reg", &port_idx) ||
> > +               port_idx >= DWAPB_MAX_PORTS) {
> > +               dev_err(gpio->dev, "missing/invalid port index for %s\n",
> > +                       port_np->full_name);
> > +               return -EINVAL;
> > +       }
> > +
> > +       port = &gpio->ports[offs];
> > +       port->gpio = gpio;
> > +
> > +       if (of_property_read_u32(port_np, "snps,nr-gpios", &ngpio)) {
> > +               dev_info(gpio->dev, "failed to get number of gpios for %s\n",
> > +                        port_np->full_name);
> > +               ngpio = 32;
> > +       }
> > +
> > +       dat = gpio->regs + GPIO_EXT_PORTA + (port_idx * GPIO_EXT_PORT_SIZE);
> > +       set = gpio->regs + GPIO_SWPORTA_DR + (port_idx * GPIO_SWPORT_DR_SIZE);
> > +       dirout = gpio->regs + GPIO_SWPORTA_DDR +
> > +               (port_idx * GPIO_SWPORT_DDR_SIZE);
> > +
> > +       err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout,
> > +                        NULL, false);
> > +       if (err) {
> > +               dev_err(gpio->dev, "failed to init gpio chip for %s\n",
> > +                       port_np->full_name);
> > +               return err;
> > +       }
> > +
> > +       port->bgc.gc.ngpio = ngpio;
> > +       port->bgc.gc.of_node = port_np;
> > +
> > +       /*
> > +        * Only port A can provide interrupts in all configurations of the IP.
> > +        */
> > +       if (port_idx == 0 &&
> > +           of_property_read_bool(port_np, "interrupt-controller"))
> > +               dwapb_configure_irqs(gpio, port);
> > +
> > +       err = gpiochip_add(&port->bgc.gc);
> > +       if (err)
> > +               dev_err(gpio->dev, "failed to register gpiochip for %s\n",
> > +                       port_np->full_name);
> > +       else
> > +               port->is_registered = true;
> > +
> > +       return err;
> > +}
> > +
> > +static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
> > +{
> > +       unsigned int m;
> > +
> > +       for (m = 0; m < gpio->nr_ports; ++m)
> > +               if (gpio->ports[m].is_registered)
> > +                       WARN_ON(gpiochip_remove(&gpio->ports[m].bgc.gc));
> > +}
> > +
> > +static int dwapb_gpio_probe(struct platform_device *pdev)
> > +{
> > +       struct resource *res;
> > +       struct dwapb_gpio *gpio;
> > +       struct device_node *np;
> > +       int err;
> > +       unsigned int offs = 0;
> > +
> > +       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> > +       if (!gpio)
> > +               return -ENOMEM;
> > +       gpio->dev = &pdev->dev;
> > +
> > +       gpio->nr_ports = of_get_child_count(pdev->dev.of_node);
> > +       if (!gpio->nr_ports) {
> > +               err = -EINVAL;
> > +               goto out_err;
> > +       }
> > +       gpio->ports = devm_kzalloc(&pdev->dev, gpio->nr_ports *
> > +                                  sizeof(*gpio->ports), GFP_KERNEL);
> > +       if (!gpio->ports) {
> > +               err = -ENOMEM;
> > +               goto out_err;
> > +       }
> > +
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       gpio->regs = devm_ioremap_resource(&pdev->dev, res);
> > +       if (IS_ERR(gpio->regs)) {
> > +               err = PTR_ERR(gpio->regs);
> > +               goto out_err;
> > +       }
> > +
> > +       for_each_child_of_node(pdev->dev.of_node, np) {
> > +               err = dwapb_gpio_add_port(gpio, np, offs++);
> > +               if (err)
> > +                       goto out_unregister;
> > +       }
> > +       platform_set_drvdata(pdev, gpio);
> > +
> > +       return 0;
> > +
> > +out_unregister:
> > +       dwapb_gpio_unregister(gpio);
> > +       dwapb_irq_teardown(gpio);
> > +
> > +out_err:
> > +       return err;
> > +}
> > +
> > +static int dwapb_gpio_remove(struct platform_device *pdev)
> > +{
> > +       struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
> > +
> > +       dwapb_gpio_unregister(gpio);
> > +       dwapb_irq_teardown(gpio);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id dwapb_of_match[] = {
> > +       { .compatible = "snps,dw-apb-gpio" },
> > +       { /* Sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, dwapb_of_match);
> > +
> > +static struct platform_driver dwapb_gpio_driver = {
> > +       .driver         = {
> > +               .name   = "gpio-dwapb",
> > +               .owner  = THIS_MODULE,
> > +               .of_match_table = of_match_ptr(dwapb_of_match),
> > +       },
> > +       .probe          = dwapb_gpio_probe,
> > +       .remove         = dwapb_gpio_remove,
> > +};
> > +
> > +module_platform_driver(dwapb_gpio_driver);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Jamie Iles");
> > +MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");
> > --
> > 1.7.9.5
> >
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply

* Re: [PATCH v2 RESEND] pwm: Add CLPS711X PWM support
From: Mark Rutland @ 2014-02-26 16:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Shiyan, linux-pwm@vger.kernel.org, Thierry Reding,
	devicetree@vger.kernel.org, Rob Herring, Pawel Moll, Ian Campbell,
	Kumar Gala, grant.likely@linaro.org
In-Reply-To: <5211076.9eDkSrDagS@wuerfel>

On Tue, Feb 25, 2014 at 03:50:32PM +0000, Arnd Bergmann wrote:
> On Tuesday 25 February 2014 19:47:57 Alexander Shiyan wrote:
> > Вторник, 25 февраля 2014, 16:33 +01:00 от Arnd Bergmann <arnd@arndb.de>:
> > > On Tuesday 25 February 2014 19:27:47 Alexander Shiyan wrote:
> => > 
> > > We really want to avoid wildcards in compatible strings. Can you call this
> > > "cirrus,cs89712-pwm" to match the first SoC that came with this hardware?
> > > Obviously if there was some chip before that (I'm not familiar with the
> > > model numbers), use that instead.
> > > 
> > > You can either list all chips you know that have this in the driver,
> > > or you use "cirrus,cs89712-pwm" as the fallback, and use the name of
> > > the SoC you have as the more specific string.
> > 
> > It seems that in this case we will need to modify the compatibility string
> > for other drivers that are already available in the kernel...
> 
> Ah, right. I missed the binding for gpio and serial going in.
> 
> DT maintainers, any suggestion on how we should proceed here?
> 
> AFAICT, clps711x platform support is still work-in-progress, so we don't
> have any upstream users to worry about yet, but changing them is still
> going to be slightly messy.

When allocating any new compatible strings, as Arnd says, we should
avoid wildcards as they're usually far too encompassing and end up
causing more trouble than they're worth.

In this case how problematic are the wildcard strings?

I assume we still have specific strings earlier in any compatible list
in any case? If not, and there are possible differences, that should be
fixed right away.

We have a few options:

a) Update the docs only.

   Note in the docs that "cirrus,clps711x-$UNIT" means anything
   compatible with the $UNIT in the cs89712. This may be
   counter-intuitive, and if a new clps711x platform comes out with an
   incompatible $UNIT it should omit "cirrus,clps711x-$UNIT" from its
   compatible list, but otherwise no harm done.

b) Deprecate the existing string.
  
   Add "cirrus,cs89712-$UNIT" to the binding docs and driver. Mark
   "cirrus,clps711x-$UNIT" as deprecated in the binding document.
   Replace "cirrus,clps711x-$UNIT" with "cirrus,cs89712-$UNIT" in all
   DTs.

   This will mean new DTBs won't work with an older kernel, but as
   support is a work in progress that might not matter. Old DTBs will
   continue to function.

   Iff you can guarantee that the old string is not possibly being used
   by anyone, it can be dropped from the driver. If not it has to remain
   (though can be commented to be deprecated), so that old DTBs
   function. It's probably best to leave it there.
  
c) Deprecate, maintaining (forwards) compatibility.

   As above, but rather than replacing "cirrus,clps711x-$UNIT" with
   "cirrus,cs89712-$UNIT" in DTs, place "cirrus,cs89712-$UNIT" before
   "cirrus,clps711x-$UNIT" in DTs. This allows new DTBs to work with
   older kernels too. Depending on what level of support you have in
   mainline currently this may or may not be an important consideration.

Cheers,
Mark.

^ permalink raw reply

* Re: [PATCH v12] gpio: add a driver for the Synopsys DesignWare APB GPIO block
From: delicious quinoa @ 2014-02-26 15:53 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-kernel, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, Jamie Iles, devicetree@vger.kernel.org,
	Rob Herring, Grant Likely, Mark Rutland, Steffen Trumtrar,
	Sebastian Hesselbarth, delicious quinoa, Heiko Stuebner,
	Alan Tull, Dinh Nguyen, Yves Vandervennet
In-Reply-To: <1393369261-17469-1-git-send-email-delicious.quinoa@gmail.com>

On Tue, Feb 25, 2014 at 5:01 PM, Alan Tull <delicious.quinoa@gmail.com> wrote:
> From: Jamie Iles <jamie@jamieiles.com>
>
> The Synopsys DesignWare block is used in some ARM devices (picoxcell)
> and can be configured to provide multiple banks of GPIO pins.
>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> Signed-off-by: Alan Tull <atull@altera.com>
> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>
> v12: - Add irq_startup/shutdown
>      - do irq_create_mapping() in probe, irq_find_mapping() in to_irq()
>      - Adjust mappings to show support for 1 gpio per port.
>      - gpio-cells = <1>
> v11: - Use NULL when checking existence of 'interrupts' property
>      - Bindings descriptions cleanup
> v10: - in documentation nr-gpio -> nr-gpios
> v9:  - cleanup in dt bindings doc
>      - use of_get_child_count()
> v8:  - remove socfpga.dtsi changes
>      - minor cleanup in devicetree documentation
> v7:  - use irq_generic_chip
>      - support one irq per gpio line or one irq for many
>      - s/bank/port/ and other cleanup
> v6:  - (atull) squash the set of patches
>      - use linear irq domain
>      - build fixes. Original driver was reviewed on v3.2.
>      - Fix setting irq edge type for 'rising' and 'both'.
>      - Support as a loadable module.
>      - Use bgpio_chip's spinlock during register access.
>      - Clean up register names to match spec
>      - s/bank/port/ because register names use the word 'port'
>      - s/nr-gpio/nr-gpios/
>      - don't get/put the of_node
>      - remove signoffs/acked-by's because of changes
>      - other cleanup
> v5:  - handle sparse bank population correctly
> v3:  - depend on rather than select IRQ_DOMAIN
>      - split IRQ support into a separate patch
> v2:  - use Rob Herring's irqdomain in generic irq chip patches
>      - use reg property to indicate bank index
>      - support irqs on both edges based on LinusW's u300 driver
> ---
>  .../devicetree/bindings/gpio/snps-dwapb-gpio.txt   |   57 +++
>  drivers/gpio/Kconfig                               |    9 +
>  drivers/gpio/Makefile                              |    1 +
>  drivers/gpio/gpio-dwapb.c                          |  438 ++++++++++++++++++++
>  4 files changed, 505 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
>  create mode 100644 drivers/gpio/gpio-dwapb.c
>
> diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
> new file mode 100644
> index 0000000..0934950
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
> @@ -0,0 +1,57 @@
> +* Synopsys DesignWare APB GPIO controller
> +
> +Required properties:
> +- compatible : Should contain "snps,dw-apb-gpio"
> +- reg : Address and length of the register set for the device.
> +- #address-cells : should be 1 (for addressing port subnodes).
> +- #size-cells : should be 0 (port subnodes).
> +
> +The GPIO controller has a configurable number of ports, each of which are
> +represented as child nodes with the following properties:
> +
> +Required properties:
> +- compatible : "snps,dw-apb-gpio-port"
> +- gpio-controller : Marks the device node as a gpio controller.
> +- #gpio-cells : Should be 1.  It is the pin number.
> +- reg : The integer port index of the port, a single cell.
> +
> +Optional properties:
> +- interrupt-controller : The first port may be configured to be an interrupt
> +controller.
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt.  Shall be set to 2.  The first cell defines the interrupt number,
> +  the second encodes the triger flags encoded as described in
> +  Documentation/devicetree/bindings/interrupts.txt
> +- interrupt-parent : The parent interrupt controller.
> +- interrupts : The interrupt to the parent controller raised when GPIOs
> +  generate the interrupts.
> +- snps,nr-gpios : The number of pins in the port, a single cell.
> +
> +Example:
> +
> +gpio: gpio@20000 {
> +       compatible = "snps,dw-apb-gpio";
> +       reg = <0x20000 0x1000>;
> +       #address-cells = <1>;
> +       #size-cells = <0>;
> +
> +       porta: gpio-controller@0 {
> +               compatible = "snps,dw-apb-gpio-port";
> +               gpio-controller;
> +               #gpio-cells = <1>;
> +               snps,nr-gpios = <8>;
> +               reg = <0>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +               interrupt-parent = <&vic1>;
> +               interrupts = <0>;
> +       };
> +
> +       portb: gpio-controller@1 {
> +               compatible = "snps,dw-apb-gpio-port";
> +               gpio-controller;
> +               #gpio-cells = <1>;
> +               snps,nr-gpios = <8>;
> +               reg = <1>;
> +       };
> +};

Hi Rob,

Are these bindings acceptable?

Alan

> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 903f24d..9979017 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -128,6 +128,15 @@ config GPIO_GENERIC_PLATFORM
>         help
>           Say yes here to support basic platform_device memory-mapped GPIO controllers.
>
> +config GPIO_DWAPB
> +       tristate "Synopsys DesignWare APB GPIO driver"
> +       select GPIO_GENERIC
> +       select GENERIC_IRQ_CHIP
> +       depends on OF_GPIO && IRQ_DOMAIN
> +       help
> +         Say Y or M here to build support for the Synopsys DesignWare APB
> +         GPIO block.
> +
>  config GPIO_IT8761E
>         tristate "IT8761E GPIO support"
>         depends on X86  # unconditional access to IO space.
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 5d50179..2d09f04 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_CS5535)     += gpio-cs5535.o
>  obj-$(CONFIG_GPIO_DA9052)      += gpio-da9052.o
>  obj-$(CONFIG_GPIO_DA9055)      += gpio-da9055.o
>  obj-$(CONFIG_GPIO_DAVINCI)     += gpio-davinci.o
> +obj-$(CONFIG_GPIO_DWAPB)       += gpio-dwapb.o
>  obj-$(CONFIG_GPIO_EM)          += gpio-em.o
>  obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
>  obj-$(CONFIG_GPIO_F7188X)      += gpio-f7188x.o
> diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
> new file mode 100644
> index 0000000..2797fbb
> --- /dev/null
> +++ b/drivers/gpio/gpio-dwapb.c
> @@ -0,0 +1,438 @@
> +/*
> + * Copyright (c) 2011 Jamie Iles
> + *
> + * 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.
> + *
> + * All enquiries to support@picochip.com
> + */
> +#include <linux/basic_mmio_gpio.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +#define GPIO_SWPORTA_DR                0x00
> +#define GPIO_SWPORTA_DDR       0x04
> +#define GPIO_SWPORTB_DR                0x0c
> +#define GPIO_SWPORTB_DDR       0x10
> +#define GPIO_SWPORTC_DR                0x18
> +#define GPIO_SWPORTC_DDR       0x1c
> +#define GPIO_SWPORTD_DR                0x24
> +#define GPIO_SWPORTD_DDR       0x28
> +#define GPIO_INTEN             0x30
> +#define GPIO_INTMASK           0x34
> +#define GPIO_INTTYPE_LEVEL     0x38
> +#define GPIO_INT_POLARITY      0x3c
> +#define GPIO_INTSTATUS         0x40
> +#define GPIO_PORTA_EOI         0x4c
> +#define GPIO_EXT_PORTA         0x50
> +#define GPIO_EXT_PORTB         0x54
> +#define GPIO_EXT_PORTC         0x58
> +#define GPIO_EXT_PORTD         0x5c
> +
> +#define DWAPB_MAX_PORTS                4
> +#define GPIO_EXT_PORT_SIZE     (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
> +#define GPIO_SWPORT_DR_SIZE    (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
> +#define GPIO_SWPORT_DDR_SIZE   (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
> +
> +struct dwapb_gpio;
> +
> +struct dwapb_gpio_port {
> +       struct bgpio_chip       bgc;
> +       bool                    is_registered;
> +       struct dwapb_gpio       *gpio;
> +};
> +
> +struct dwapb_gpio {
> +       struct  device          *dev;
> +       void __iomem            *regs;
> +       struct dwapb_gpio_port  *ports;
> +       unsigned int            nr_ports;
> +       struct irq_domain       *domain;
> +};
> +
> +static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct bgpio_chip *bgc = to_bgpio_chip(gc);
> +       struct dwapb_gpio_port *port = container_of(bgc, struct
> +                                                   dwapb_gpio_port, bgc);
> +       struct dwapb_gpio *gpio = port->gpio;
> +
> +       return irq_find_mapping(gpio->domain, offset);
> +}
> +
> +static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
> +{
> +       u32 v = readl(gpio->regs + GPIO_INT_POLARITY);
> +
> +       if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs))
> +               v &= ~BIT(offs);
> +       else
> +               v |= BIT(offs);
> +
> +       writel(v, gpio->regs + GPIO_INT_POLARITY);
> +}
> +
> +static void dwapb_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> +       struct dwapb_gpio *gpio = irq_get_handler_data(irq);
> +       struct irq_chip *chip = irq_desc_get_chip(desc);
> +       u32 irq_status = readl_relaxed(gpio->regs + GPIO_INTSTATUS);
> +
> +       while (irq_status) {
> +               int hwirq = fls(irq_status) - 1;
> +               int gpio_irq = irq_find_mapping(gpio->domain, hwirq);
> +
> +               generic_handle_irq(gpio_irq);
> +               irq_status &= ~BIT(hwirq);
> +
> +               if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK)
> +                       == IRQ_TYPE_EDGE_BOTH)
> +                       dwapb_toggle_trigger(gpio, hwirq);
> +       }
> +
> +       if (chip->irq_eoi)
> +               chip->irq_eoi(irq_desc_get_irq_data(desc));
> +}
> +
> +static void dwapb_irq_enable(struct irq_data *d)
> +{
> +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> +       struct dwapb_gpio *gpio = igc->private;
> +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&bgc->lock, flags);
> +       val = readl(gpio->regs + GPIO_INTEN);
> +       val |= BIT(d->hwirq);
> +       writel(val, gpio->regs + GPIO_INTEN);
> +       spin_unlock_irqrestore(&bgc->lock, flags);
> +}
> +
> +static void dwapb_irq_disable(struct irq_data *d)
> +{
> +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> +       struct dwapb_gpio *gpio = igc->private;
> +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&bgc->lock, flags);
> +       val = readl(gpio->regs + GPIO_INTEN);
> +       val &= ~BIT(d->hwirq);
> +       writel(val, gpio->regs + GPIO_INTEN);
> +       spin_unlock_irqrestore(&bgc->lock, flags);
> +}
> +
> +static unsigned int dwapb_irq_startup(struct irq_data *d)
> +{
> +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> +       struct dwapb_gpio *gpio = igc->private;
> +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> +
> +       if (gpio_lock_as_irq(&bgc->gc, irqd_to_hwirq(d)))
> +               dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n",
> +                       irqd_to_hwirq(d));
> +       dwapb_irq_enable(d);
> +       return 0;
> +}
> +
> +static void dwapb_irq_shutdown(struct irq_data *d)
> +{
> +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> +       struct dwapb_gpio *gpio = igc->private;
> +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> +
> +       dwapb_irq_disable(d);
> +       gpio_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d));
> +}
> +
> +static int dwapb_irq_set_type(struct irq_data *d, u32 type)
> +{
> +       struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
> +       struct dwapb_gpio *gpio = igc->private;
> +       struct bgpio_chip *bgc = &gpio->ports[0].bgc;
> +       int bit = d->hwirq;
> +       unsigned long level, polarity, flags;
> +
> +       if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
> +                    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
> +               return -EINVAL;
> +
> +       spin_lock_irqsave(&bgc->lock, flags);
> +       level = readl(gpio->regs + GPIO_INTTYPE_LEVEL);
> +       polarity = readl(gpio->regs + GPIO_INT_POLARITY);
> +
> +       switch (type) {
> +       case IRQ_TYPE_EDGE_BOTH:
> +               level |= BIT(bit);
> +               dwapb_toggle_trigger(gpio, bit);
> +               break;
> +       case IRQ_TYPE_EDGE_RISING:
> +               level |= BIT(bit);
> +               polarity |= BIT(bit);
> +               break;
> +       case IRQ_TYPE_EDGE_FALLING:
> +               level |= BIT(bit);
> +               polarity &= ~BIT(bit);
> +               break;
> +       case IRQ_TYPE_LEVEL_HIGH:
> +               level &= ~BIT(bit);
> +               polarity |= BIT(bit);
> +               break;
> +       case IRQ_TYPE_LEVEL_LOW:
> +               level &= ~BIT(bit);
> +               polarity &= ~BIT(bit);
> +               break;
> +       }
> +
> +       writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
> +       writel(polarity, gpio->regs + GPIO_INT_POLARITY);
> +       spin_unlock_irqrestore(&bgc->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
> +                                struct dwapb_gpio_port *port)
> +{
> +       struct gpio_chip *gc = &port->bgc.gc;
> +       struct device_node *node =  gc->of_node;
> +       struct irq_chip_generic *irq_gc;
> +       unsigned int hwirq, ngpio = gc->ngpio;
> +       struct irq_chip_type *ct;
> +       int err, irq;
> +
> +       irq = irq_of_parse_and_map(node, 0);
> +       if (!irq) {
> +               dev_warn(gpio->dev, "no irq for bank %s\n",
> +                       port->bgc.gc.of_node->full_name);
> +               return;
> +       }
> +
> +       gpio->domain = irq_domain_add_linear(node, ngpio,
> +                                            &irq_generic_chip_ops, gpio);
> +       if (!gpio->domain)
> +               return;
> +
> +       err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1,
> +                                            "gpio-dwapb", handle_level_irq,
> +                                            IRQ_NOREQUEST, 0,
> +                                            IRQ_GC_INIT_NESTED_LOCK);
> +       if (err) {
> +               dev_info(gpio->dev, "irq_alloc_domain_generic_chips failed\n");
> +               irq_domain_remove(gpio->domain);
> +               gpio->domain = NULL;
> +               return;
> +       }
> +
> +       irq_gc = irq_get_domain_generic_chip(gpio->domain, 0);
> +       if (!irq_gc) {
> +               irq_domain_remove(gpio->domain);
> +               gpio->domain = NULL;
> +               return;
> +       }
> +
> +       irq_gc->reg_base = gpio->regs;
> +       irq_gc->private = gpio;
> +
> +       ct = irq_gc->chip_types;
> +       ct->chip.irq_ack = irq_gc_ack_set_bit;
> +       ct->chip.irq_mask = irq_gc_mask_set_bit;
> +       ct->chip.irq_unmask = irq_gc_mask_clr_bit;
> +       ct->chip.irq_set_type = dwapb_irq_set_type;
> +       ct->chip.irq_enable = dwapb_irq_enable;
> +       ct->chip.irq_disable = dwapb_irq_disable;
> +       ct->chip.irq_startup = dwapb_irq_startup;
> +       ct->chip.irq_shutdown = dwapb_irq_shutdown;
> +       ct->regs.ack = GPIO_PORTA_EOI;
> +       ct->regs.mask = GPIO_INTMASK;
> +
> +       irq_setup_generic_chip(irq_gc, IRQ_MSK(port->bgc.gc.ngpio),
> +                       IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
> +
> +       irq_set_chained_handler(irq, dwapb_irq_handler);
> +       irq_set_handler_data(irq, gpio);
> +
> +       for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
> +               irq_create_mapping(gpio->domain, hwirq);
> +
> +       port->bgc.gc.to_irq = dwapb_gpio_to_irq;
> +}
> +
> +static void dwapb_irq_teardown(struct dwapb_gpio *gpio)
> +{
> +       struct dwapb_gpio_port *port = &gpio->ports[0];
> +       struct gpio_chip *gc = &port->bgc.gc;
> +       unsigned int ngpio = gc->ngpio;
> +       irq_hw_number_t hwirq;
> +
> +       if (!gpio->domain)
> +               return;
> +
> +       for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
> +               irq_dispose_mapping(irq_find_mapping(gpio->domain, hwirq));
> +
> +       irq_domain_remove(gpio->domain);
> +       gpio->domain = NULL;
> +}
> +
> +static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
> +                              struct device_node *port_np,
> +                              unsigned int offs)
> +{
> +       struct dwapb_gpio_port *port;
> +       u32 port_idx, ngpio;
> +       void __iomem *dat, *set, *dirout;
> +       int err;
> +
> +       if (of_property_read_u32(port_np, "reg", &port_idx) ||
> +               port_idx >= DWAPB_MAX_PORTS) {
> +               dev_err(gpio->dev, "missing/invalid port index for %s\n",
> +                       port_np->full_name);
> +               return -EINVAL;
> +       }
> +
> +       port = &gpio->ports[offs];
> +       port->gpio = gpio;
> +
> +       if (of_property_read_u32(port_np, "snps,nr-gpios", &ngpio)) {
> +               dev_info(gpio->dev, "failed to get number of gpios for %s\n",
> +                        port_np->full_name);
> +               ngpio = 32;
> +       }
> +
> +       dat = gpio->regs + GPIO_EXT_PORTA + (port_idx * GPIO_EXT_PORT_SIZE);
> +       set = gpio->regs + GPIO_SWPORTA_DR + (port_idx * GPIO_SWPORT_DR_SIZE);
> +       dirout = gpio->regs + GPIO_SWPORTA_DDR +
> +               (port_idx * GPIO_SWPORT_DDR_SIZE);
> +
> +       err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout,
> +                        NULL, false);
> +       if (err) {
> +               dev_err(gpio->dev, "failed to init gpio chip for %s\n",
> +                       port_np->full_name);
> +               return err;
> +       }
> +
> +       port->bgc.gc.ngpio = ngpio;
> +       port->bgc.gc.of_node = port_np;
> +
> +       /*
> +        * Only port A can provide interrupts in all configurations of the IP.
> +        */
> +       if (port_idx == 0 &&
> +           of_property_read_bool(port_np, "interrupt-controller"))
> +               dwapb_configure_irqs(gpio, port);
> +
> +       err = gpiochip_add(&port->bgc.gc);
> +       if (err)
> +               dev_err(gpio->dev, "failed to register gpiochip for %s\n",
> +                       port_np->full_name);
> +       else
> +               port->is_registered = true;
> +
> +       return err;
> +}
> +
> +static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
> +{
> +       unsigned int m;
> +
> +       for (m = 0; m < gpio->nr_ports; ++m)
> +               if (gpio->ports[m].is_registered)
> +                       WARN_ON(gpiochip_remove(&gpio->ports[m].bgc.gc));
> +}
> +
> +static int dwapb_gpio_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct dwapb_gpio *gpio;
> +       struct device_node *np;
> +       int err;
> +       unsigned int offs = 0;
> +
> +       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> +       if (!gpio)
> +               return -ENOMEM;
> +       gpio->dev = &pdev->dev;
> +
> +       gpio->nr_ports = of_get_child_count(pdev->dev.of_node);
> +       if (!gpio->nr_ports) {
> +               err = -EINVAL;
> +               goto out_err;
> +       }
> +       gpio->ports = devm_kzalloc(&pdev->dev, gpio->nr_ports *
> +                                  sizeof(*gpio->ports), GFP_KERNEL);
> +       if (!gpio->ports) {
> +               err = -ENOMEM;
> +               goto out_err;
> +       }
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       gpio->regs = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(gpio->regs)) {
> +               err = PTR_ERR(gpio->regs);
> +               goto out_err;
> +       }
> +
> +       for_each_child_of_node(pdev->dev.of_node, np) {
> +               err = dwapb_gpio_add_port(gpio, np, offs++);
> +               if (err)
> +                       goto out_unregister;
> +       }
> +       platform_set_drvdata(pdev, gpio);
> +
> +       return 0;
> +
> +out_unregister:
> +       dwapb_gpio_unregister(gpio);
> +       dwapb_irq_teardown(gpio);
> +
> +out_err:
> +       return err;
> +}
> +
> +static int dwapb_gpio_remove(struct platform_device *pdev)
> +{
> +       struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
> +
> +       dwapb_gpio_unregister(gpio);
> +       dwapb_irq_teardown(gpio);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id dwapb_of_match[] = {
> +       { .compatible = "snps,dw-apb-gpio" },
> +       { /* Sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, dwapb_of_match);
> +
> +static struct platform_driver dwapb_gpio_driver = {
> +       .driver         = {
> +               .name   = "gpio-dwapb",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = of_match_ptr(dwapb_of_match),
> +       },
> +       .probe          = dwapb_gpio_probe,
> +       .remove         = dwapb_gpio_remove,
> +};
> +
> +module_platform_driver(dwapb_gpio_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Jamie Iles");
> +MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");
> --
> 1.7.9.5
>

^ permalink raw reply

* Re: [PATCH v4 3/3] Documentation: of: Document graph bindings
From: Philipp Zabel @ 2014-02-26 15:47 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Russell King - ARM Linux, Mauro Carvalho Chehab, Grant Likely,
	Rob Herring, Sylwester Nawrocki, Laurent Pinchart, Kyungmin Park,
	linux-kernel, linux-media, devicetree, Guennadi Liakhovetski
In-Reply-To: <530DFF4C.8080807@ti.com>

Am Mittwoch, den 26.02.2014, 16:50 +0200 schrieb Tomi Valkeinen:
> On 26/02/14 16:57, Philipp Zabel wrote:
> > Hi Tomi,
> > 
> > Am Mittwoch, den 26.02.2014, 15:14 +0200 schrieb Tomi Valkeinen:
> >> On 25/02/14 16:58, Philipp Zabel wrote:
> >>
> >>> +Optional endpoint properties
> >>> +----------------------------
> >>> +
> >>> +- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node.
> >>
> >> Why is that optional? What use is an endpoint, if it's not connected to
> >> something?
> > 
> > This allows to include the an empty endpoint template in a SoC dtsi for
> > the convenience of board dts writers. Also, the same property is
> > currently listed as optional in video-interfaces.txt.
> > 
> >   soc.dtsi:
> > 	display-controller {
> > 		port {
> > 			disp0: endpoint { };
> > 		};
> > 	};
> > 
> >   board.dts:
> > 	#include "soc.dtsi"
> > 	&disp0 {
> > 		remote-endpoint = <&panel_input>;
> > 	};
> > 	panel {
> > 		port {
> > 			panel_in: endpoint {
> > 				remote-endpoint = <&disp0>;
> > 			};
> > 		};
> > 	};
> > 
> > Any board not using that port can just leave the endpoint disconnected.
> 
> Hmm I see. I'm against that.
> 
> I think the SoC dtsi should not contain endpoint node, or even port node
> (at least usually).

Well, at least the port is a physical thing. I see no reason not to have
it in the dtsi.

> It doesn't know how many endpoints, if any, a
> particular board has. That part should be up to the board dts.

...

> I've done this with OMAP as (much simplified):
> 
> SoC.dtsi:
> 
> dss: dss@58000000 {
> 	status = "disabled";
> };
> 
> Nothing else (relevant here). The binding documentation states that dss
> has one port, and information what data is needed for the port and endpoint.
> 
> board.dts:
> 
> &dss {
>         status = "ok";
> 
>         pinctrl-names = "default";
>         pinctrl-0 = <&dss_dpi_pins>;
> 
>         dpi_out: endpoint {
> 
>                 remote-endpoint = <&tfp410_in>;
>                 data-lines = <24>;
>         };
> };
> 
> That's using the shortened version without port node.

Ok, that looks compact enough. I still don't see the need to change make
the remote-endpoint property required to achieve this, though. On the
other hand, I wouldn't object to making it mandatory either.

> Of course, it's up to the developer how his dts looks like. But to me it
> makes sense to require the remote-endpoint property, as the endpoint, or
> even the port, doesn't make much sense if there's nothing to connect to.

Please let's not make it mandatory for a port node to contain an
endpoint. For any device with multiple ports we can't use the simplified
form above, and only adding the (correctly numbered) port in all the
board device trees would be a pain.

regards
Philipp

^ permalink raw reply

* Re: [PATCH v4] can: xilinx CAN controller support.
From: Marc Kleine-Budde @ 2014-02-26 15:43 UTC (permalink / raw)
  To: Appana Durga Kedareswara Rao, wg@grandegger.com, Michal Simek,
	grant.likely@linaro.org, robh+dt@kernel.org,
	linux-can@vger.kernel.org
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <678ca296-8687-4e7c-9014-ae69d886a068@CO9EHSMHS014.ehs.local>

[-- Attachment #1: Type: text/plain, Size: 4901 bytes --]

On 02/26/2014 03:46 PM, Appana Durga Kedareswara Rao wrote:
> Hi Marc,
> 
> 
>> -----Original Message-----
>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>> Sent: Wednesday, February 26, 2014 6:52 PM
>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
>> grant.likely@linaro.org; robh+dt@kernel.org; linux-can@vger.kernel.org
>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>> kernel@vger.kernel.org; devicetree@vger.kernel.org
>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>>
>> On 02/26/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
>>>> This loop looks broken. Can you explain how it works.
>>>>
>>>> What it shoud do is:
>>>> We have put (priv->tx_head - priv->tx_tail) CAN frames into the FIFO.
>>>> This means at maximum there could be this amount of CAN frames which
>>>> have been successfully transmitted. For every cycle in this while
>>>> loop you
>>>> should:
>>>> a) check if a CAN frame has successfully been transmitted
>>>>    (as this CAN core uses a FIFO it should be "oldest")
>>>>    A read_reg() of some kind is missing in your loop.
>>>> b) if needed, remove this event from the FIFO or
>>>>    mark the interrupt as done. Whatever you hardware needs.
>>>> c) update your statistics
>>>> d) Use can_get_echo_skb to push this frame into the networking stack
>>>> e) As a CAN frame has been transmitted successfully, wake the tx_queue.
>>>>
>>>>> +   while (priv->tx_head - priv->tx_tail > 0) {
>>>>> +           if (isr & XCAN_IXR_TXFLL_MASK) {
>>>>> +                   priv->write_reg(priv, XCAN_ICR_OFFSET,
>>>>> +                                   XCAN_IXR_TXFLL_MASK);
>>>>> +                   netif_stop_queue(ndev);
>>>>
>>>> Why do you stop the queue here? A CAN frame has successfully been
>>>> transmitted, there should be room in the FIFO.
>>>>
>>>>> +                   break;
>>>>> +           }
>>>>> +           can_get_echo_skb(ndev, priv->tx_tail %
>>>>> +                                   priv->xcan_echo_skb_max_tx);
>>>>> +           priv->tx_tail++;
>>>>> +   }
>>>>> +
>>>
>>> The below are the bit fields available for the Transmit FIFO.
>>> 1) In the ISR(interrupt status register)  Tx Ok interrupt and Tx fifo full
>> interrupt.
>>> 2) in the SR(Status Register) Tx fifo full condition.
>>>
>>>
>>> I am modifying the entire tx interrupt logic to like below.
>>>
>>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
>>>         struct xcan_priv *priv = netdev_priv(ndev);
>>>         struct net_device_stats *stats = &ndev->stats;
>>>
>>>             while (priv->tx_head - priv->tx_tail > 0) {
>>>                 if (isr & XCAN_IXR_TXFLL_MASK) {
>>>                         priv->write_reg(priv, XCAN_ICR_OFFSET,
>>>                                         XCAN_IXR_TXFLL_MASK);
>>>                           break;
>>>                 }
>>>                 can_get_echo_skb(ndev, priv->tx_tail %
>>>                                         priv->xcan_echo_skb_max_tx);
>>>                 priv->tx_tail++;
>>>          stats->tx_packets++;
>>>         netif_wake_queue(ndev);
>>>               can_led_event(ndev, CAN_LED_EVENT_TX);
>>>
>>>         }
>>
>> You just need to wake the queue once.
> 
> Ok
>>
>>> }
>>>
>>>
>>> Are you Ok with the above logic?
>>
>> No, how can you tell how many frames have been transmitted?
> 
> There is no register to read how many can frames are transmitted.
> The only way to know Is by reading this parameter (stats->tx_packets++;) through ip command

stats->tx_packets is calculated in the above loop and the loop is
broken. Let me illustrate the problem:

- xmit is called 10 times in a row
- this means you have 10 CAN frames in the TX FIFO
- a single CAN frame gets transmitted
- you get an interrupt
- you enter the above routine and loop 10 times and echo the CAN frame
  back into the stack

Now every application sees 10 transmitted packages, but there is only
one transmitted. Every time you loop you have to check if the CAN frame
has already been transmitted or not. Is that possible with the hardware?

> ip -d -s link show can
> Or using ifconfig command.
> 
> At the h/w level it can transmit Max upto 64 packets (Max fifo depth)
> We need to monitor the Tx fifo full bit in the ISR(Interrupt Status Register)  or Tx fifo full bit in the SR(Status Register) and if it is full we need to stop the queue that is
> I am doing in the _xmit by reading the status register before proceeding the   packet transmission.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]

^ permalink raw reply

* Re: [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
From: Felipe Balbi @ 2014-02-26 15:41 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dmitry.torokhov, rydberg, jcbian, balbi, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree
In-Reply-To: <1393428486-15001-4-git-send-email-rogerq@ti.com>

[-- Attachment #1: Type: text/plain, Size: 271 bytes --]

On Wed, Feb 26, 2014 at 05:28:01PM +0200, Roger Quadros wrote:
> Get rid of the attb_read_val() platform hook. Instead,
> read the ATTB gpio directly from the driver.
> 
> Fail if valid ATTB gpio is not provided by patform data.

s/patform/platform/

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* [PATCH v2 8/8] ARM: dts: am43x-epos-evm: Correct Touch controller info
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros, Benoit Cousson,
	Tony Lindgren
In-Reply-To: <1393428486-15001-1-git-send-email-rogerq@ti.com>

Fixup Y resolution and add default pin state. Also update
the compatible id.

CC: Benoit Cousson <bcousson@baylibre.com>
CC: Tony Lindgren <tony@atomide.com>
CC: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 arch/arm/boot/dts/am43x-epos-evm.dts | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index fbf9c4c..6c8efcf 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -79,6 +79,13 @@
 				0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
 			>;
 		};
+
+		pixcir_ts_pins: pixcir_ts_pins {
+			pinctrl-single,pins = <
+				0x44 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_a1.gpio1_17 */
+			>;
+		};
+
 	};
 
 	matrix_keypad: matrix_keypad@0 {
@@ -157,7 +164,9 @@
 	};
 
 	pixcir_ts@5c {
-		compatible = "pixcir,pixcir_ts";
+		compatible = "pixcir,pixcir_tangoc";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pixcir_ts_pins>;
 		reg = <0x5c>;
 		interrupt-parent = <&gpio1>;
 		interrupts = <17 0>;
@@ -165,7 +174,7 @@
 		attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
 
 		x-size = <1024>;
-		y-size = <768>;
+		y-size = <600>;
 	};
 };
 
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v2 7/8] Input: pixcir_i2c_ts: Add device tree support
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros
In-Reply-To: <1393428486-15001-1-git-send-email-rogerq@ti.com>

Provide device tree support and binding information.
Also provide support for a new chip "pixcir_tangoc".

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 .../bindings/input/touchscreen/pixcir_i2c_ts.txt   | 26 ++++++++
 .../devicetree/bindings/vendor-prefixes.txt        |  1 +
 drivers/input/touchscreen/pixcir_i2c_ts.c          | 78 ++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
new file mode 100644
index 0000000..0ab9505
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
@@ -0,0 +1,26 @@
+* Pixcir I2C touchscreen controllers
+
+Required properties:
+- compatible: must be "pixcir,pixcir_ts" or "pixcir,pixcir_tangoc"
+- reg: I2C address of the chip
+- interrupts: interrupt to which the chip is connected
+- attb-gpio: GPIO connected to the ATTB line of the chip
+- x-size: horizontal resolution of touchscreen
+- y-size: vertical resolution of touchscreen
+
+Example:
+
+	i2c@00000000 {
+		/* ... */
+
+		pixcir_ts@5c {
+			compatible = "pixcir,pixcir_ts";
+			reg = <0x5c>;
+			interrupts = <2 0>;
+			attb-gpio = <&gpf 2 0 2>;
+			x-size = <800>;
+			y-size = <600>;
+		};
+
+		/* ... */
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 40ce2df..d2324b7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -65,6 +65,7 @@ onnn	ON Semiconductor Corp.
 panasonic	Panasonic Corporation
 phytec	PHYTEC Messtechnik GmbH
 picochip	Picochip Ltd
+pixcir  PIXCIR MICROELECTRONICS Co., Ltd
 powervr	PowerVR (deprecated, use img)
 qca	Qualcomm Atheros, Inc.
 qcom	Qualcomm Technologies, Inc
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8ca258b..bb6b42a 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -26,6 +26,9 @@
 #include <linux/input/mt.h>
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
@@ -404,16 +407,70 @@ unlock:
 static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
 			 pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
 
+#ifdef CONFIG_OF
+static const struct of_device_id pixcir_of_match[];
+
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	struct pixcir_ts_platform_data *pdata;
+	struct device_node *np = dev->of_node;
+
+	const struct of_device_id *match;
+
+	match = of_match_device(of_match_ptr(pixcir_of_match), dev);
+	if (!match)
+		return ERR_PTR(-EINVAL);
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->chip = *(const struct pixcir_i2c_chip_data *)match->data;
+
+	pdata->gpio_attb = of_get_named_gpio(np, "attb-gpio", 0);
+	/* gpio_attb validity is checked in probe */
+
+	if (of_property_read_u32(np, "x-size", &pdata->x_max)) {
+		dev_err(dev, "Failed to get x-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->x_max -= 1;
+
+	if (of_property_read_u32(np, "y-size", &pdata->y_max)) {
+		dev_err(dev, "Failed to get y-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->y_max -= 1;
+
+	dev_dbg(dev, "%s: x %d, y %d, gpio %d\n", __func__,
+		pdata->x_max + 1, pdata->y_max + 1, pdata->gpio_attb);
+
+	return pdata;
+}
+#else
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int pixcir_i2c_ts_probe(struct i2c_client *client,
 					 const struct i2c_device_id *id)
 {
 	const struct pixcir_ts_platform_data *pdata =
 			dev_get_platdata(&client->dev);
 	struct device *dev = &client->dev;
+	struct device_node *np = dev->of_node;
 	struct pixcir_i2c_ts_data *tsdata;
 	struct input_dev *input;
 	int error;
 
+	if (np && !pdata) {
+		pdata = pixcir_parse_dt(dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	}
+
 	if (!pdata) {
 		dev_err(&client->dev, "platform data not defined\n");
 		return -EINVAL;
@@ -524,15 +581,36 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 static const struct i2c_device_id pixcir_i2c_ts_id[] = {
 	{ "pixcir_ts", 0 },
+	{ "pixcir_tangoc", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
 
+#ifdef CONFIG_OF
+static const struct pixcir_i2c_chip_data pixcir_ts_data = {
+	.max_fingers = 2,
+	/* no hw id support */
+};
+
+static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
+	.max_fingers = 5,
+	.has_hw_ids = true,
+};
+
+static const struct of_device_id pixcir_of_match[] = {
+	{ .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data },
+	{ .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pixcir_of_match);
+#endif
+
 static struct i2c_driver pixcir_i2c_ts_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
 		.name	= "pixcir_ts",
 		.pm	= &pixcir_dev_pm_ops,
+		.of_match_table = of_match_ptr(pixcir_of_match),
 	},
 	.probe		= pixcir_i2c_ts_probe,
 	.remove		= pixcir_i2c_ts_remove,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v2 6/8] Input: pixcir_i2c_ts: Implement wakeup from suspend
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros
In-Reply-To: <1393428486-15001-1-git-send-email-rogerq@ti.com>

Improve the suspend and resume handlers to allow the device
to wakeup the system from suspend.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 46 ++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index b1e92f6..8ca258b 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -345,21 +345,59 @@ static void pixcir_input_close(struct input_dev *dev)
 static int pixcir_i2c_ts_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
+
+	if (device_may_wakeup(&client->dev)) {
+		/* need to start device if not open, to be wakeup source */
+		if (!input->users) {
+			ret = pixcir_start(ts);
+			if (ret)
+				goto unlock;
+		}
 
-	if (device_may_wakeup(&client->dev))
 		enable_irq_wake(client->irq);
 
-	return 0;
+	} else if (input->users) {
+		ret = pixcir_stop(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 
 static int pixcir_i2c_ts_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
 
-	if (device_may_wakeup(&client->dev))
+	if (device_may_wakeup(&client->dev)) {
 		disable_irq_wake(client->irq);
 
-	return 0;
+		/* need to stop device if it was not open on suspend */
+		if (!input->users) {
+			ret = pixcir_stop(ts);
+			if (ret)
+				goto unlock;
+		}
+
+	} else if (input->users) {
+		ret = pixcir_start(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 #endif
 
-- 
1.8.3.2

^ permalink raw reply related


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