Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757052AbcCRKen (ORCPT ); Fri, 18 Mar 2016 06:34:43 -0400 Received: from down.free-electrons.com ([37.187.137.238]:41962 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755092AbcCRKed (ORCPT ); Fri, 18 Mar 2016 06:34:33 -0400 Date: Fri, 18 Mar 2016 11:34:18 +0100 From: Alexandre Belloni To: Ludovic Desroches Cc: nicolas.ferre@atmel.com, plagnioj@jcrosoft.com, boris.brezillon@free-electrons.com, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/3] ARM: at91: use chipid device for soc detection Message-ID: <20160318103418.GA2531@piout.net> References: <1458285681-25684-1-git-send-email-ludovic.desroches@atmel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1458285681-25684-1-git-send-email-ludovic.desroches@atmel.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5310 Lines: 169 On 18/03/2016 at 08:21:19 +0100, Ludovic Desroches wrote : > So far, the CIDR and EXID registers were in the DBGU interface. This device > has disappeared with the SAMA5D2 family. These registers are exposed > through a new device called chipid. > > Signed-off-by: Ludovic Desroches > [nicolas.ferre@atmel.com: remove useless warnings] Acked-by: Alexandre Belloni > --- > .../devicetree/bindings/arm/atmel-at91.txt | 4 ++ > arch/arm/mach-at91/soc.c | 81 +++++++++++++++++----- > 2 files changed, 67 insertions(+), 18 deletions(-) > > diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt > index 7fd64ec..0b1fcbf 100644 > --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt > +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt > @@ -41,6 +41,10 @@ compatible: must be one of: > - "atmel,sama5d43" > - "atmel,sama5d44" > > +Chipid required properties: > +- compatible: Should be "atmel,sama5d2-chipid" > +- reg : Should contain registers location and length > + > PIT Timer required properties: > - compatible: Should be "atmel,at91sam9260-pit" > - reg: Should contain registers location and length > diff --git a/arch/arm/mach-at91/soc.c b/arch/arm/mach-at91/soc.c > index 54343ff..034d563 100644 > --- a/arch/arm/mach-at91/soc.c > +++ b/arch/arm/mach-at91/soc.c > @@ -22,48 +22,93 @@ > #include "soc.h" > > #define AT91_DBGU_CIDR 0x40 > -#define AT91_DBGU_CIDR_VERSION(x) ((x) & 0x1f) > -#define AT91_DBGU_CIDR_EXT BIT(31) > -#define AT91_DBGU_CIDR_MATCH_MASK 0x7fffffe0 > #define AT91_DBGU_EXID 0x44 > +#define AT91_CHIPID_CIDR 0x00 > +#define AT91_CHIPID_EXID 0x04 > +#define AT91_CIDR_VERSION(x) ((x) & 0x1f) > +#define AT91_CIDR_EXT BIT(31) > +#define AT91_CIDR_MATCH_MASK 0x7fffffe0 > > -struct soc_device * __init at91_soc_init(const struct at91_soc *socs) > +int __init at91_get_cidr_exid_from_dbgu(u32 *cidr, u32 *exid) > { > - struct soc_device_attribute *soc_dev_attr; > - const struct at91_soc *soc; > - struct soc_device *soc_dev; > struct device_node *np; > void __iomem *regs; > - u32 cidr, exid; > > np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-dbgu"); > if (!np) > np = of_find_compatible_node(NULL, NULL, > "atmel,at91sam9260-dbgu"); > + if (!np) > + return -ENODEV; > > - if (!np) { > - pr_warn("Could not find DBGU node"); > - return NULL; > + regs = of_iomap(np, 0); > + of_node_put(np); > + > + if (!regs) { > + pr_warn("Could not map DBGU iomem range"); > + return -ENXIO; > } > > + *cidr = readl(regs + AT91_DBGU_CIDR); > + *exid = readl(regs + AT91_DBGU_EXID); > + > + iounmap(regs); > + > + return 0; > +} > + > +int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) > +{ > + struct device_node *np; > + void __iomem *regs; > + > + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-chipid"); > + if (!np) > + return -ENODEV; > + > regs = of_iomap(np, 0); > of_node_put(np); > > if (!regs) { > pr_warn("Could not map DBGU iomem range"); > - return NULL; > + return -ENXIO; > } > > - cidr = readl(regs + AT91_DBGU_CIDR); > - exid = readl(regs + AT91_DBGU_EXID); > + *cidr = readl(regs + AT91_CHIPID_CIDR); > + *exid = readl(regs + AT91_CHIPID_EXID); > > iounmap(regs); > > + return 0; > +} > + > +struct soc_device * __init at91_soc_init(const struct at91_soc *socs) > +{ > + struct soc_device_attribute *soc_dev_attr; > + const struct at91_soc *soc; > + struct soc_device *soc_dev; > + u32 cidr, exid; > + int ret; > + > + /* > + * With SAMA5D2 and later SoCs, CIDR and EXID registers are no more > + * in the dbgu device but in the chipid device whose purpose is only > + * to expose these two registers. > + */ > + ret = at91_get_cidr_exid_from_dbgu(&cidr, &exid); > + if (ret) > + ret = at91_get_cidr_exid_from_chipid(&cidr, &exid); > + if (ret) { > + if (ret == -ENODEV) > + pr_warn("Could not find identification node"); > + return NULL; > + } > + > for (soc = socs; soc->name; soc++) { > - if (soc->cidr_match != (cidr & AT91_DBGU_CIDR_MATCH_MASK)) > + if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) > continue; > > - if (!(cidr & AT91_DBGU_CIDR_EXT) || soc->exid_match == exid) > + if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) > break; > } > > @@ -79,7 +124,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) > soc_dev_attr->family = soc->family; > soc_dev_attr->soc_id = soc->name; > soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", > - AT91_DBGU_CIDR_VERSION(cidr)); > + AT91_CIDR_VERSION(cidr)); > soc_dev = soc_device_register(soc_dev_attr); > if (IS_ERR(soc_dev)) { > kfree(soc_dev_attr->revision); > @@ -91,7 +136,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) > if (soc->family) > pr_info("Detected SoC family: %s\n", soc->family); > pr_info("Detected SoC: %s, revision %X\n", soc->name, > - AT91_DBGU_CIDR_VERSION(cidr)); > + AT91_CIDR_VERSION(cidr)); > > return soc_dev; > } > -- > 2.5.0 > -- Alexandre Belloni, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com