* [PATCH 03/21] ARM: Kirkwood: Convert mv88f6281gtw_ge switch setup to DT
From: Andrew Lunn @ 2014-02-07 9:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207092505.4a0e9963@skate>
On Fri, Feb 07, 2014 at 09:25:05AM +0100, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Fri, 7 Feb 2014 00:41:59 +0100, Andrew Lunn wrote:
> > The mv88f6281gtw_ge has a ethernet switch connected to the ethernet
> > port of the SoC. Convert the platform device instantiationn to a DT
> > instantiation.
> >
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > ---
> > arch/arm/mach-kirkwood/Kconfig | 7 ----
> > arch/arm/mach-kirkwood/Makefile | 1 -
> > arch/arm/mach-kirkwood/Module.symvers | 0
> > arch/arm/mach-kirkwood/board-dt.c | 3 --
> > arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c | 50 --------------------------
> > arch/arm/mach-kirkwood/common.h | 7 ----
> > 6 files changed, 68 deletions(-)
> > create mode 100644 arch/arm/mach-kirkwood/Module.symvers
>
> This is probably a mistake.
>
> > delete mode 100644 arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c
>
> Hum, I maybe missed something, but where are the corresponding DT
> informations added to replace the C description of the Ethernet switch?
Hi Thomas
Yes, i screwed that patch up somewhere.
It will be fixed in v2.
Andrew
^ permalink raw reply
* [PATCH 01/18] arm64: initial support for GICv3
From: Arnab Basu @ 2014-02-07 8:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391607050-540-2-git-send-email-marc.zyngier@arm.com>
Hi Marc
Marc Zyngier <marc.zyngier <at> arm.com> writes:
> +
> +static inline void __iomem *gic_dist_base(struct irq_data *d)
I would suggest that this function be renamed (something like
gic_base_for_irq?) since it returns dist or redist sgi base address. The
name suggests it always returns the dist base address.
> +{
> + if (d->hwirq < 32) /* SGI+PPI -> SGI_base for this CPU */
> + return gic_data_rdist_sgi_base();
> +
> + if (d->hwirq <= 1023) /* SPI -> dist_base */
> + return gic_data.dist_base;
> +
> + if (d->hwirq >= 8192)
> + BUG(); /* LPI Detected!!! */
> +
> + return NULL;
> +}
> +
> +static inline unsigned int gic_irq(struct irq_data *d)
> +{
> + return d->hwirq;
> +}
> +
> +static void gic_do_wait_for_rwp(void __iomem *base)
> +{
> + u32 val;
> +
> + do {
> + val = readl_relaxed(base + GICD_CTLR);
Maybe rename GICD_CTLR to GICx_CTLR since it is being used for both the
distributor and the redistributor.
> + cpu_relax();
> + } while (val & GICD_CTLR_RWP);
Similar to above GICx_CTLR_RWP
> +
> +static int gic_irq_domain_xlate(struct irq_domain *d,
> + struct device_node *controller,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != controller)
> + return -EINVAL;
> + if (intsize < 3)
> + return -EINVAL;
> +
> + switch(intspec[0]) {
> + case 0: /* SPI */
> + *out_hwirq = intspec[1] + 32;
> + break;
> + case 1: /* PPI */
> + *out_hwirq = intspec[1] + 16;
> + break;
I wonder if there is any value to syncing these with the defines in
"include/dt-bindings/interrupt-controller/arm-gic.h" somehow.
Thanks
Arnab
^ permalink raw reply
* [PATCH v3 05/15] ARM: at91: move sam9261 SoC to common clk
From: Boris BREZILLON @ 2014-02-07 8:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-6-git-send-email-jjhiblot@traphandler.com>
Hello JJ,
On 23/01/2014 16:57, Jean-Jacques Hiblot wrote:
> This patch removes the selection of AT91_USE_OLD_CLK when selecting
> sam9261 SoCs support. This will automatically enable COMMON_CLK_AT91 option
> and add support for at91 common clk implementation.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> arch/arm/mach-at91/Kconfig | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index b4f7d6f..2214beb 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -120,7 +120,6 @@ config SOC_AT91SAM9261
> select HAVE_AT91_DBGU0
> select HAVE_FB_ATMEL
> select SOC_AT91SAM9
> - select AT91_USE_OLD_CLK
> select HAVE_AT91_USB_CLK
add :
depends on COMMON_CLK
if you want to get rid of DT related clk_lookup definitions.
You'll also have to remove all the AT91SAM9261 sections from Kconfig.non_dt,
because this will conflict with the "depends on COMMON_CLK" line (the
ARCH_AT91SAM9261 config selects AT91_USE_OLD_CLK which forbids the use
of CCF).
I'm not sure droping the clk_lookup definitions worth the trouble, but
I'll let at91
maintainers decide.
Best Regards,
Boris
> help
> Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
^ permalink raw reply
* [PATCH 1/2] i2c-s3c2410: Leave the bus disabled unless it is in use
From: Naveen Krishna Ch @ 2014-02-07 8:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130124122036.GF12933@pengutronix.de>
Hello Wolfram,
Sorry for a replying after really long time.
On 24 January 2013 17:50, Wolfram Sang <w.sang@pengutronix.de> wrote:
> On Thu, Nov 29, 2012 at 10:35:34AM +0530, Naveen Krishna Chatradhi wrote:
>> From: Simon Glass <sjg@chromium.org>
>>
>> There is a rather odd feature of the exynos i2c controller that if it
>> is left enabled, it can lock itself up with the clk line held low.
>> This makes the bus unusable.
>>
>> Unfortunately, the s3c24xx_i2c_set_master() function does not notice
>> this, and reports a timeout. From then on the bus cannot be used until
>> the AP is rebooted.
>>
>> The problem happens when any sort of interrupt occurs (e.g. due to a
>> bus transition) when we are not in the middle of a transaction. We
>> have seen many instances of this when U-Boot leaves the bus apparently
>> happy, but Linux cannot access it.
>>
>> The current code is therefore pretty fragile.
>>
>> This fixes things by leaving the bus disabled unless we are actually
>> in a transaction. We enable the bus at the start of the transaction and
>> disable it at the end. That way we won't get interrupts and will not
>> lock up the bus.
>>
>> It might be possible to clear pending interrupts on start-up, but this
>> seems to be a more robust solution. We can't service interrupts when
>> we are not in a transaction, and anyway would rather not lock up the
>> bus while we try.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Cc: Grant Grundler <grundler@chromium.org>
>> Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
>
> So, I assume this patch is still needed despite the ongoing discussion
> about arbitration?
Yes, this is an i2c crontroller fix.
>
>> ---
>> drivers/i2c/busses/i2c-s3c2410.c | 37 +++++++++++++++++++++++++++++++++----
>> 1 file changed, 33 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
>> index e93e7d6..2fd346d 100644
>> --- a/drivers/i2c/busses/i2c-s3c2410.c
>> +++ b/drivers/i2c/busses/i2c-s3c2410.c
>> @@ -186,6 +186,31 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
>> writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
>> }
>>
>> +/*
>> + * Disable the bus so that we won't get any interrupts from now on, or try
>> + * to drive any lines. This is the default state when we don't have
>> + * anything to send/receive.
>> + *
>> + * If there is an event on the bus, or we have a pre-existing event at
>
> Otherwise, if...
>
>> + * kernel boot time, we may not notice the event and the I2C controller
>> + * will lock the bus with the I2C clock line low indefinitely.
>> + */
>> +static inline void s3c24xx_i2c_disable_bus(struct s3c24xx_i2c *i2c)
>> +{
>> + unsigned long tmp;
>> +
>> + /* Stop driving the I2C pins */
>> + tmp = readl(i2c->regs + S3C2410_IICSTAT);
>> + tmp &= ~S3C2410_IICSTAT_TXRXEN;
>> + writel(tmp, i2c->regs + S3C2410_IICSTAT);
>> +
>> + /* We don't expect any interrupts now, and don't want send acks */
>> + tmp = readl(i2c->regs + S3C2410_IICCON);
>> + tmp &= ~(S3C2410_IICCON_IRQEN | S3C2410_IICCON_IRQPEND |
>> + S3C2410_IICCON_ACKEN);
>> + writel(tmp, i2c->regs + S3C2410_IICCON);
>> +}
>> +
>>
>> /* s3c24xx_i2c_message_start
>> *
>> @@ -646,7 +671,11 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
>>
>> s3c24xx_i2c_wait_idle(i2c);
>>
>> + s3c24xx_i2c_disable_bus(i2c);
>> +
>> out:
>> + i2c->state = STATE_IDLE;
>> +
>
> Why is the state change after the label?
As the interrupts are enabled in the beginning of this function.
and interrupts in STATE_IDLE needs handling in a different way.
This was added with the intention the irq routine will handle the cases
>
>> return ret;
>> }
>>
>> @@ -912,7 +941,6 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)
>>
>> static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
>> {
>> - unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;
>> struct s3c2410_platform_i2c *pdata;
>> unsigned int freq;
>>
>> @@ -926,12 +954,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
>>
>> dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
>>
>> - writel(iicon, i2c->regs + S3C2410_IICCON);
>> + writel(0, i2c->regs + S3C2410_IICCON);
>> + writel(0, i2c->regs + S3C2410_IICSTAT);
>>
>> /* we need to work out the divisors for the clock... */
>>
>> if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
>> - writel(0, i2c->regs + S3C2410_IICCON);
>> dev_err(i2c->dev, "cannot meet bus frequency required\n");
>> return -EINVAL;
>> }
>> @@ -939,7 +967,8 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
>> /* todo - check that the i2c lines aren't being dragged anywhere */
>>
>> dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
>> - dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
>> + dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02x\n",
>> + readl(i2c->regs + S3C2410_IICCON));
>>
>
> Regards,
>
> Wolfram
Will re-base and post the patch..
>
> --
> Pengutronix e.K. | Wolfram Sang |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
--
Shine bright,
(: Nav :)
^ permalink raw reply
* [PATCH v3 01/15] at91: dt: Add at91sam9261 dt SoC support
From: Boris BREZILLON @ 2014-02-07 8:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207082350.GT9558@ns203013.ovh.net>
Hello Jean-Christophe,
On 07/02/2014 09:23, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
>> This patch adds the basics to support the Device Tree on a sam9261-based platform
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>> ---
>> arch/arm/boot/dts/at91sam9261.dtsi | 627 +++++++++++++++++++++++++++++++++++++
>> arch/arm/mach-at91/at91sam9261.c | 15 +
>> 2 files changed, 642 insertions(+)
>> create mode 100644 arch/arm/boot/dts/at91sam9261.dtsi
>>
>> diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
>> new file mode 100644
>> index 0000000..2730611
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/at91sam9261.dtsi
>> @@ -0,0 +1,627 @@
>> +/*
>> + * at91sam9261.dtsi - Device Tree Include file for AT91SAM9261 SoC
>> + *
>> + * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>> + *
>> + * Licensed under GPLv2 only.
>> + */
>> +
>> +#include "skeleton.dtsi"
>> +#include <dt-bindings/pinctrl/at91.h>
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/clk/at91.h>
>> +
>> +/ {
>> + model = "Atmel AT91SAM9261 family SoC";
>> + compatible = "atmel,at91sam9261";
>> + interrupt-parent = <&aic>;
>> +
>> + aliases {
>> + serial0 = &dbgu;
>> + serial1 = &usart0;
>> + serial2 = &usart1;
>> + serial3 = &usart2;
>> + gpio0 = &pioA;
>> + gpio1 = &pioB;
>> + gpio2 = &pioC;
>> + tcb0 = &tcb0;
>> + i2c0 = &i2c0;
>> + ssc0 = &ssc0;
>> + ssc1 = &ssc1;
>> + };
>> + cpus {
>> + #address-cells = <0>;
>> + #size-cells = <0>;
>> +
>> + cpu {
>> + compatible = "arm,arm926ej-s";
>> + device_type = "cpu";
>> + };
>> + };
>> +
>> + memory {
>> + reg = <0x20000000 0x08000000>;
>> + };
>> +
>> + ahb {
>> + compatible = "simple-bus";
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + ranges;
>> +
>> + usb0: ohci at 00500000 {
>> + compatible = "atmel,at91rm9200-ohci", "usb-ohci";
>> + reg = <0x00500000 0x100000>;
>> + interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
> as requested before use the new interrupt property
> interrupts-extended (mandatory)
>
> there is missing
> pinctrl-names = "default";
>
> on mmc & co
>> + status = "disabled";
>> + };
>> +
>> + nand0: nand at 40000000 {
>> + compatible = "atmel,at91rm9200-nand";
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + reg = <0x40000000 0x10000000>;
>> + atmel,nand-addr-offset = <22>;
>> + atmel,nand-cmd-offset = <21>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_nand>;
>> +
>> + gpios = <&pioC 15 GPIO_ACTIVE_HIGH
>> + &pioC 14 GPIO_ACTIVE_HIGH
>> + 0
>> + >;
>> + status = "disabled";
>> + };
>> +
>> + apb {
>> + compatible = "simple-bus";
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + ranges;
>> +
>> + tcb0: timer at fffa0000 {
>> + compatible = "atmel,at91rm9200-tcb";
>> + reg = <0xfffa0000 0x100>;
>> + interrupts = < 17 IRQ_TYPE_LEVEL_HIGH 0
>> + 18 IRQ_TYPE_LEVEL_HIGH 0
>> + 19 IRQ_TYPE_LEVEL_HIGH 0
>> + >;
>> + clocks = <&tcb0_clk>;
>> + clock-names = "t0_clk";
>> + status = "disabled";
> we use the tcb as shedule clock this should be on by default
>> + };
>> +
>> + usb1: gadget at fffa4000 {
>> + compatible = "atmel,at91rm9200-udc";
>> + reg = <0xfffa4000 0x4000>;
>> + interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
>> + status = "disabled";
>> + };
>> +
>> + mmc0: mmc at fffa8000 {
>> + compatible = "atmel,hsmci";
>> + reg = <0xfffa8000 0x600>;
>> + interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + clocks = <&mci0_clk>;
>> + clock-names = "mci_clk";
>> + status = "disabled";
>> + };
>> +
>> + i2c0: i2c at fffac000 {
>> + compatible = "atmel,at91sam9261-i2c";
>> + pinctrl-0 = <&pinctrl_i2c_twi>;
>> + reg = <0xfffac000 0x100>;
>> + interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + clocks = <&twi0_clk>;
>> + status = "disabled";
>> + };
>> +
>> + usart0: serial at fffb0000 {
>> + compatible = "atmel,at91sam9260-usart";
>> + reg = <0xfffb0000 0x200>;
>> + interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
>> + atmel,use-dma-rx;
>> + atmel,use-dma-tx;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart0>;
>> + clocks = <&usart0_clk>;
>> + clock-names = "usart";
>> + status = "disabled";
>> + };
>> +
>> + usart1: serial at fffb4000 {
>> + compatible = "atmel,at91sam9260-usart";
>> + reg = <0xfffb4000 0x200>;
>> + interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
>> + atmel,use-dma-rx;
>> + atmel,use-dma-tx;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart1>;
>> + clocks = <&usart1_clk>;
>> + clock-names = "usart";
>> + status = "disabled";
>> + };
>> +
>> + usart2: serial at fffb8000{
>> + compatible = "atmel,at91sam9260-usart";
>> + reg = <0xfffb8000 0x200>;
>> + interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
>> + atmel,use-dma-rx;
>> + atmel,use-dma-tx;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart2>;
>> + clocks = <&usart2_clk>;
>> + clock-names = "usart";
>> + status = "disabled";
>> + };
>> +
>> + ssc0: ssc at fffbc000 {
>> + compatible = "atmel,at91rm9200-ssc";
>> + reg = <0xfffbc000 0x4000>;
>> + interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
>> + status = "disabled";
>> + };
>> +
>> + ssc1: ssc at fffc0000 {
>> + compatible = "atmel,at91rm9200-ssc";
>> + reg = <0xfffc0000 0x4000>;
>> + interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
>> + status = "disabled";
>> + };
>> +
>> + spi0: spi at fffc8000 {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + compatible = "atmel,at91rm9200-spi";
>> + reg = <0xfffc8000 0x200>;
>> + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_spi0>;
>> + clocks = <&spi0_clk>;
>> + clock-names = "spi_clk";
>> + status = "disabled";
>> + };
>> +
>> + spi1: spi at fffcc000 {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + compatible = "atmel,at91rm9200-spi";
>> + reg = <0xfffcc000 0x200>;
>> + interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_spi1>;
>> + clocks = <&spi1_clk>;
>> + clock-names = "spi_clk";
>> + status = "disabled";
>> + };
> as said for sama5d3 we need to have macro for the hw CS as GPIO to make it
> more clear to use and read
>> +
>> + ramc: ramc at ffffea00 {
>> + compatible = "atmel,at91sam9260-sdramc";
>> + reg = <0xffffea00 0x200>;
>> + };
>> +
>> + aic: interrupt-controller at fffff000 {
>> + #interrupt-cells = <3>;
>> + compatible = "atmel,at91rm9200-aic";
>> + interrupt-controller;
>> + reg = <0xfffff000 0x200>;
>> + atmel,external-irqs = <29 30 31>;
>> + };
> one missing empty line
>> + dbgu: serial at fffff200 {
>> + compatible = "atmel,at91sam9260-usart";
>> + reg = <0xfffff200 0x200>;
>> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_dbgu>;
>> + clocks = <&mck>;
>> + clock-names = "usart";
>> + status = "disabled";
>> + };
>> +
>> + pinctrl at fffff400 {
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
>> + ranges = <0xfffff400 0xfffff400 0xa00>;
>> +
>> + atmel,mux-mask = <
>> + /* A B */
>> + 0xffffffff 0xfffffff7 /* pioA */
>> + 0xffffffff 0xfffffff4 /* pioB */
>> + 0xffffffff 0xffffff07 /* pioC */
>> + >;
>> +
>> + /* shared pinctrl settings */
>> + dbgu {
>> + pinctrl_dbgu: dbgu-0 {
>> + atmel,pins =
>> + <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
>> + };
>> + };
>> +
>> + usart0 {
>> + pinctrl_usart0: usart0-0 {
>> + atmel,pins =
>> + <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
>> + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart0_rts: usart0_rts-0 {
>> + atmel,pins =
>> + <AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart0_cts: usart0_cts-0 {
>> + atmel,pins =
>> + <AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + usart1 {
>> + pinctrl_usart1: usart1-0 {
>> + atmel,pins =
>> + <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
>> + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart1_rts: usart1_rts-0 {
>> + atmel,pins =
>> + <AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart1_cts: usart1_cts-0 {
>> + atmel,pins =
>> + <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + usart2 {
>> + pinctrl_usart2: usart2-0 {
>> + atmel,pins =
>> + <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
>> + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart2_rts: usart2_rts-0 {
>> + atmel,pins =
>> + <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_usart2_cts: usart2_cts-0 {
>> + atmel,pins =
>> + <AT91_PIOA 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + nand {
>> + pinctrl_nand: nand-0 {
>> + atmel,pins =
>> + <AT91_PIOC 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP
>> + AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
>> + };
>> + };
>> +
>> + mmc0 {
>> + pinctrl_mmc0_clk: mmc0_clk-0 {
>> + atmel,pins =
>> + <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
>> + atmel,pins =
>> + <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
>> + AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
>> + };
>> +
>> + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
>> + atmel,pins =
>> + <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
>> + AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
>> + AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
>> + };
>> + };
>> +
>> + ssc0 {
>> + pinctrl_ssc0_tx: ssc0_tx-0 {
>> + atmel,pins =
>> + <AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_ssc0_rx: ssc0_rx-0 {
>> + atmel,pins =
>> + <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + ssc1 {
>> + pinctrl_ssc1_tx: ssc1_tx-0 {
>> + atmel,pins =
>> + <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE
>> + AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE
>> + AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_ssc1_rx: ssc1_rx-0 {
>> + atmel,pins =
>> + <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE
>> + AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE
>> + AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + spi0 {
>> + pinctrl_spi0: spi0-0 {
>> + atmel,pins =
>> + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + spi1 {
>> + pinctrl_spi1: spi1-0 {
>> + atmel,pins =
>> + <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + tcb0 {
>> + pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
>> + atmel,pins = <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
>> + atmel,pins = <AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
>> + atmel,pins = <AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
>> + atmel,pins = <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
>> + atmel,pins = <AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
>> + atmel,pins = <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
>> + atmel,pins = <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
>> + atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> +
>> + pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
>> + atmel,pins = <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + i2c0 {
>> + pinctrl_i2c_bitbang: i2c-0-bitbang {
>> + atmel,pins =
>> + <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
>> + AT91_PIOA 8 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
>> + };
>> + pinctrl_i2c_twi: i2c-0-twi {
>> + atmel,pins =
>> + <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE
>> + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
>> + };
>> + };
>> +
>> + pioA: gpio at fffff400 {
>> + compatible = "atmel,at91rm9200-gpio";
>> + reg = <0xfffff400 0x200>;
>> + interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
>> + #gpio-cells = <2>;
>> + gpio-controller;
>> + interrupt-controller;
>> + #interrupt-cells = <2>;
>> + clocks = <&pioA_clk>;
>> + };
>> +
>> + pioB: gpio at fffff600 {
>> + compatible = "atmel,at91rm9200-gpio";
>> + reg = <0xfffff600 0x200>;
>> + interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
>> + #gpio-cells = <2>;
>> + gpio-controller;
>> + interrupt-controller;
>> + #interrupt-cells = <2>;
>> + clocks = <&pioB_clk>;
>> + };
>> +
>> + pioC: gpio at fffff800 {
>> + compatible = "atmel,at91rm9200-gpio";
>> + reg = <0xfffff800 0x200>;
>> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
>> + #gpio-cells = <2>;
>> + gpio-controller;
>> + interrupt-controller;
>> + #interrupt-cells = <2>;
>> + clocks = <&pioC_clk>;
>> + };
>> + };
>> +
>> + pmc: pmc at fffffc00 {
>> + compatible = "atmel,at91rm9200-pmc";
>> + reg = <0xfffffc00 0x100>;
>> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
>> + interrupt-controller;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + #interrupt-cells = <1>;
>> +
>> + clk32k: slck {
>> + compatible = "fixed-clock";
>> + #clock-cells = <0>;
>> + clock-frequency = <32768>;
>> + };
>> +
>> + main: mainck {
>> + compatible = "atmel,at91rm9200-clk-main";
>> + #clock-cells = <0>;
>> + interrupts-extended = <&pmc AT91_PMC_MOSCS>;
>> + clocks = <&clk32k>;
>> + };
>> +
>> + plla: pllack {
>> + compatible = "atmel,at91rm9200-clk-pll";
>> + #clock-cells = <0>;
>> + interrupts-extended = <&pmc AT91_PMC_LOCKA>;
>> + clocks = <&main>;
>> + reg = <0>;
>> + atmel,clk-input-range = <1000000 32000000>;
>> + #atmel,pll-clk-output-range-cells = <4>;
>> + atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
>> + };
>> +
>> + pllb: pllbck {
>> + compatible = "atmel,at91rm9200-clk-pll";
>> + #clock-cells = <0>;
>> + interrupts-extended = <&pmc AT91_PMC_LOCKB>;
>> + clocks = <&main>;
>> + reg = <1>;
>> + atmel,clk-input-range = <1000000 32000000>;
>> + #atmel,pll-clk-output-range-cells = <4>;
>> + atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
>> + };
>> +
>> + mck: masterck {
>> + compatible = "atmel,at91rm9200-clk-master";
>> + #clock-cells = <0>;
>> + interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
>> + clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
>> + atmel,clk-output-range = <0 94000000>;
>> + atmel,clk-divisors = <1 2 4 3>;
>> + };
>> + periphck {
>> + compatible = "atmel,at91rm9200-clk-peripheral";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + clocks = <&mck>;
>> +
>> + pioA_clk: pioA_clk {
>> + #clock-cells = <0>;
>> + reg = <2>;
>> + };
>> +
>> + pioB_clk: pioB_clk {
>> + #clock-cells = <0>;
>> + reg = <3>;
>> + };
>> +
>> + pioC_clk: pioC_clk {
>> + #clock-cells = <0>;
>> + reg = <4>;
>> + };
>> +
>> + usart0_clk: usart0_clk {
>> + #clock-cells = <0>;
>> + reg = <6>;
>> + };
>> +
>> + usart1_clk: usart1_clk {
>> + #clock-cells = <0>;
>> + reg = <7>;
>> + };
>> +
>> + usart2_clk: usart2_clk {
>> + #clock-cells = <0>;
>> + reg = <8>;
>> + };
>> +
>> + mci0_clk: mci0_clk {
>> + #clock-cells = <0>;
>> + reg = <9>;
>> + };
>> +
>> + twi0_clk: twi0_clk {
>> + reg = <11>;
>> + #clock-cells = <0>;
>> + };
>> +
>> + spi0_clk: spi0_clk {
>> + #clock-cells = <0>;
>> + reg = <12>;
>> + };
>> +
>> + spi1_clk: spi1_clk {
>> + #clock-cells = <0>;
>> + reg = <13>;
>> + };
>> +
>> + tcb0_clk: tcb0_clk {
>> + #clock-cells = <0>;
>> + reg = <17>;
>> + };
>> +
>> + lcd_clk: lcd_clk {
>> + #clock-cells = <0>;
>> + reg = <21>;
>> + };
>> + };
>> + };
>> +
>> + rstc at fffffd00 {
>> + compatible = "atmel,at91sam9260-rstc";
>> + reg = <0xfffffd00 0x10>;
>> + };
>> +
>> + shdwc at fffffd10 {
>> + compatible = "atmel,at91sam9260-shdwc";
>> + reg = <0xfffffd10 0x10>;
>> + };
>> +
>> + pit: timer at fffffd30 {
>> + compatible = "atmel,at91sam9260-pit";
>> + reg = <0xfffffd30 0xf>;
>> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
>> + clocks = <&mck>;
>> + };
>> +
>> + watchdog at fffffd40 {
>> + compatible = "atmel,at91sam9260-wdt";
>> + reg = <0xfffffd40 0x10>;
>> + status = "disabled";
>> + };
>> + };
>> + };
>> +
>> + i2c at 0 {
>> + compatible = "i2c-gpio";
>> + pinctrl-0 = <&pinctrl_i2c_bitbang>;
>> + gpios = <&pioA 7 GPIO_ACTIVE_HIGH /* sda */
>> + &pioA 8 GPIO_ACTIVE_HIGH /* scl */
>> + >;
>> + i2c-gpio,sda-open-drain;
>> + i2c-gpio,scl-open-drain;
>> + i2c-gpio,delay-us = <2>; /* ~100 kHz */
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + status = "disabled";
>> + };
>> +};
>> diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
>> index 6276b4c..6a2c869 100644
>> --- a/arch/arm/mach-at91/at91sam9261.c
>> +++ b/arch/arm/mach-at91/at91sam9261.c
>> @@ -189,6 +189,21 @@ static struct clk_lookup periph_clocks_lookups[] = {
>> CLKDEV_CON_ID("pioA", &pioA_clk),
>> CLKDEV_CON_ID("pioB", &pioB_clk),
>> CLKDEV_CON_ID("pioC", &pioC_clk),
>> + /* more usart lookup table for DT entries */
>> + CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
>> + CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
>> + CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk),
>> + CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk),
>> + /* more tc lookup table for DT entries */
>> + CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
>> + CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &hck0),
>> + CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk),
>> + CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk),
>> + CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
>> + CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk),
>> + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
>> + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
>> + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
> do we really need this with ccf?
We need this in case we want to support multi-board kernel with some boards
that do not support CCF.
If you want to drop these clk lookup defintions you'll have to add the
"depends on COMMON_CLK" line in the "config SOC_AT91SAM9261" section.
Best Regards,
Boris
>> };
>>
>> static struct clk_lookup usart_clocks_lookups[] = {
>> --
>> 1.8.5.2
>>
^ permalink raw reply
* [PATCH v2 07/12] at91: dt: smc: Added smc bus driver
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389270709-32662-8-git-send-email-jjhiblot@traphandler.com>
On 13:31 Thu 09 Jan , Jean-Jacques Hiblot wrote:
> The EBI/SMC external interface is used to access external peripherals (NAND
> and Ethernet controller in the case of sam9261ek). Different configurations and
> timings are required for those peripherals. This bus driver can be used to
> setup the bus timings/configuration from the device tree.
> It currently accepts timings in clock period and in nanoseconds.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
NACK on the binding
will comment on the patch
Best Regards,
J.
> drivers/memory/Kconfig | 10 ++
> drivers/memory/Makefile | 1 +
> drivers/memory/atmel-smc.c | 431 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 442 insertions(+)
> create mode 100644 drivers/memory/atmel-smc.c
>
> diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
> index 29a11db..fbdfd63 100644
> --- a/drivers/memory/Kconfig
> +++ b/drivers/memory/Kconfig
> @@ -50,4 +50,14 @@ config TEGRA30_MC
> analysis, especially for IOMMU/SMMU(System Memory Management
> Unit) module.
>
> +config ATMEL_SMC
> + bool "Atmel SMC/EBI driver"
> + default y
> + depends on SOC_AT91SAM9 && OF
> + help
> + Driver for Atmel SMC/EBI controller.
> + Used to configure the EBI (external bus interface) when the device-
> + tree is used. This bus supports NANDs, external ethernet controller,
> + SRAMs, ATA devices, etc.
> +
> endif
> diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
> index 969d923..101abc4 100644
> --- a/drivers/memory/Makefile
> +++ b/drivers/memory/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_TI_EMIF) += emif.o
> obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
> obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
> obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o
> +obj-$(CONFIG_ATMEL_SMC) += atmel-smc.o
> diff --git a/drivers/memory/atmel-smc.c b/drivers/memory/atmel-smc.c
> new file mode 100644
> index 0000000..0a1d9ba
> --- /dev/null
> +++ b/drivers/memory/atmel-smc.c
> @@ -0,0 +1,431 @@
> +/*
> + * EBI driver for Atmel SAM9 chips
> + * inspired by the fsl weim bus driver
> + *
> + * Copyright (C) 2013 JJ Hiblot.
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/module.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/of_device.h>
> +#include <mach/at91sam9_smc.h>
> +
> +struct smc_data {
> + struct clk *bus_clk;
> + void __iomem *base;
> + struct device *dev;
> +};
> +
> +struct at91_smc_devtype {
> + unsigned int cs_count;
> +};
> +
> +static const struct at91_smc_devtype sam9261_smc_devtype = {
> + .cs_count = 6,
> +};
> +
> +static const struct of_device_id smc_id_table[] = {
> + { .compatible = "atmel,at91sam9261-smc", .data = &sam9261_smc_devtype},
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, smc_id_table);
> +
> +struct smc_parameters_type {
> + const char *name;
> + u16 width;
> + u16 shift;
> +};
> +
> +static const struct smc_parameters_type smc_parameters[] = {
> + {"smc,burst_size", 2, 28},
> + {"smc,burst_enabled", 1, 24},
> + {"smc,tdf_mode", 1, 20},
> + {"smc,bus_width", 2, 12},
> + {"smc,byte_access_type", 1, 8},
> + {"smc,nwait_mode", 2, 4},
> + {"smc,write_mode", 1, 0},
> + {"smc,read_mode", 1, 1},
> + {NULL}
> +};
> +
> +static int get_mode_register_from_dt(struct smc_data *smc,
> + struct device_node *np,
> + struct sam9_smc_config *cfg)
> +{
> + int ret;
> + u32 val;
> + struct device *dev = smc->dev;
> + const struct smc_parameters_type *p = smc_parameters;
> + u32 mode = cfg->mode;
> +
> + while (p->name) {
> + ret = of_property_read_u32(np, p->name , &val);
> + if (ret == -EINVAL) {
> + dev_dbg(dev, "%s: property %s not set.\n", np->name,
> + p->name);
> + p++;
> + continue;
> + } else if (ret) {
> + dev_err(dev, "%s: can't get property %s.\n", np->name,
> + p->name);
> + return ret;
> + }
> + if (val >= (1<<p->width)) {
> + dev_err(dev, "%s: property %s out of range.\n",
> + np->name, p->name);
> + return -ERANGE;
> + }
> + mode &= ~(((1<<p->width)-1) << p->shift);
> + mode |= (val << p->shift);
> + p++;
> + }
> + cfg->mode = mode;
> + return 0;
> +}
> +
> +static int generic_timing_from_dt(struct smc_data *smc, struct device_node *np,
> + struct sam9_smc_config *cfg)
> +{
> + u32 val;
> +
> + if (!of_property_read_u32(np, "smc,ncs_read_setup" , &val))
> + cfg->ncs_read_setup = val;
> +
> + if (!of_property_read_u32(np, "smc,nrd_setup" , &val))
> + cfg->nrd_setup = val;
> +
> + if (!of_property_read_u32(np, "smc,ncs_write_setup" , &val))
> + cfg->ncs_write_setup = val;
> +
> + if (!of_property_read_u32(np, "smc,nwe_setup" , &val))
> + cfg->nwe_setup = val;
> +
> + if (!of_property_read_u32(np, "smc,ncs_read_pulse" , &val))
> + cfg->ncs_read_pulse = val;
> +
> + if (!of_property_read_u32(np, "smc,nrd_pulse" , &val))
> + cfg->nrd_pulse = val;
> +
> + if (!of_property_read_u32(np, "smc,ncs_write_pulse" , &val))
> + cfg->ncs_write_pulse = val;
> +
> + if (!of_property_read_u32(np, "smc,nwe_pulse" , &val))
> + cfg->nwe_pulse = val;
> +
> + if (!of_property_read_u32(np, "smc,read_cycle" , &val))
> + cfg->read_cycle = val;
> +
> + if (!of_property_read_u32(np, "smc,write_cycle" , &val))
> + cfg->write_cycle = val;
> +
> + if (!of_property_read_u32(np, "smc,tdf_cycles" , &val))
> + cfg->tdf_cycles = val;
> +
> + return get_mode_register_from_dt(smc, np, cfg);
> +}
> +
> +/* convert the time in ns in a number of clock cycles */
> +static u32 ns_to_cycles(u32 ns, u32 clk)
> +{
> + /*
> + * convert the clk to kHz for the rest of the calculation to avoid
> + * overflow
> + */
> + u32 clk_kHz = clk / 1000;
> + u32 ncycles = ((ns * clk_kHz) + 1000000 - 1) / 1000000;
> + return ncycles;
> +}
> +
> +static u32 cycles_to_coded_cycle(u32 cycles, int a, int b)
> +{
> + u32 mask_high = (1 << a) - 1;
> + u32 mask_low = (1 << b) - 1;
> + u32 coded;
> +
> + /* check if the value can be described with the coded format */
> + if (cycles & (mask_high & ~mask_low)) {
> + /* not representable. we need to round up */
> + cycles |= mask_high;
> + cycles += 1;
> + }
> + /* Now the value can be represented in the coded format */
> + coded = (cycles & ~mask_high) >> (a - b);
> + coded |= (cycles & mask_low);
> + return coded;
> +}
> +
> +static u32 ns_to_rw_cycles(u32 ns, u32 clk)
> +{
> + return cycles_to_coded_cycle(ns_to_cycles(ns, clk), 8, 7);
> +}
> +
> +static u32 ns_to_pulse_cycles(u32 ns, u32 clk)
> +{
> + return cycles_to_coded_cycle(ns_to_cycles(ns, clk), 8, 6);
> +}
> +
> +static u32 ns_to_setup_cycles(u32 ns, u32 clk)
> +{
> + return cycles_to_coded_cycle(ns_to_cycles(ns, clk), 7, 5);
> +}
> +
> +static u32 cycles_to_ns(u32 cycles, u32 clk)
> +{
> + /*
> + * convert the clk to kHz for the rest of the calculation to avoid
> + * overflow
> + */
> + u32 clk_kHz = clk / 1000;
> + return (cycles * 1000000) / clk_kHz;
> +}
> +
> +static u32 coded_cycle_to_cycles(u32 coded, int a, int b)
> +{
> + u32 cycles = (coded >> b) << a;
> + u32 mask_low = (1 << b) - 1;
> + cycles |= (coded & mask_low);
> + return cycles;
> +}
> +
> +static u32 rw_cycles_to_ns(u32 reg, u32 clk)
> +{
> + return cycles_to_ns(coded_cycle_to_cycles(reg, 8, 7), clk);
> +}
> +
> +static u32 pulse_cycles_to_ns(u32 reg, u32 clk)
> +{
> + return cycles_to_ns(coded_cycle_to_cycles(reg, 8, 6), clk);
> +}
> +
> +static u32 setup_cycles_to_ns(u32 reg, u32 clk)
> +{
> + return cycles_to_ns(coded_cycle_to_cycles(reg, 7, 5), clk);
> +}
> +
> +static void dump_timing(struct smc_data *smc, struct sam9_smc_config *config)
> +{
> + u32 freq = clk_get_rate(smc->bus_clk);
> + struct device *dev = smc->dev;
> +
> +#define DUMP(fn, y) dev_info(dev, "%s : 0x%x (%d ns)\n", #y, config->y,\
> + fn(config->y, freq))
> +#define DUMP_PULSE(y) DUMP(pulse_cycles_to_ns, y)
> +#define DUMP_RWCYCLE(y) DUMP(rw_cycles_to_ns, y)
> +#define DUMP_SETUP(y) DUMP(setup_cycles_to_ns, y)
> +#define DUMP_SIMPLE(y) DUMP(cycles_to_ns, y)
> +
> + DUMP_SETUP(nwe_setup);
> + DUMP_SETUP(ncs_write_setup);
> + DUMP_SETUP(nrd_setup);
> + DUMP_SETUP(ncs_read_setup);
> + DUMP_PULSE(nwe_pulse);
> + DUMP_PULSE(ncs_write_pulse);
> + DUMP_PULSE(nrd_pulse);
> + DUMP_PULSE(ncs_read_pulse);
> + DUMP_RWCYCLE(write_cycle);
> + DUMP_RWCYCLE(read_cycle);
> + DUMP_SIMPLE(tdf_cycles);
> +}
> +
> +static int ns_timing_from_dt(struct smc_data *smc, struct device_node *np,
> + struct sam9_smc_config *cfg)
> +{
> + u32 t_ns;
> + u32 freq = clk_get_rate(smc->bus_clk);
> +
> + if (!of_property_read_u32(np, "smc,ncs_read_setup" , &t_ns))
> + cfg->ncs_read_setup = ns_to_setup_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,nrd_setup" , &t_ns))
> + cfg->nrd_setup = ns_to_setup_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,ncs_write_setup" , &t_ns))
> + cfg->ncs_write_setup = ns_to_setup_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,nwe_setup" , &t_ns))
> + cfg->nwe_setup = ns_to_setup_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,ncs_read_pulse" , &t_ns))
> + cfg->ncs_read_pulse = ns_to_pulse_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,nrd_pulse" , &t_ns))
> + cfg->nrd_pulse = ns_to_pulse_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,ncs_write_pulse" , &t_ns))
> + cfg->ncs_write_pulse = ns_to_pulse_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,nwe_pulse" , &t_ns))
> + cfg->nwe_pulse = ns_to_pulse_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,read_cycle" , &t_ns))
> + cfg->read_cycle = ns_to_rw_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,write_cycle" , &t_ns))
> + cfg->write_cycle = ns_to_rw_cycles(t_ns, freq);
> +
> + if (!of_property_read_u32(np, "smc,tdf_cycles" , &t_ns))
> + cfg->tdf_cycles = ns_to_cycles(t_ns, freq);
> +
> + return get_mode_register_from_dt(smc, np, cfg);
> +}
> +
> +struct converter {
> + const char *name;
> + int (*fn) (struct smc_data *smc, struct device_node *np,
> + struct sam9_smc_config *cfg);
> +};
> +static const struct converter converters[] = {
> + {"raw", generic_timing_from_dt},
> + {"nanosec", ns_timing_from_dt},
> +};
> +
> +/* Parse and set the timing for this device. */
> +static int smc_timing_setup(struct smc_data *smc, struct device_node *np,
> + const struct at91_smc_devtype *devtype)
> +{
> + int ret;
> + u32 cs;
> + int i;
> + struct device *dev = smc->dev;
> + const struct converter *converter;
> + const char *converter_name = NULL;
> + struct sam9_smc_config cfg;
> +
> + ret = of_property_read_u32(np, "smc,cs" , &cs);
> + if (ret < 0) {
> + dev_err(dev, "missing mandatory property : smc,cs\n");
> + return ret;
> + }
> + if (cs >= devtype->cs_count) {
> + dev_err(dev, "invalid value for property smc,cs (=%d)."
> + "Must be in range 0 to %d\n", cs, devtype->cs_count-1);
> + return -EINVAL;
> + }
> +
> + of_property_read_string(np, "smc,converter", &converter_name);
> + if (converter_name) {
> + for (i = 0; i < ARRAY_SIZE(converters); i++)
> + if (strcmp(converters[i].name, converter_name) == 0)
> + converter = &converters[i];
> + if (!converter) {
> + dev_info(dev, "unknown converter. aborting\n");
> + return -EINVAL;
> + }
> + } else {
> + dev_dbg(dev, "cs %d: no smc converter provided. using "
> + "raw register values\n", cs);
> + converter = &converters[0];
> + }
> + dev_dbg(dev, "cs %d using converter : %s\n", cs, converter->name);
> + sam9_smc_cs_read(smc->base + (0x10 * cs), &cfg);
> + converter->fn(smc, np, &cfg);
> + ret = sam9_smc_check_cs_configuration(&cfg);
> + if (ret < 0) {
> + dev_info(dev, "invalid smc configuration for cs %d."
> + "clipping values\n", cs);
> + sam9_smc_clip_cs_configuration(&cfg);
> + dump_timing(smc, &cfg);
> + }
> +#ifdef DEBUG
> + else
> + dump_timing(smc, &cfg);
> +#endif
> +
> + sam9_smc_cs_configure(smc->base + (0x10 * cs), &cfg);
> + return 0;
> +}
> +
> +static int smc_parse_dt(struct smc_data *smc)
> +{
> + struct device *dev = smc->dev;
> + const struct of_device_id *of_id = of_match_device(smc_id_table, dev);
> + const struct at91_smc_devtype *devtype = of_id->data;
> + struct device_node *child;
> + int ret;
> +
> + for_each_child_of_node(dev->of_node, child) {
> + if (!child->name)
> + continue;
> + if (!of_device_is_available(child))
> + continue;
> + ret = smc_timing_setup(smc, child, devtype);
> + if (ret) {
> + static struct property status = {
> + .name = "status",
> + .value = "disabled",
> + .length = sizeof("disabled"),
> + };
> + dev_err(dev, "%s set timing failed. This node will be disabled.\n",
> + child->full_name);
> + ret = of_update_property(child, &status);
> + if (ret < 0) {
> + dev_err(dev, "can't disable %s. aborting probe\n",
> + child->full_name);
> + break;
> + }
> + }
> + }
> +
> + ret = of_platform_populate(dev->of_node, of_default_bus_match_table,
> + NULL, dev);
> + if (ret)
> + dev_err(dev, "%s fail to create devices.\n",
> + dev->of_node->full_name);
> +
> + return ret;
> +}
> +
> +static int smc_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + int ret;
> + void __iomem *base;
> + struct clk *clk;
> + struct smc_data *smc = devm_kzalloc(&pdev->dev, sizeof(struct smc_data),
> + GFP_KERNEL);
> +
> + if (!smc)
> + return -ENOMEM;
> +
> + smc->dev = &pdev->dev;
> +
> + /* get the resource */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + base = devm_request_and_ioremap(&pdev->dev, res);
> + if (IS_ERR(base)) {
> + dev_err(&pdev->dev, "can't map SMC base address\n");
> + return PTR_ERR(base);
> + }
> +
> + /* get the clock */
> + clk = devm_clk_get(&pdev->dev, "smc");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + smc->bus_clk = clk;
> + smc->base = base;
> +
> + /* parse the device node */
> + ret = smc_parse_dt(smc);
> + if (!ret)
> + dev_info(&pdev->dev, "Driver registered.\n");
> +
> + return ret;
> +}
> +
> +static struct platform_driver smc_driver = {
> + .driver = {
> + .name = "atmel-smc",
> + .owner = THIS_MODULE,
> + .of_match_table = smc_id_table,
> + },
> +};
> +module_platform_driver_probe(smc_driver, smc_probe);
> +
> +MODULE_AUTHOR("JJ Hiblot");
> +MODULE_DESCRIPTION("Atmel's SMC/EBI driver");
> +MODULE_LICENSE("GPL");
> --
> 1.8.5.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] can: xilinx CAN controller support.
From: Appana Durga Kedareswara Rao @ 2014-02-07 8:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F382D5.6090706@pengutronix.de>
Hi Marc,
> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl at pengutronix.de]
> Sent: Thursday, February 06, 2014 6:11 PM
> To: Appana Durga Kedareswara Rao; wg at grandegger.com; Michal Simek;
> grant.likely at linaro.org; robh+dt at kernel.org; linux-can at vger.kernel.org
> Cc: netdev at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; devicetree at vger.kernel.org; Appana Durga
> Kedareswara Rao
> Subject: Re: [PATCH] can: xilinx CAN controller support.
>
> On 02/06/2014 11:19 AM, Kedareswara rao Appana wrote:
> > This patch adds xilinx CAN controller support.
> > This driver supports both ZYNQ CANPS IP and Soft IP AXI CAN
> > controller.
> >
> > Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
>
> First review, see comments inline.
>
> Marc
>
> > ---
> > This patch is rebased on the 3.14 rc1 kernel.
> > ---
> > .../devicetree/bindings/net/can/xilinx_can.txt | 43 +
> > drivers/net/can/Kconfig | 8 +
> > drivers/net/can/Makefile | 1 +
> > drivers/net/can/xilinx_can.c | 1150 ++++++++++++++++++++
> > 4 files changed, 1202 insertions(+), 0 deletions(-) create mode
> > 100644 Documentation/devicetree/bindings/net/can/xilinx_can.txt
> > create mode 100644 drivers/net/can/xilinx_can.c
> >
> > diff --git a/Documentation/devicetree/bindings/net/can/xilinx_can.txt
> > b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
> > new file mode 100644
> > index 0000000..34f9643
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
> > @@ -0,0 +1,43 @@
> > +Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
> > +---------------------------------------------------------
> > +
> > +Required properties:
> > +- compatible : Should be "xlnx,zynq-can-1.00.a" for Zynq
> CAN
> > + controllers and "xlnx,axi-can-1.00.a" for Axi CAN
> > + controllers.
> > +- reg : Physical base address and size of the Axi CAN/Zynq
> > + CANPS registers map.
> > +- interrupts : Property with a value describing the interrupt
> > + number.
> > +- interrupt-parent : Must be core interrupt controller
> > +- clock-names : List of input clock names - "ref_clk",
> "aper_clk"
> > + (See clock bindings for details. Two clocks are
> > + required for Zynq CAN. For Axi CAN
> > + case it is one(ref_clk)).
> > +- clocks : Clock phandles (see clock bindings for details).
> > +- xlnx,can-tx-dpth : Can Tx fifo depth (Required for Axi CAN).
> > +- xlnx,can-rx-dpth : Can Rx fifo depth (Required for Axi CAN).
> > +
> > +
> > +Example:
> > +
> > +For Zynq CANPS Dts file:
> > + zynq_can_0: zynq-can at e0008000 {
> > + compatible = "xlnx,zynq-can-1.00.a";
> > + clocks = <&clkc 19>, <&clkc 36>;
> > + clock-names = "ref_clk", "aper_clk";
> > + reg = <0xe0008000 0x1000>;
> > + interrupts = <0 28 4>;
> > + interrupt-parent = <&intc>;
>
> Above xlnx,can-{rx,tx}-dpth is mentioned as required, but it's not in the
> Zynq example.
One of the Difference b/w the AXI CAN and zynq CAN is in AXI CAN the fifo depth(tx,rx)
Is user configurable. But in case of ZYNQ CAN the fifo depth is fixed for tx and rx fifo's(64)
Xlnx,can-{rx,tx}-dpth is required only for AXI CAN case it is not required for zynq CAN.
That's why didn't putted that property in device tree.
>
> > + };
> > +For Axi CAN Dts file:
> > + axi_can_0: axi-can at 40000000 {
> > + compatible = "xlnx,axi-can-1.00.a";
> > + clocks = <&clkc 0>;
> > + clock-names = "ref_clk" ;
> > + reg = <0x40000000 0x10000>;
> > + interrupt-parent = <&intc>;
> > + interrupts = <0 59 1>;
> > + xlnx,can-tx-dpth = <0x40>;
> > + xlnx,can-rx-dpth = <0x40>;
> > + };
> > diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index
> > d447b88..2344fb5 100644
> > --- a/drivers/net/can/Kconfig
> > +++ b/drivers/net/can/Kconfig
> > @@ -125,6 +125,14 @@ config CAN_GRCAN
> > endian syntheses of the cores would need some modifications on
> > the hardware level to work.
> >
> > +config CAN_XILINXCAN
> > + tristate "Xilinx CAN"
> > + depends on ARCH_ZYNQ || MICROBLAZE
> > + default n
>
> "default n" is default, please remove.
>
Ok
> > + ---help---
> > + Xilinx CAN driver. This driver supports both soft AXI CAN IP and
> > + Zynq CANPS IP.
> > +
> > source "drivers/net/can/mscan/Kconfig"
> >
> > source "drivers/net/can/sja1000/Kconfig"
> > diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index
> > c744039..0b8e11e 100644
> > --- a/drivers/net/can/Makefile
> > +++ b/drivers/net/can/Makefile
> > @@ -25,5 +25,6 @@ obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-
> ican3.o
> > obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
> > obj-$(CONFIG_PCH_CAN) += pch_can.o
> > obj-$(CONFIG_CAN_GRCAN) += grcan.o
> > +obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
> >
> > ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git
> > a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c new file
> > mode 100644 index 0000000..c1b2b9d
> > --- /dev/null
> > +++ b/drivers/net/can/xilinx_can.c
> > @@ -0,0 +1,1150 @@
> > +/* Xilinx CAN device driver
> > + *
> > + * Copyright (C) 2012 - 2014 Xilinx, Inc.
> > + * Copyright (C) 2009 PetaLogix. All rights reserved.
> > + *
> > + * Description:
> > + * This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
> > + * This program is free software: you can redistribute it and/or
> > +modify
> > + * it under the terms of the GNU General Public License as published
> > +by
> > + * the Free Software Foundation, either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/errno.h>
> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/netdevice.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/skbuff.h>
> > +#include <linux/string.h>
> > +#include <linux/types.h>
> > +#include <linux/can/dev.h>
> > +#include <linux/can/error.h>
> > +#include <linux/can/led.h>
> > +
> > +#define DRIVER_NAME "XILINX_CAN"
> > +
> > +/* CAN registers set */
> > +#define XCAN_SRR_OFFSET 0x00 /* Software reset */
> > +#define XCAN_MSR_OFFSET 0x04 /* Mode select */
> > +#define XCAN_BRPR_OFFSET 0x08 /* Baud rate prescaler */
> > +#define XCAN_BTR_OFFSET 0x0C /* Bit timing */
> > +#define XCAN_ECR_OFFSET 0x10 /* Error counter */
> > +#define XCAN_ESR_OFFSET 0x14 /* Error status */
> > +#define XCAN_SR_OFFSET 0x18 /* Status */
> > +#define XCAN_ISR_OFFSET 0x1C /* Interrupt status */
> > +#define XCAN_IER_OFFSET 0x20 /* Interrupt enable */
> > +#define XCAN_ICR_OFFSET 0x24 /* Interrupt clear */
> > +#define XCAN_TXFIFO_ID_OFFSET 0x30 /* TX FIFO ID */
> > +#define XCAN_TXFIFO_DLC_OFFSET 0x34 /* TX FIFO DLC */
> > +#define XCAN_TXFIFO_DW1_OFFSET 0x38 /* TX FIFO Data
> Word 1 */
> > +#define XCAN_TXFIFO_DW2_OFFSET 0x3C /* TX FIFO Data
> Word 2 */
> > +#define XCAN_RXFIFO_ID_OFFSET 0x50 /* RX FIFO ID */
> > +#define XCAN_RXFIFO_DLC_OFFSET 0x54 /* RX FIFO DLC */
> > +#define XCAN_RXFIFO_DW1_OFFSET 0x58 /* RX FIFO Data
> Word 1 */
> > +#define XCAN_RXFIFO_DW2_OFFSET 0x5C /* RX FIFO Data
> Word 2 */
> > +
> > +/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
> > +#define XCAN_SRR_CEN_MASK 0x00000002 /* CAN enable */
> > +#define XCAN_SRR_RESET_MASK 0x00000001 /* Soft Reset the
> CAN core */
> > +#define XCAN_MSR_LBACK_MASK 0x00000002 /* Loop back
> mode select */
> > +#define XCAN_MSR_SLEEP_MASK 0x00000001 /* Sleep mode
> select */
> > +#define XCAN_BRPR_BRP_MASK 0x000000FF /* Baud rate
> prescaler */
> > +#define XCAN_BTR_SJW_MASK 0x00000180 /* Synchronous
> jump width */
> > +#define XCAN_BTR_TS2_MASK 0x00000070 /* Time segment
> 2 */
> > +#define XCAN_BTR_TS1_MASK 0x0000000F /* Time segment
> 1 */
> > +#define XCAN_ECR_REC_MASK 0x0000FF00 /* Receive error
> counter */
> > +#define XCAN_ECR_TEC_MASK 0x000000FF /* Transmit error
> counter */
> > +#define XCAN_ESR_ACKER_MASK 0x00000010 /* ACK error */
> > +#define XCAN_ESR_BERR_MASK 0x00000008 /* Bit error */
> > +#define XCAN_ESR_STER_MASK 0x00000004 /* Stuff error */
> > +#define XCAN_ESR_FMER_MASK 0x00000002 /* Form error */
> > +#define XCAN_ESR_CRCER_MASK 0x00000001 /* CRC error */
> > +#define XCAN_SR_TXFLL_MASK 0x00000400 /* TX FIFO is full
> */
> > +#define XCAN_SR_ESTAT_MASK 0x00000180 /* Error status */
> > +#define XCAN_SR_ERRWRN_MASK 0x00000040 /* Error warning
> */
> > +#define XCAN_SR_NORMAL_MASK 0x00000008 /* Normal mode
> */
> > +#define XCAN_SR_LBACK_MASK 0x00000002 /* Loop back
> mode */
> > +#define XCAN_SR_CONFIG_MASK 0x00000001 /* Configuration
> mode */
> > +#define XCAN_IXR_TXFEMP_MASK 0x00004000 /* TX FIFO Empty
> */
> > +#define XCAN_IXR_WKUP_MASK 0x00000800 /* Wake up
> interrupt */
> > +#define XCAN_IXR_SLP_MASK 0x00000400 /* Sleep
> interrupt */
> > +#define XCAN_IXR_BSOFF_MASK 0x00000200 /* Bus off
> interrupt */
> > +#define XCAN_IXR_ERROR_MASK 0x00000100 /* Error interrupt
> */
> > +#define XCAN_IXR_RXNEMP_MASK 0x00000080 /* RX FIFO
> NotEmpty intr */
> > +#define XCAN_IXR_RXOFLW_MASK 0x00000040 /* RX FIFO
> Overflow intr */
> > +#define XCAN_IXR_RXOK_MASK 0x00000010 /* Message
> received intr */
> > +#define XCAN_IXR_TXOK_MASK 0x00000002 /* TX successful
> intr */
> > +#define XCAN_IXR_ARBLST_MASK 0x00000001 /* Arbitration
> lost intr */
> > +#define XCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg
> identifier */
> > +#define XCAN_IDR_SRR_MASK 0x00100000 /* Substitute
> remote TXreq */
> > +#define XCAN_IDR_IDE_MASK 0x00080000 /* Identifier
> extension */
> > +#define XCAN_IDR_ID2_MASK 0x0007FFFE /* Extended
> message ident */
> > +#define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX
> request */
> > +#define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length
> code */
> > +
> > +#define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK |
> XCAN_IXR_BSOFF_MASK |\
> > + XCAN_IXR_WKUP_MASK |
> XCAN_IXR_SLP_MASK | \
> > + XCAN_IXR_RXNEMP_MASK |
> XCAN_IXR_ERROR_MASK | \
> > + XCAN_IXR_ARBLST_MASK |
> XCAN_IXR_RXOK_MASK)
> > +
> > +/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
> > +#define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width
> */
> > +#define XCAN_BTR_TS2_SHIFT 4 /* Time segment 2 */
> > +#define XCAN_IDR_ID1_SHIFT 21 /* Standard Messg
> Identifier */
> > +#define XCAN_IDR_ID2_SHIFT 1 /* Extended Message
> Identifier */
> > +#define XCAN_DLCR_DLC_SHIFT 28 /* Data length code */
> > +#define XCAN_ESR_REC_SHIFT 8 /* Rx Error Count */
> > +
> > +/* CAN frame length constants */
> > +#define XCAN_ECHO_SKB_MAX 64
> > +#define XCAN_NAPI_WEIGHT 64
> > +#define XCAN_FRAME_MAX_DATA_LEN 8
> > +#define XCAN_TIMEOUT (50 * HZ)
> > +
> > +/**
> > + * struct xcan_priv - This definition define CAN driver instance
> > + * @can: CAN private data structure.
> > + * @open_time: For holding timeout values
> > + * @waiting_ech_skb_index: Pointer for skb
> > + * @ech_skb_next: This tell the next packet in the queue
> > + * @waiting_ech_skb_num: Gives the number of packets waiting
> > + * @xcan_echo_skb_max_tx: Maximum number packets the driver
> can send
> > + * @xcan_echo_skb_max_rx: Maximum number packets the driver
> can receive
> > + * @napi: NAPI structure
> > + * @ech_skb_lock: For spinlock purpose
> > + * @read_reg: For reading data from CAN registers
> > + * @write_reg: For writing data to CAN registers
> > + * @dev: Network device data structure
> > + * @reg_base: Ioremapped address to registers
> > + * @irq_flags: For request_irq()
> > + * @aperclk: Pointer to struct clk
> > + * @devclk: Pointer to struct clk
> > + */
> > +struct xcan_priv {
> > + struct can_priv can;
> > + int open_time;
> > + int waiting_ech_skb_index;
> > + int ech_skb_next;
> > + int waiting_ech_skb_num;
> > + int xcan_echo_skb_max_tx;
> > + int xcan_echo_skb_max_rx;
> > + struct napi_struct napi;
> > + spinlock_t ech_skb_lock;
> > + u32 (*read_reg)(const struct xcan_priv *priv, int reg);
> > + void (*write_reg)(const struct xcan_priv *priv, int reg, u32 val);
>
> Why do you have {read,write}_reg function here?
xcan_write_reg/xcan_read_reg is used because this IP is also in big endian version.
We won't support It but if someone else want to support that's why putted these function's here.
If you are not ok with this will remove.
>
> > + struct net_device *dev;
> > + void __iomem *reg_base;
> > + unsigned long irq_flags;
> > + struct clk *aperclk;
> > + struct clk *devclk;
> > +};
> > +
> > +/* CAN Bittiming constants as per Xilinx CAN specs */ static struct
> > +can_bittiming_const xcan_bittiming_const = {
> > + .name = DRIVER_NAME,
> > + .tseg1_min = 1,
> > + .tseg1_max = 16,
> > + .tseg2_min = 1,
> > + .tseg2_max = 8,
> > + .sjw_max = 4,
> > + .brp_min = 1,
> > + .brp_max = 256,
> > + .brp_inc = 1,
> > +};
> > +
> > +/**
> > + * xcan_write_reg - Write a value to the device register
> > + * @priv: Driver private data structure
> > + * @reg: Register offset
> > + * @val: Value to write at the Register offset
> > + *
> > + * Write data to the paricular CAN register */ static void
> > +xcan_write_reg(const struct xcan_priv *priv, int reg, u32 val) {
> > + writel(val, priv->reg_base + reg);
> > +}
> > +
> > +/**
> > + * xcan_read_reg - Read a value from the device register
> > + * @priv: Driver private data structure
> > + * @reg: Register offset
> > + *
> > + * Read data from the particular CAN register
> > + * Return: value read from the CAN register */ static u32
> > +xcan_read_reg(const struct xcan_priv *priv, int reg) {
> > + return readl(priv->reg_base + reg);
> > +}
> > +
> > +/**
> > + * set_reset_mode - Resets the CAN device mode
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This is the driver reset mode routine.The driver
> > + * enters into configuration mode.
> > + *
> > + * Return: 0 on success and failure value on error */ static int
> > +set_reset_mode(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + unsigned long timeout;
> > +
> > + priv->can.state = CAN_STATE_STOPPED;
> > + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_OFFSET);
> > +
> > + timeout = jiffies + XCAN_TIMEOUT;
> > + while (!(priv->read_reg(priv, XCAN_SR_OFFSET) &
> XCAN_SR_CONFIG_MASK)) {
> > + if (time_after(jiffies, timeout)) {
> > + netdev_warn(ndev, "timedout waiting for config
> mode\n");
> > + return -ETIMEDOUT;
> > + }
> > + schedule_timeout(1);
>
> better use usleep_range()
>
Ok
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_set_bittiming - CAN set bit timing routine
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This is the driver set bittiming routine.
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_set_bittiming(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + struct can_bittiming *bt = &priv->can.bittiming;
> > + u32 btr0, btr1;
> > + u32 is_config_mode;
> > +
> > + /* Check whether Xilinx CAN is in configuration mode.
> > + * It cannot set bit timing if Xilinx CAN is not in configuration mode.
> > + */
> > + is_config_mode = priv->read_reg(priv, XCAN_SR_OFFSET) &
> > + XCAN_SR_CONFIG_MASK;
> > + if (!is_config_mode) {
> > + netdev_alert(ndev,
> > + "Cannot set bittiming can is not in config mode\n");
> > + return -EPERM;
> > + }
> > +
> > + netdev_dbg(ndev,
> "brp=%d,prop=%d,phase_seg1:%d,phase_reg2=%d,sjw=%d\n",
> > + bt->brp, bt->prop_seg, bt->phase_seg1, bt-
> >phase_seg2,
> > + bt->sjw);
>
> I think this dbg can be removed, as it just prints the userspace values.
>
Ok
> > +
> > + /* Setting Baud Rate prescalar value in BRPR Register */
> > + btr0 = (bt->brp - 1) & XCAN_BRPR_BRP_MASK;
> > +
> > + /* Setting Time Segment 1 in BTR Register */
> > + btr1 = (bt->prop_seg + bt->phase_seg1 - 1) & XCAN_BTR_TS1_MASK;
> > +
> > + /* Setting Time Segment 2 in BTR Register */
> > + btr1 |= ((bt->phase_seg2 - 1) << XCAN_BTR_TS2_SHIFT) &
> > + XCAN_BTR_TS2_MASK;
> > +
> > + /* Setting Synchronous jump width in BTR Register */
> > + btr1 |= ((bt->sjw - 1) << XCAN_BTR_SJW_SHIFT) &
> XCAN_BTR_SJW_MASK;
> > +
> > + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
> > + netdev_info(ndev, "Doesn't support Triple Sampling\n");
>
> no need to check, it's not passed to the driver until you advertise you
> support it (see priv->can.ctrlmode_supported).
Ok
>
> > + netdev_dbg(ndev, "Setting BTR0=0x%02x BTR1=0x%02x\n", btr0,
> btr1);
> > +
> > + priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0);
> > + priv->write_reg(priv, XCAN_BTR_OFFSET, btr1);
> > +
> > + netdev_dbg(ndev, "BRPR=0x%08x, BTR=0x%08x\n",
> > + priv->read_reg(priv, XCAN_BRPR_OFFSET),
> > + priv->read_reg(priv, XCAN_BTR_OFFSET));
>
> One of the dbg should be enough.
>
Ok
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_start - This the drivers start routine
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This is the drivers start routine.
> > + * Based on the State of the CAN device it puts
> > + * the CAN device into a proper mode.
> > + *
> > + * Return: 0 always
> > + */
> > +static int xcan_start(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + /* Check if it is in reset mode */
> > + if (priv->can.state != CAN_STATE_STOPPED)
> > + set_reset_mode(ndev);
>
> Please check return value of set_reset_mode
Ok
>
> > +
> > + /* Enable interrupts */
> > + priv->write_reg(priv, XCAN_IER_OFFSET, XCAN_INTR_ALL);
> > +
> > + /* Check whether it is loopback mode or normal mode */
> > + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
> > + /* Put device into loopback mode */
> > + priv->write_reg(priv, XCAN_MSR_OFFSET,
> XCAN_MSR_LBACK_MASK);
> > + else
> > + /* The device is in normal mode */
> > + priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> > +
> > + if (priv->can.state == CAN_STATE_STOPPED) {
>
> I think your driver is always in CAN_STATE_STOPPED, right?
Usually it in stopped state only(configuration mode) during initialization.
>
> > + /* Enable Xilinx CAN */
> > + priv->write_reg(priv, XCAN_SRR_OFFSET,
> XCAN_SRR_CEN_MASK);
> > + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> > + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
> > + while ((priv->read_reg(priv, XCAN_SR_OFFSET) &
> > + XCAN_SR_LBACK_MASK) == 0)
> > + ;
> > + } else {
> > + while ((priv->read_reg(priv, XCAN_SR_OFFSET)
> > + & XCAN_SR_NORMAL_MASK) == 0)
> > + ;
>
> Please add a timeout to the loops.
Ok
>
> > + }
> > + netdev_dbg(ndev, "status:#x%08x\n",
> > + priv->read_reg(priv, XCAN_SR_OFFSET));
> > + }
> > + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_do_set_mode - This sets the mode of the driver
> > + * @ndev: Pointer to net_device structure
> > + * @mode: Tells the mode of the driver
> > + *
> > + * This check the drivers state and calls the
> > + * the corresponding modes to set.
> > + *
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_do_set_mode(struct net_device *ndev, enum can_mode mode) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + int ret;
> > +
> > + netdev_dbg(ndev, "Setting the mode of the driver%s\n", __func__);
>
> please remove dbg
Ok
>
> > +
> > + if (!priv->open_time)
> > + return -EINVAL;
>
> please remove open_time completely.
Ok
>
> > +
> > + switch (mode) {
> > + case CAN_MODE_START:
> > + ret = xcan_start(ndev);
> > + if (ret < 0)
> > + netdev_err(ndev, "xcan_start failed!\n");
> > +
> > + if (netif_queue_stopped(ndev))
> > + netif_wake_queue(ndev);
>
> just call wake_queue
Ok. But existing drivers are using netif_wake_queue right?
> > + break;
> > + default:
> > + ret = -EOPNOTSUPP;
> > + break;
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +/**
> > + * xcan_start_xmit - Starts the transmission
> > + * @skb: sk_buff pointer that contains data to be Txed
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This function is invoked from upper layers to initiate
> > +transmission. This
> > + * function uses the next available free txbuff and populates their
> > +fields to
> > + * start the transmission.
> > + *
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + struct net_device_stats *stats = &ndev->stats;
> > + struct can_frame *cf = (struct can_frame *)skb->data;
> > + u32 id, dlc, tmp_dw1, tmp_dw2 = 0, data1, data2 = 0;
> > + unsigned long flags;
> > +
>
> Please add here:
>
> if (can_dropped_invalid_skb(dev, skb))
> return NETDEV_TX_OK;
Ok
>
> > + /* Check if the TX buffer is full */
> > + if (priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_TXFLL_MASK)
> {
> > + netif_stop_queue(ndev);
> > + netdev_err(ndev, "TX register is still full!\n");
> > + return NETDEV_TX_BUSY;
> > + } else if (priv->waiting_ech_skb_num == priv-
> >xcan_echo_skb_max_tx) {
> > + netif_stop_queue(ndev);
> > + netdev_err(ndev, "waiting:0x%08x, max:0x%08x\n",
> > + priv->waiting_ech_skb_num, priv-
> >xcan_echo_skb_max_tx);
> > + return NETDEV_TX_BUSY;
> > + }
>
> You should handle flow control after you put the CAN frame into the
> hardware, but before activating the TX complete interrutp.
>
Ok
> > + /* Watch carefully on the bit sequence */
> > + if ((cf->can_id & CAN_EFF_FLAG) == 0) {
>
> Nitpick easier to read is:
>
>
> if (cf->can_id & CAN_EFF_FLAG) {
> /* EFF handling */
> } else {
> /* STD handling */
> }
>
Ok
> > + /* Standard CAN ID format */
> > + id = ((cf->can_id & CAN_SFF_MASK) << XCAN_IDR_ID1_SHIFT)
> &
> > + XCAN_IDR_ID1_MASK;
> > +
> > + if (cf->can_id & CAN_RTR_FLAG)
> > + /* Extended frames remote TX request */
> > + id |= XCAN_IDR_SRR_MASK;
> > + } else {
> > + /* Extended CAN ID format */
> > + id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT)
> &
> > + XCAN_IDR_ID2_MASK;
> > + id |= (((cf->can_id & CAN_EFF_MASK) >>
> > + (CAN_EFF_ID_BITS-CAN_SFF_ID_BITS)) <<
> > + XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK;
> > +
> > + /* The substibute remote TX request bit should be "1"
> > + * for extended frames as in the Xilinx CAN datasheet
> > + */
> > + id |= XCAN_IDR_IDE_MASK | XCAN_IDR_SRR_MASK;
> > +
> > + if (cf->can_id & CAN_RTR_FLAG)
> > + /* Extended frames remote TX request */
> > + id |= XCAN_IDR_RTR_MASK;
> > + }
> > +
> > + dlc = (cf->can_dlc & 0xf) << XCAN_DLCR_DLC_SHIFT;
>
> With the above check can_dlc is valid.
>
> > +
> > + tmp_dw1 = le32_to_cpup((u32 *)(cf->data));
> > + data1 = htonl(tmp_dw1);
>
> This looks broken. cf->data is in big endian, what is the endianess of your
> registers?
>
Endianess of our registers is little endian that's why need to do like this.
> > + if (dlc > 4) {
> > + tmp_dw2 = le32_to_cpup((u32 *)(cf->data + 4));
> > + data2 = htonl(tmp_dw2);
> > + }
> > +
> > + netdev_dbg(ndev,
> "tx:id=0x%08x,dlc=0x%08x,d1=0x%08x,d2=0x%08x\n",
> > + id, dlc, data1, data2);
>
> please remove the dbg
>
Ok
> > + /* Write the Frame to Xilinx CAN TX FIFO */
> > + priv->write_reg(priv, XCAN_TXFIFO_ID_OFFSET, id);
> > + priv->write_reg(priv, XCAN_TXFIFO_DLC_OFFSET, dlc);
> > + priv->write_reg(priv, XCAN_TXFIFO_DW1_OFFSET, data1);
> > + priv->write_reg(priv, XCAN_TXFIFO_DW2_OFFSET, data2);
>
> Which write triggers the transmission?
>
The last write triggers the transmission.
If we are sending data less than 4 bytes in that case also we need to
Fill this( XCAN_TXFIFO_DW2_OFFSET) with default value .
> > + stats->tx_bytes += cf->can_dlc;
>
> Can you move the tx_bytes += to your tx-complete routine?
Ok
>
> > + ndev->trans_start = jiffies;
>
> Please remove
Ok
> > +
> > + can_put_echo_skb(skb, ndev, priv->ech_skb_next);
>
> This looks racy, first fill the echo_skb, then start the transmission.
Ok But I didn't understand it clearly.
Will you please explain a little clear.
> > +
> > + priv->ech_skb_next = (priv->ech_skb_next + 1) %
> > + priv->xcan_echo_skb_max_tx;
> > +
> > + spin_lock_irqsave(&priv->ech_skb_lock, flags);
> > + priv->waiting_ech_skb_num++;
> > + spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
> > +
>
> Please move the flow controll handling here.
>
Ok
> > + return NETDEV_TX_OK;
> > +}
> > +
> > +/**
> > + * xcan_rx - Is called from CAN isr to complete the received
> > + * frame processing
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This function is invoked from the CAN isr(poll) to process the Rx
> > +frames. It
> > + * does minimal processing and invokes "netif_receive_skb" to
> > +complete further
> > + * processing.
> > + * Return: 0 on success and negative error value on error */ static
> > +int xcan_rx(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + struct net_device_stats *stats = &ndev->stats;
> > + struct can_frame *cf;
> > + struct sk_buff *skb;
> > + u32 id_xcan, dlc, data1, data2;
> > +
> > + skb = alloc_can_skb(ndev, &cf);
> > + if (!skb)
> > + return -ENOMEM;
> > +
> > + /* Read a frame from Xilinx zynq CANPS */
> > + id_xcan = priv->read_reg(priv, XCAN_RXFIFO_ID_OFFSET);
> > + dlc = priv->read_reg(priv, XCAN_RXFIFO_DLC_OFFSET) &
> XCAN_DLCR_DLC_MASK;
> > + data1 = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
> > + data2 = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
>
> If you don't use data? below, don't read them in the first place. Better move
> the read below, where you fill the data of the can_frame.
>
Ok
> + netdev_dbg(ndev,
> "rx:id=0x%08x,dlc=0x%08x,d1=0x%08x,d2=0x%08x\n",
> > + id_xcan, dlc, data1, data2);
> >
> please remove dbg
Ok
>
> +
> > + /* Change Xilinx CAN data length format to socketCAN data format
> */
> > + cf->can_dlc = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
> > + XCAN_DLCR_DLC_SHIFT);
> > +
> > + /* Change Xilinx CAN ID format to socketCAN ID format */
> > + if (id_xcan & XCAN_IDR_IDE_MASK) {
> > + /* The received frame is an Extended format frame */
> > + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
> > + cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
> > + XCAN_IDR_ID2_SHIFT;
> > + cf->can_id |= CAN_EFF_FLAG;
> > + if (id_xcan & XCAN_IDR_RTR_MASK)
> > + cf->can_id |= CAN_RTR_FLAG;
> > + } else {
> > + /* The received frame is a standard format frame */
> > + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
> > + XCAN_IDR_ID1_SHIFT;
> > + if (id_xcan & XCAN_IDR_RTR_MASK)
> > + cf->can_id |= CAN_RTR_FLAG;
> > + }
> > +
> > + /* Change Xilinx CAN data format to socketCAN data format */
>
> Don't fill cf->data if RTR is set. The endianess handling looks weird here,
> too.
>
OK
> > + *(u32 *)(cf->data) = ntohl(data1);
> > + if (cf->can_dlc > 4)
> > + *(u32 *)(cf->data + 4) = ntohl(data2);
> > + else
> > + *(u32 *)(cf->data + 4) = 0;
>
> no need to set to zero
>
Ok
> > + stats->rx_bytes += cf->can_dlc;
>
> please group rx_bytes and rx_packets handling
> > +
Ok
> > + can_led_event(ndev, CAN_LED_EVENT_RX);
> > +
> > + netif_receive_skb(skb);
> > +
> > + stats->rx_packets++;
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_err_interrupt - error frame Isr
> > + * @ndev: net_device pointer
> > + * @isr: interrupt status register value
> > + *
> > + * This is the CAN error interrupt and it will
> > + * check the the type of error and forward the error
> > + * frame to upper layers.
> > + */
> > +static void xcan_err_interrupt(struct net_device *ndev, u32 isr) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + struct net_device_stats *stats = &ndev->stats;
> > + struct can_frame *cf;
> > + struct sk_buff *skb;
> > + u32 err_status, status;
> > +
> > + skb = alloc_can_err_skb(ndev, &cf);
> > + if (!skb) {
> > + netdev_err(ndev, "alloc_can_err_skb() failed!\n");
> > + return;
> > + }
> > +
> > + err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
> > + priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);
> > + status = priv->read_reg(priv, XCAN_SR_OFFSET);
> > +
> > + if (isr & XCAN_IXR_BSOFF_MASK) {
> > + priv->can.state = CAN_STATE_BUS_OFF;
> > + cf->can_id |= CAN_ERR_BUSOFF;
> > + priv->can.can_stats.bus_off++;
> > + /* Leave device in Config Mode in bus-off state */
> > + priv->write_reg(priv, XCAN_SRR_OFFSET,
> XCAN_SRR_RESET_MASK);
> > + can_bus_off(ndev);
> > + } else if ((status & XCAN_SR_ESTAT_MASK) ==
> XCAN_SR_ESTAT_MASK) {
> > + cf->can_id |= CAN_ERR_CRTL;
> > + priv->can.state = CAN_STATE_ERROR_PASSIVE;
> > + priv->can.can_stats.error_passive++;
> > + cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE |
> > + CAN_ERR_CRTL_TX_PASSIVE;
> > + } else if (status & XCAN_SR_ERRWRN_MASK) {
> > + cf->can_id |= CAN_ERR_CRTL;
> > + priv->can.state = CAN_STATE_ERROR_WARNING;
> > + priv->can.can_stats.error_warning++;
> > + cf->data[1] |= CAN_ERR_CRTL_RX_WARNING |
> > + CAN_ERR_CRTL_TX_WARNING;
> > + }
> > +
> > + /* Check for Arbitration lost interrupt */
> > + if (isr & XCAN_IXR_ARBLST_MASK) {
> > + cf->can_id |= CAN_ERR_LOSTARB;
> > + cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
> > + priv->can.can_stats.arbitration_lost++;
> > + }
> > +
> > + /* Check for RX FIFO Overflow interrupt */
> > + if (isr & XCAN_IXR_RXOFLW_MASK) {
> > + cf->can_id |= CAN_ERR_CRTL;
> > + cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
> > + stats->rx_over_errors++;
> > + stats->rx_errors++;
> > + priv->write_reg(priv, XCAN_SRR_OFFSET,
> XCAN_SRR_RESET_MASK);
> > + }
> > +
> > + /* Check for error interrupt */
> > + if (isr & XCAN_IXR_ERROR_MASK) {
> > + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> > + cf->data[2] |= CAN_ERR_PROT_UNSPEC;
> > +
> > + /* Check for Ack error interrupt */
> > + if (err_status & XCAN_ESR_ACKER_MASK) {
> > + cf->can_id |= CAN_ERR_ACK;
> > + cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
> > + stats->tx_errors++;
> > + }
> > +
> > + /* Check for Bit error interrupt */
> > + if (err_status & XCAN_ESR_BERR_MASK) {
> > + cf->can_id |= CAN_ERR_PROT;
> > + cf->data[2] = CAN_ERR_PROT_BIT;
> > + stats->tx_errors++;
> > + }
> > +
> > + /* Check for Stuff error interrupt */
> > + if (err_status & XCAN_ESR_STER_MASK) {
> > + cf->can_id |= CAN_ERR_PROT;
> > + cf->data[2] = CAN_ERR_PROT_STUFF;
> > + stats->rx_errors++;
> > + }
> > +
> > + /* Check for Form error interrupt */
> > + if (err_status & XCAN_ESR_FMER_MASK) {
> > + cf->can_id |= CAN_ERR_PROT;
> > + cf->data[2] = CAN_ERR_PROT_FORM;
> > + stats->rx_errors++;
> > + }
> > +
> > + /* Check for CRC error interrupt */
> > + if (err_status & XCAN_ESR_CRCER_MASK) {
> > + cf->can_id |= CAN_ERR_PROT;
> > + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ |
> > + CAN_ERR_PROT_LOC_CRC_DEL;
> > + stats->rx_errors++;
> > + }
> > + priv->can.can_stats.bus_error++;
> > + }
> > +
> > + netif_rx(skb);
> > + stats->rx_packets++;
> > + stats->rx_bytes += cf->can_dlc;
> > +
> > + netdev_dbg(ndev, "%s: error status register:0x%x\n",
> > + __func__, priv->read_reg(priv, XCAN_ESR_OFFSET));
> }
> > +
> > +/**
> > + * xcan_state_interrupt - It will check the state of the CAN device
> > + * @ndev: net_device pointer
> > + * @isr: interrupt status register value
> > + *
> > + * This will checks the state of the CAN device
> > + * and puts the device into appropriate state.
> > + */
> > +static void xcan_state_interrupt(struct net_device *ndev, u32 isr) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + /* Check for Sleep interrupt if set put CAN device in sleep state */
> > + if (isr & XCAN_IXR_SLP_MASK)
> > + priv->can.state = CAN_STATE_SLEEPING;
> > +
> > + /* Check for Wake up interrupt if set put CAN device in Active state
> */
> > + if (isr & XCAN_IXR_WKUP_MASK)
> > + priv->can.state = CAN_STATE_ERROR_ACTIVE; }
> > +
> > +/**
> > + * xcan_rx_poll - Poll routine for rx packets (NAPI)
> > + * @napi: napi structure pointer
> > + * @quota: Max number of rx packets to be processed.
> > + *
> > + * This is the poll routine for rx part.
> > + * It will process the packets maximux quota value.
> > + *
> > + * Return: number of packets received */ static int
> > +xcan_rx_poll(struct napi_struct *napi, int quota) {
> > + struct net_device *ndev = napi->dev;
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + u32 isr, ier;
> > + int work_done = 0;
> > +
> > + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> > + while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) {
> > + if (isr & XCAN_IXR_RXOK_MASK) {
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> > + XCAN_IXR_RXOK_MASK);
> > + if (xcan_rx(ndev) < 0)
> > + return work_done;
> > + work_done++;
> > + } else {
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> > + XCAN_IXR_RXNEMP_MASK);
> > + break;
> > + }
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> XCAN_IXR_RXNEMP_MASK);
> > + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> > + }
> > +
> > + if (work_done < quota) {
> > + napi_complete(napi);
> > + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> > + ier |= (XCAN_IXR_RXOK_MASK |
> XCAN_IXR_RXNEMP_MASK);
> > + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> > + }
> > + return work_done;
> > +}
> > +
> > +/**
> > + * xcan_tx_interrupt - Tx Done Isr
> > + * @ndev: net_device pointer
> > + */
> > +static void xcan_tx_interrupt(struct net_device *ndev) {
> > + unsigned long flags;
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + struct net_device_stats *stats = &ndev->stats;
> > + u32 processed = 0, txpackets;
> > +
> > + stats->tx_packets++;
> > + netdev_dbg(ndev, "%s: waiting total:%d,current:%d\n", __func__,
> > + priv->waiting_ech_skb_num, priv-
> >waiting_ech_skb_index);
> > +
> > + txpackets = priv->waiting_ech_skb_num;
> > +
> > + if (txpackets) {
> > + can_get_echo_skb(ndev, priv->waiting_ech_skb_index);
> > + priv->waiting_ech_skb_index =
> > + (priv->waiting_ech_skb_index + 1) %
> > + priv->xcan_echo_skb_max_tx;
> > + processed++;
> > + txpackets--;
> > + }
> > +
> > + spin_lock_irqsave(&priv->ech_skb_lock, flags);
> > + priv->waiting_ech_skb_num -= processed;
> > + spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
> > +
> > + netdev_dbg(ndev, "%s: waiting total:%d,current:%d\n", __func__,
> > + priv->waiting_ech_skb_num, priv-
> >waiting_ech_skb_index);
> > +
> > + netif_wake_queue(ndev);
> > +
> > + can_led_event(ndev, CAN_LED_EVENT_TX); }
> > +
> > +/**
> > + * xcan_interrupt - CAN Isr
> > + * @irq: irq number
> > + * @dev_id: device id poniter
> > + *
> > + * This is the xilinx CAN Isr. It checks for the type of interrupt
> > + * and invokes the corresponding ISR.
> > + *
> > + * Return:
> > + * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
> > +*/ static irqreturn_t xcan_interrupt(int irq, void *dev_id) {
> > + struct net_device *ndev = (struct net_device *)dev_id;
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + u32 isr, ier;
> > +
> > + if (priv->can.state == CAN_STATE_STOPPED)
>
> This should not happen, please remove.
Ok
>
> > + return IRQ_NONE;
> > +
> > + /* Get the interrupt status from Xilinx CAN */
> > + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> > + if (!isr)
> > + return IRQ_NONE;
> > +
> > + netdev_dbg(ndev, "%s: isr:#x%08x, err:#x%08x\n", __func__,
> > + isr, priv->read_reg(priv, XCAN_ESR_OFFSET));
> > +
> > + /* Check for the type of interrupt and Processing it */
> > + if (isr & (XCAN_IXR_SLP_MASK | XCAN_IXR_WKUP_MASK)) {
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> (XCAN_IXR_SLP_MASK |
> > + XCAN_IXR_WKUP_MASK));
> > + xcan_state_interrupt(ndev, isr);
> > + }
> > +
> > + /* Check for Tx interrupt and Processing it */
> > + if (isr & XCAN_IXR_TXOK_MASK) {
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> XCAN_IXR_TXOK_MASK);
> > + xcan_tx_interrupt(ndev);
> > + }
> > +
> > + /* Check for the type of error interrupt and Processing it */
> > + if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
> > + XCAN_IXR_BSOFF_MASK |
> XCAN_IXR_ARBLST_MASK)) {
> > + priv->write_reg(priv, XCAN_ICR_OFFSET,
> (XCAN_IXR_ERROR_MASK |
> > + XCAN_IXR_RXOFLW_MASK |
> XCAN_IXR_BSOFF_MASK |
> > + XCAN_IXR_ARBLST_MASK));
> > + xcan_err_interrupt(ndev, isr);
> > + }
> > +
> > + /* Check for the type of receive interrupt and Processing it */
> > + if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) {
> > + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> > + ier &= ~(XCAN_IXR_RXNEMP_MASK |
> XCAN_IXR_RXOK_MASK);
> > + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> > + napi_schedule(&priv->napi);
> > + }
> > + return IRQ_HANDLED;
> > +}
> > +
> > +/**
> > + * xcan_stop - Driver stop routine
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This is the drivers stop routine. It will disable the
> > + * interrupts and put the device into configuration mode.
> > + */
> > +static void xcan_stop(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + u32 ier;
> > +
> > + /* Disable interrupts and leave the can in configuration mode */
> > + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> > + ier &= ~XCAN_INTR_ALL;
> > + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> > + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
> > + priv->can.state = CAN_STATE_STOPPED; }
> > +
> > +/**
> > + * xcan_open - Driver open routine
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * This is the driver open routine.
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_open(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + int err;
> > +
> > + /* Set chip into reset mode */
> > + err = set_reset_mode(ndev);
> > + if (err < 0)
> > + netdev_err(ndev, "mode resetting failed failed!\n");
> > +
> > + /* Common open */
> > + err = open_candev(ndev);
> > + if (err)
> > + return err;
> > +
> > + err = xcan_start(ndev);
> > + if (err < 0)
> > + netdev_err(ndev, "xcan_start failed!\n");
> > +
> > +
> > + can_led_event(ndev, CAN_LED_EVENT_OPEN);
> > + napi_enable(&priv->napi);
> > + netif_start_queue(ndev);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_close - Driver close routine
> > + * @ndev: Pointer to net_device structure
> > + *
> > + * Return: 0 always
> > + */
> > +static int xcan_close(struct net_device *ndev) {
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + netif_stop_queue(ndev);
> > + napi_disable(&priv->napi);
> > + xcan_stop(ndev);
> > + close_candev(ndev);
> > +
> > + can_led_event(ndev, CAN_LED_EVENT_STOP);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_get_berr_counter - error counter routine
> > + * @ndev: Pointer to net_device structure
> > + * @bec: Pointer to can_berr_counter structure
> > + *
> > + * This is the driver error counter routine.
> > + * Return: 0 always
> > + */
> > +static int xcan_get_berr_counter(const struct net_device *ndev,
> > + struct can_berr_counter *bec)
> > +{
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) &
> XCAN_ECR_TEC_MASK;
> > + bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
> > + XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
> > + return 0;
> > +}
> > +
> > +static const struct net_device_ops xcan_netdev_ops = {
> > + .ndo_open = xcan_open,
> > + .ndo_stop = xcan_close,
> > + .ndo_start_xmit = xcan_start_xmit,
> > +};
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +/**
> > + * xcan_suspend - Suspend method for the driver
> > + * @_dev: Address of the platform_device structure
> > + *
> > + * Put the driver into low power mode.
> > + * Return: 0 always
> > + */
> > +static int xcan_suspend(struct device *_dev) {
> > + struct platform_device *pdev = container_of(_dev,
> > + struct platform_device, dev);
> > + struct net_device *ndev = platform_get_drvdata(pdev);
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + if (netif_running(ndev)) {
> > + netif_stop_queue(ndev);
> > + netif_device_detach(ndev);
> > + }
> > +
> > + priv->write_reg(priv, XCAN_MSR_OFFSET,
> XCAN_MSR_SLEEP_MASK);
> > + priv->can.state = CAN_STATE_SLEEPING;
> > +
> > + clk_disable(priv->aperclk);
> > + clk_disable(priv->devclk);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_resume - Resume from suspend
> > + * @dev: Address of the platformdevice structure
> > + *
> > + * Resume operation after suspend.
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_resume(struct device *dev) {
> > + struct platform_device *pdev = container_of(dev,
> > + struct platform_device, dev);
> > + struct net_device *ndev = platform_get_drvdata(pdev);
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > + int ret;
> > +
> > + ret = clk_enable(priv->aperclk);
> > + if (ret) {
> > + dev_err(dev, "Cannot enable clock.\n");
> > + return ret;
> > + }
> > + ret = clk_enable(priv->devclk);
> > + if (ret) {
> > + dev_err(dev, "Cannot enable clock.\n");
> > + return ret;
> > + }
> > +
> > + priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> > + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
> > + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> > +
> > + if (netif_running(ndev)) {
> > + netif_device_attach(ndev);
> > + netif_start_queue(ndev);
> > + }
> > +
> > + return 0;
> > +}
> > +#endif
> > +
> > +static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend,
> xcan_resume);
> > +
> > +/**
> > + * xcan_probe - Platform registration call
> > + * @pdev: Handle to the platform device structure
> > + *
> > + * This function does all the memory allocation and registration for
> > +the CAN
> > + * device.
> > + *
> > + * Return: 0 on success and failure value on error */ static int
> > +xcan_probe(struct platform_device *pdev) {
> > + struct resource *res; /* IO mem resources */
> > + struct net_device *ndev;
> > + struct xcan_priv *priv;
> > + int ret, fifodep;
> > +
> > + /* Create a CAN device instance */
> > + ndev = alloc_candev(sizeof(struct xcan_priv),
> XCAN_ECHO_SKB_MAX);
> > + if (!ndev)
> > + return -ENOMEM;
> > +
> > + priv = netdev_priv(ndev);
> > + priv->dev = ndev;
> > + priv->can.bittiming_const = &xcan_bittiming_const;
> > + priv->can.do_set_bittiming = xcan_set_bittiming;
> > + priv->can.do_set_mode = xcan_do_set_mode;
> > + priv->can.do_get_berr_counter = xcan_get_berr_counter;
> > + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
> > + CAN_CTRLMODE_BERR_REPORTING;
> > + priv->xcan_echo_skb_max_tx = XCAN_ECHO_SKB_MAX;
> > + priv->xcan_echo_skb_max_rx = XCAN_NAPI_WEIGHT;
> > +
> > + /* Get IRQ for the device */
> > + ndev->irq = platform_get_irq(pdev, 0);
> > + ret = devm_request_irq(&pdev->dev, ndev->irq, &xcan_interrupt,
> > + priv->irq_flags, dev_name(&pdev->dev),
> > + (void *)ndev);
>
> We usually request the interrupt on in the open() function
>
Ok Will Move into open routine
Regards,
Kedar.
> > + if (ret < 0) {
> > + dev_err(&pdev->dev, "Irq allocation for CAN failed\n");
> > + goto err_free;
> > + }
> > +
> > + spin_lock_init(&priv->ech_skb_lock);
> > + ndev->flags |= IFF_ECHO; /* We support local echo */
> > +
> > + platform_set_drvdata(pdev, ndev);
> > + SET_NETDEV_DEV(ndev, &pdev->dev);
> > + ndev->netdev_ops = &xcan_netdev_ops;
> > +
> > + /* Get the virtual base address for the device */
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
> > + if (IS_ERR(priv->reg_base)) {
> > + ret = PTR_ERR(priv->reg_base);
> > + goto err_free;
> > + }
> > + ndev->mem_start = res->start;
> > + ndev->mem_end = res->end;
> > +
> > + priv->write_reg = xcan_write_reg;
> > + priv->read_reg = xcan_read_reg;
> > +
> > + /* Getting the CAN devclk info */
> > + priv->devclk = devm_clk_get(&pdev->dev, "ref_clk");
> > + if (IS_ERR(priv->devclk)) {
> > + dev_err(&pdev->dev, "Device clock not found.\n");
> > + ret = PTR_ERR(priv->devclk);
> > + goto err_free;
> > + }
> > +
> > + /* Check for type of CAN device */
> > + if (of_device_is_compatible(pdev->dev.of_node,
> > + "xlnx,zynq-can-1.00.a")) {
> > + priv->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
> > + if (IS_ERR(priv->aperclk)) {
> > + dev_err(&pdev->dev, "aper clock not found\n");
> > + ret = PTR_ERR(priv->aperclk);
> > + goto err_free;
> > + }
> > + } else {
> > + priv->aperclk = priv->devclk;
> > + ret = of_property_read_u32(pdev->dev.of_node,
> > + "xlnx,can-tx-dpth", &fifodep);
> > + if (ret < 0)
> > + goto err_free;
> > + priv->xcan_echo_skb_max_tx = fifodep;
> > + ret = of_property_read_u32(pdev->dev.of_node,
> > + "xlnx,can-rx-dpth", &fifodep);
> > + if (ret < 0)
> > + goto err_free;
> > + priv->xcan_echo_skb_max_rx = fifodep;
> > + }
> > +
> > + ret = clk_prepare_enable(priv->devclk);
> > + if (ret) {
> > + dev_err(&pdev->dev, "unable to enable device clock\n");
> > + goto err_free;
> > + }
> > +
> > + ret = clk_prepare_enable(priv->aperclk);
> > + if (ret) {
> > + dev_err(&pdev->dev, "unable to enable aper clock\n");
> > + goto err_unprepar_disabledev;
> > + }
> > +
> > + priv->can.clock.freq = clk_get_rate(priv->devclk);
> > +
> > + netif_napi_add(ndev, &priv->napi, xcan_rx_poll,
> > + priv->xcan_echo_skb_max_rx);
> > + ret = register_candev(ndev);
> > + if (ret) {
> > + dev_err(&pdev->dev, "fail to register failed (err=%d)\n",
> ret);
> > + goto err_unprepar_disableaper;
> > + }
> > +
> > + devm_can_led_init(ndev);
> > + dev_info(&pdev->dev,
> > + "reg_base=0x%p irq=%d clock=%d, tx fifo
> depth:%d\n",
> > + priv->reg_base, ndev->irq, priv->can.clock.freq,
> > + priv->xcan_echo_skb_max_tx);
> > +
> > + return 0;
> > +
> > +err_unprepar_disableaper:
> > + clk_disable_unprepare(priv->aperclk);
> > +err_unprepar_disabledev:
> > + clk_disable_unprepare(priv->devclk);
> > +err_free:
> > + free_candev(ndev);
> > +
> > + return ret;
> > +}
> > +
> > +/**
> > + * xcan_remove - Unregister the device after releasing the resources
> > + * @pdev: Handle to the platform device structure
> > + *
> > + * This function frees all the resources allocated to the device.
> > + * Return: 0 always
> > + */
> > +static int xcan_remove(struct platform_device *pdev) {
> > + struct net_device *ndev = platform_get_drvdata(pdev);
> > + struct xcan_priv *priv = netdev_priv(ndev);
> > +
> > + if (set_reset_mode(ndev) < 0)
> > + netdev_err(ndev, "mode resetting failed!\n");
> > +
> > + unregister_candev(ndev);
> > + netif_napi_del(&priv->napi);
> > + clk_disable_unprepare(priv->aperclk);
> > + clk_disable_unprepare(priv->devclk);
> > +
> > + free_candev(ndev);
> > +
> > + return 0;
> > +}
> > +
> > +/* Match table for OF platform binding */ static struct of_device_id
> > +xcan_of_match[] = {
> > + { .compatible = "xlnx,zynq-can-1.00.a", },
> > + { .compatible = "xlnx,axi-can-1.00.a", },
> > + { /* end of list */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, xcan_of_match);
> > +
> > +static struct platform_driver xcan_driver = {
> > + .probe = xcan_probe,
> > + .remove = xcan_remove,
> > + .driver = {
> > + .owner = THIS_MODULE,
> > + .name = DRIVER_NAME,
> > + .pm = &xcan_dev_pm_ops,
> > + .of_match_table = xcan_of_match,
> > + },
> > +};
> > +
> > +module_platform_driver(xcan_driver);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Xilinx Inc");
> > +MODULE_DESCRIPTION("Xilinx CAN interface");
> >
>
>
> --
> 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 |
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
^ permalink raw reply
* [PATCH] pinctrl:at91:add drive strength configuration
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390285991-1634-1-git-send-email-mark.roszko@gmail.com>
On 01:33 Tue 21 Jan , Marek Roszko wrote:
> The SAMA5 and most SAM9xGs(baring a few exceptions like the SAM945G) have drive
> control registers that allow configuring the output current of the gpio pins between
> three predefined levels of low,medium and high drive.
>
> This patch adds four new dt-bindings that allow setting the strength via the device tree.
> Added set/get drive strength to pinctrl ops table.
> A sama5d3-gpio of id entry was made to set the set/get drive strength function for the
> sam5d3s which unforunately have different register addresses and strength-to-value
> map than the sam9s.
> Added PIO_DRIVER1/2 defines in at91_pio.h prefixed with the target SoC.
missing the SoB so we can not apply it
otherwise
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
and please split the patch in 2 dt and driver
Best Regards,
J.
> ---
> arch/arm/boot/dts/sama5d3.dtsi | 10 +--
> arch/arm/mach-at91/include/mach/at91_pio.h | 7 ++
> drivers/pinctrl/pinctrl-at91.c | 131 +++++++++++++++++++++++++++-
> include/dt-bindings/pinctrl/at91.h | 5 ++
> 4 files changed, 147 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
> index 5cdaba4..5576330 100644
> --- a/arch/arm/boot/dts/sama5d3.dtsi
> +++ b/arch/arm/boot/dts/sama5d3.dtsi
> @@ -619,7 +619,7 @@
>
>
> pioA: gpio at fffff200 {
> - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
> + compatible = "atmel,sama5d3-gpio", "atmel,at91rm9200-gpio";
> reg = <0xfffff200 0x100>;
> interrupts = <6 IRQ_TYPE_LEVEL_HIGH 1>;
> #gpio-cells = <2>;
> @@ -629,7 +629,7 @@
> };
>
> pioB: gpio at fffff400 {
> - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
> + compatible = "atmel,sama5d3-gpio", "atmel,at91rm9200-gpio";
> reg = <0xfffff400 0x100>;
> interrupts = <7 IRQ_TYPE_LEVEL_HIGH 1>;
> #gpio-cells = <2>;
> @@ -639,7 +639,7 @@
> };
>
> pioC: gpio at fffff600 {
> - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
> + compatible = "atmel,sama5d3-gpio", "atmel,at91rm9200-gpio";
> reg = <0xfffff600 0x100>;
> interrupts = <8 IRQ_TYPE_LEVEL_HIGH 1>;
> #gpio-cells = <2>;
> @@ -649,7 +649,7 @@
> };
>
> pioD: gpio at fffff800 {
> - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
> + compatible = "atmel,sama5d3-gpio", "atmel,at91rm9200-gpio";
> reg = <0xfffff800 0x100>;
> interrupts = <9 IRQ_TYPE_LEVEL_HIGH 1>;
> #gpio-cells = <2>;
> @@ -659,7 +659,7 @@
> };
>
> pioE: gpio at fffffa00 {
> - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
> + compatible = "atmel,sama5d3-gpio", "atmel,at91rm9200-gpio";
> reg = <0xfffffa00 0x100>;
> interrupts = <10 IRQ_TYPE_LEVEL_HIGH 1>;
> #gpio-cells = <2>;
> diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h
> index 732b11c..b1e6380 100644
> --- a/arch/arm/mach-at91/include/mach/at91_pio.h
> +++ b/arch/arm/mach-at91/include/mach/at91_pio.h
> @@ -66,6 +66,13 @@
> #define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */
> #define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */
>
> +
> +#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/
> +#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/
> +
> +#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/
> +#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/
> +
> #define ABCDSR_PERIPH_A 0x0
> #define ABCDSR_PERIPH_B 0x1
> #define ABCDSR_PERIPH_C 0x2
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index a7549c4..d79e085 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -62,10 +62,21 @@ static int gpio_banks;
> #define DEGLITCH (1 << 2)
> #define PULL_DOWN (1 << 3)
> #define DIS_SCHMIT (1 << 4)
> +#define DRIVE_STRENGTH_SHIFT 5
> +#define DRIVE_STRENGTH (0x3 << DRIVE_STRENGTH_SHIFT)
> #define DEBOUNCE (1 << 16)
> #define DEBOUNCE_VAL_SHIFT 17
> #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
>
> +#define DRIVE_STRENGTH_DEFAULT (0x0 << 5)
> +#define DRIVE_STRENGTH_LOW (0x1 << 5)
> +#define DRIVE_STRENGTH_MED (0x2 << 5)
> +#define DRIVE_STRENGTH_HI (0x3 << 5)
> +
> +
> +#define DRIVE_STRENGTH_MASK 0x3
> +#define NUM_PINS_PER_DIVIDED_REGS 16
> +
> /**
> * struct at91_pmx_func - describes AT91 pinmux functions
> * @name: the name of this specific function
> @@ -148,6 +159,8 @@ struct at91_pinctrl_mux_ops {
> void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on);
> bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
> void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 div);
> + unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin);
> + void (*set_drivestrength)(void __iomem *pio, unsigned pin, u32 strength);
> bool (*get_pulldown)(void __iomem *pio, unsigned pin);
> void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
> bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
> @@ -319,6 +332,24 @@ static unsigned pin_to_mask(unsigned int pin)
> return 1 << pin;
> }
>
> +static inline int two_bit_pin_value_shift(unsigned pin)
> +{
> + return 2*((pin >= NUM_PINS_PER_DIVIDED_REGS)
> + ? pin - NUM_PINS_PER_DIVIDED_REGS : pin);
> +}
> +
> +static unsigned sama5d3_get_drive_register(unsigned int pin)
> +{
> + return (pin > NUM_PINS_PER_DIVIDED_REGS-1)
> + ? SAMA5D3_PIO_DRIVER2: SAMA5D3_PIO_DRIVER1;
> +}
> +
> +static unsigned at91sam9x5_get_drive_register(unsigned int pin)
> +{
> + return (pin > NUM_PINS_PER_DIVIDED_REGS-1)
> + ? AT91SAM9X5_PIO_DRIVER2: AT91SAM9X5_PIO_DRIVER1;
> +}
> +
> static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
> {
> writel_relaxed(mask, pio + PIO_IDR);
> @@ -462,6 +493,73 @@ static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is
> __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
> }
>
> +static inline u32 read_drive_strength(void __iomem *reg, unsigned pin)
> +{
> + unsigned tmp = __raw_readl(reg);
> + tmp = tmp >> two_bit_pin_value_shift(pin)
> +
> + return tmp & DRIVE_STRENGTH_MASK;
> +}
> +
> +static unsigned at91_mux_sama5d3_get_drivestrength(void __iomem *pio, unsigned pin)
> +{
> + unsigned tmp = read_drive_strength(pio + sama5d3_get_drive_register(pin), pin);
> +
> + /*value of 0 = low, all other values are 1 to 1*/
> + if (!tmp)
> + tmp = DRIVE_STRENGTH_LOW;
> +
> + return tmp;
> +}
> +
> +static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio, unsigned pin)
> +{
> + unsigned tmp = read_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin);
> +
> + /*
> + * inverse the setting for dt defines
> + * 0 = hi, 1 = med, 2 = low, 3 = rsvd
> + */
> + tmp = DRIVE_STRENGTH_HI - tmp;
> +
> + return tmp;
> +}
> +
> +static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength)
> +{
> + unsigned tmp = __raw_readl(reg);
> +
> + tmp &= ~(DRIVE_STRENGTH_MASK << two_bit_pin_value_shift(pin));
> + tmp |= strength << two_bit_pin_value_shift(pin);
> +
> + __raw_writel(tmp, reg);
> +}
> +
> +static void at91_mux_sama5d3_set_drivestrength(void __iomem *pio, unsigned pin,
> + u32 setting)
> +{
> + /* do nothing if setting is zero */
> + if (!setting)
> + return;
> +
> + /* strength is 1 to 1 with setting for SAMA5 */
> + set_drive_strength(pio + sama5d3_get_drive_register(pin), pin, setting);
> +}
> +
> +static void at91_mux_sam9x5_set_drivestrength(void __iomem *pio, unsigned pin,
> + u32 setting)
> +{
> + /* do nothing if setting is zero */
> + if (!setting)
> + return;
> +
> + /* strength is inverse on SAM9s, 0 = hi, 1 = med, 2 = low, 3 = rsvd */
> + setting = DRIVE_STRENGTH_HI - setting;
> +
> + set_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin, setting);
> +}
> +
> +
> static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask)
> {
> __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
> @@ -491,6 +589,27 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
> .set_deglitch = at91_mux_pio3_set_deglitch,
> .get_debounce = at91_mux_pio3_get_debounce,
> .set_debounce = at91_mux_pio3_set_debounce,
> + .get_drivestrength = at91_mux_sam9x5_get_drivestrength,
> + .set_drivestrength = at91_mux_sam9x5_set_drivestrength,
> + .get_pulldown = at91_mux_pio3_get_pulldown,
> + .set_pulldown = at91_mux_pio3_set_pulldown,
> + .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
> + .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
> + .irq_type = alt_gpio_irq_type,
> +};
> +
> +static struct at91_pinctrl_mux_ops sama5d3_ops = {
> + .get_periph = at91_mux_pio3_get_periph,
> + .mux_A_periph = at91_mux_pio3_set_A_periph,
> + .mux_B_periph = at91_mux_pio3_set_B_periph,
> + .mux_C_periph = at91_mux_pio3_set_C_periph,
> + .mux_D_periph = at91_mux_pio3_set_D_periph,
> + .get_deglitch = at91_mux_pio3_get_deglitch,
> + .set_deglitch = at91_mux_pio3_set_deglitch,
> + .get_debounce = at91_mux_pio3_get_debounce,
> + .set_debounce = at91_mux_pio3_set_debounce,
> + .get_drivestrength = at91_mux_sama5d3_get_drivestrength,
> + .set_drivestrength = at91_mux_sama5d3_set_drivestrength,
> .get_pulldown = at91_mux_pio3_get_pulldown,
> .set_pulldown = at91_mux_pio3_set_pulldown,
> .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
> @@ -498,6 +617,7 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
> .irq_type = alt_gpio_irq_type,
> };
>
> +
> static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin)
> {
> if (pin->mux) {
> @@ -736,6 +856,9 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
> *config |= DEGLITCH;
> if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div))
> *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT);
> + if (info->ops->get_drivestrength)
> + *config |= DRIVE_STRENGTH | (info->ops->get_drivestrength(pio, pin)
> + << DRIVE_STRENGTH_SHIFT);
> if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin))
> *config |= PULL_DOWN;
> if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin))
> @@ -753,6 +876,7 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
> void __iomem *pio;
> int i;
> unsigned long config;
> + unsigned pin;
>
> for (i = 0; i < num_configs; i++) {
> config = configs[i];
> @@ -761,7 +885,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
> "%s:%d, pin_id=%d, config=0x%lx",
> __func__, __LINE__, pin_id, config);
> pio = pin_to_controller(info, pin_to_bank(pin_id));
> - mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
> + pin = pin_id % MAX_NB_GPIO_PER_BANK;
> + mask = pin_to_mask(pin);
>
> if (config & PULL_UP && config & PULL_DOWN)
> return -EINVAL;
> @@ -773,6 +898,9 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
> if (info->ops->set_debounce)
> info->ops->set_debounce(pio, mask, config & DEBOUNCE,
> (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT);
> + if (info->ops->set_drivestrength)
> + info->ops->set_drivestrength(pio, pin,
> + (config & DRIVE_STRENGTH) >> DRIVE_STRENGTH_SHIFT);
> if (info->ops->set_pulldown)
> info->ops->set_pulldown(pio, mask, config & PULL_DOWN);
> if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
> @@ -1551,6 +1679,7 @@ static void at91_gpio_probe_fixup(void)
>
> static struct of_device_id at91_gpio_of_match[] = {
> { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, },
> + { .compatible = "atmel,sama5d3-gpio", .data = &sama5d3_ops, },
> { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops },
> { /* sentinel */ }
> };
> diff --git a/include/dt-bindings/pinctrl/at91.h b/include/dt-bindings/pinctrl/at91.h
> index 0fee6ff..af71ebb 100644
> --- a/include/dt-bindings/pinctrl/at91.h
> +++ b/include/dt-bindings/pinctrl/at91.h
> @@ -20,6 +20,11 @@
>
> #define AT91_PINCTRL_PULL_UP_DEGLITCH (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DEGLITCH)
>
> +#define AT91_PINCTRL_DRIVE_STRENGTH_DEFAULT (0x0 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_LOW (0x1 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_MED (0x2 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_HI (0x3 << 5)
> +
> #define AT91_PIOA 0
> #define AT91_PIOB 1
> #define AT91_PIOC 2
> --
> 1.7.10.4
>
^ permalink raw reply
* [PATCH 1/2] USB: at91: fix the number of endpoint parameter
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DE389B.3000702@atmel.com>
On 10:06 Tue 21 Jan , Nicolas Ferre wrote:
> On 21/01/2014 09:12, Bo Shen :
> > Hi J,
> >
> > On 01/21/2014 01:49 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >> On 11:39 Mon 20 Jan , Bo Shen wrote:
> >>> Hi J,
> >>>
> >>> On 01/18/2014 01:20 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>> On 10:59 Fri 17 Jan , Bo Shen wrote:
> >>>>> In sama5d3 SoC, there are 16 endpoints. As the USBA_NR_ENDPOINTS
> >>>>> is only 7. So, fix it for sama5d3 SoC using the udc->num_ep.
> >>>>>
> >>>>> Signed-off-by: Bo Shen <voice.shen@atmel.com>
> >>>>> ---
> >>>>>
> >>>>> drivers/usb/gadget/atmel_usba_udc.c | 2 +-
> >>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
> >>>>> index 2cb52e0..7e67a81 100644
> >>>>> --- a/drivers/usb/gadget/atmel_usba_udc.c
> >>>>> +++ b/drivers/usb/gadget/atmel_usba_udc.c
> >>>>> @@ -1670,7 +1670,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
> >>>>> if (ep_status) {
> >>>>> int i;
> >>>>>
> >>>>> - for (i = 0; i < USBA_NR_ENDPOINTS; i++)
> >>>>> + for (i = 0; i < udc->num_ep; i++)
> >>>>
> >>>> no the limit need to specified in the driver as a checkpoint by the compatible
> >>>> or platform driver id
> >>>
> >>> You mean, we should not trust the data passed from dt node or
> >>> platform data? Or do you think we should do double confirm?
> >>
> >> no base on the driver name or the compatible you will known the MAX EP
> >>
> >> not based on the dt ep description
> >>
> >> as we do on pinctrl-at91
> >
> > I am sorry, I am not fully get it after reading the code of
> > pinctrl-at91.c, can you give the example code in pinctrl-at91.c?
> >
> > Btw, the udc->num_ep is get from the following code.
> > for dt
> > --->8---
> > while ((pp = of_get_next_child(np, pp)))
> > udc->num_ep++;
> > ---<8---
> >
> > for non-dt
> > --->8---
> > udc->num_ep = pdata->num_ep;
> > ---8<---
>
> It seems to me pretty valid to use num_ep in this driver and not have to
> rely on another compatibility string just for this.
> The information is here, it is retrieved pretty cleanly so I vote for a
> simple use of it: if we introduce another information we will have to
> double check the cross errors that would happen...
here is the key point you describe the HW
so choose detect the IP version and then check we do not describe too many EP
or you prove the correct compatible so we known this not the same IP
and we can check the DT information
Best Regards,
J.
>
> Bye,
>
> >>>>> if (ep_status & (1 << i)) {
> >>>>> if (ep_is_control(&udc->usba_ep[i]))
> >>>>> usba_control_irq(udc, &udc->usba_ep[i]);
> >>>>> --
> >>>>> 1.8.5.2
> >>>>>
> >>>
> >>> Best Regards,
> >>> Bo Shen
> >
> > Best Regards,
> > Bo Shen
> >
>
>
> --
> Nicolas Ferre
^ permalink raw reply
* [PATCH v4 02/10] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
From: Anup Patel @ 2014-02-07 8:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <003501cf23de$a4a878d0$edf96a70$@samsung.com>
On Fri, Feb 7, 2014 at 1:58 PM, Jungseok Lee <jays.lee@samsung.com> wrote:
> On Thursday, February 06, 2014 8:32 PM, Anup Patel wrote:
>> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to VCPUs. This patch extends
>> current in-kernel PSCI emulation to provide PSCI v0.2 interface to VCPUs.
>>
>> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for keeping the ABI backward-
>> compatible.
>>
>> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
>> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU init using KVM_ARM_VCPU_INIT
>> ioctl.
>>
>> Signed-off-by: Anup Patel <anup.patel@linaro.org>
>> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
>> ---
>> arch/arm/include/asm/kvm_host.h | 2 +-
>> arch/arm/include/asm/kvm_psci.h | 4 ++
>> arch/arm/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>> arch/arm/kvm/arm.c | 1 +
>> arch/arm/kvm/psci.c | 85 +++++++++++++++++++++++++++++++------
>> arch/arm64/include/asm/kvm_host.h | 2 +-
>> arch/arm64/include/asm/kvm_psci.h | 4 ++
>> arch/arm64/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>> 8 files changed, 152 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 09af149..193ceaf
>> 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -36,7 +36,7 @@
>> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #define KVM_HAVE_ONE_REG
>>
>> -#define KVM_VCPU_MAX_FEATURES 1
>> +#define KVM_VCPU_MAX_FEATURES 2
>>
>> #include <kvm/arm_vgic.h>
>>
>> diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h index 9a83d98..4c0e3e1
>> 100644
>> --- a/arch/arm/include/asm/kvm_psci.h
>> +++ b/arch/arm/include/asm/kvm_psci.h
>> @@ -18,6 +18,10 @@
>> #ifndef __ARM_KVM_PSCI_H__
>> #define __ARM_KVM_PSCI_H__
>>
>> +#define KVM_ARM_PSCI_0_1 1
>> +#define KVM_ARM_PSCI_0_2 2
>> +
>> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>
>> #endif /* __ARM_KVM_PSCI_H__ */
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index ef0c878..9c922d9
>> 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -83,6 +83,7 @@ struct kvm_regs {
>> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -192,7 +193,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -201,9 +202,41 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>
> Hi
>
> This patch describes PSCI v0.2 specification well. Instead,
> I have a question on interface types, not implementation.
>
> According to PSCI v0.2 document, it does not cover DVFS.
> Could I get an idea why DVFS is not supported?
PSCI v0.2 only describes few mandatory functions required for
being PSCI v0.2 compliant. For rest of the stuff such as DVFS
you will need to define your own platform specific PSCI function.
(Marc/Mark correct me if I am wrong here?)
Mab be in future some PSCI vX.Y will define standardized PSCI
function for DVFS too.
Regards,
Anup
>
> Best Regards
> Jungseok Lee
>
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> #define KVM_PSCI_RET_NI ((unsigned long)-1)
>> #define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif /* __ARM_KVM_H__ */
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 1d8248e..c8a71df 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -197,6 +197,7 @@ int kvm_dev_ioctl_check_extension(long ext)
>> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
>> case KVM_CAP_ONE_REG:
>> case KVM_CAP_ARM_PSCI:
>> + case KVM_CAP_ARM_PSCI_0_2:
>> r = 1;
>> break;
>> case KVM_CAP_COALESCED_MMIO:
>> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 448f60e..e4ec4af 100644
>> --- a/arch/arm/kvm/psci.c
>> +++ b/arch/arm/kvm/psci.c
>> @@ -85,17 +85,57 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> return KVM_PSCI_RET_SUCCESS;
>> }
>>
>> -/**
>> - * kvm_psci_call - handle PSCI call if r0 value is in range
>> - * @vcpu: Pointer to the VCPU struct
>> - *
>> - * Handle PSCI calls from guests through traps from HVC instructions.
>> - * The calling convention is similar to SMC calls to the secure world where
>> - * the function number is placed in r0 and this function returns true if the
>> - * function number specified in r0 is withing the PSCI range, and false
>> - * otherwise.
>> - */
>> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> +int kvm_psci_version(struct kvm_vcpu *vcpu) {
>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>> + return KVM_ARM_PSCI_0_2;
>> +
>> + return KVM_ARM_PSCI_0_1;
>> +}
>> +
>> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu) {
>> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> + unsigned long val;
>> +
>> + switch (psci_fn) {
>> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
>> + /*
>> + * Bits[31:16] = Major Version = 0
>> + * Bits[15:0] = Minor Version = 2
>> + */
>> + val = 2;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_OFF:
>> + kvm_psci_vcpu_off(vcpu);
>> + val = KVM_PSCI_RET_SUCCESS;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_ON:
>> + case KVM_PSCI_0_2_FN64_CPU_ON:
>> + val = kvm_psci_vcpu_on(vcpu);
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN_MIGRATE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
>> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
>> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
>> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN64_MIGRATE:
>> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
>> + val = KVM_PSCI_RET_NI;
>> + break;
>> + default:
>> + return false;
>> + }
>> +
>> + *vcpu_reg(vcpu, 0) = val;
>> + return true;
>> +}
>> +
>> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
>> {
>> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> unsigned long val;
>> @@ -112,7 +152,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> case KVM_PSCI_FN_MIGRATE:
>> val = KVM_PSCI_RET_NI;
>> break;
>> -
>> default:
>> return false;
>> }
>> @@ -120,3 +159,25 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> *vcpu_reg(vcpu, 0) = val;
>> return true;
>> }
>> +
>> +/**
>> + * kvm_psci_call - handle PSCI call if r0 value is in range
>> + * @vcpu: Pointer to the VCPU struct
>> + *
>> + * Handle PSCI calls from guests through traps from HVC instructions.
>> + * The calling convention is similar to SMC calls to the secure world
>> +where
>> + * the function number is placed in r0 and this function returns true
>> +if the
>> + * function number specified in r0 is withing the PSCI range, and false
>> + * otherwise.
>> + */
>> +bool kvm_psci_call(struct kvm_vcpu *vcpu) {
>> + switch (kvm_psci_version(vcpu)) {
>> + case KVM_ARM_PSCI_0_2:
>> + return kvm_psci_0_2_call(vcpu);
>> + case KVM_ARM_PSCI_0_1:
>> + return kvm_psci_0_1_call(vcpu);
>> + default:
>> + return false;
>> + };
>> +}
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 0a1d697..92242ce 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -39,7 +39,7 @@
>> #include <kvm/arm_vgic.h>
>> #include <kvm/arm_arch_timer.h>
>>
>> -#define KVM_VCPU_MAX_FEATURES 2
>> +#define KVM_VCPU_MAX_FEATURES 3
>>
>> struct kvm_vcpu;
>> int kvm_target_cpu(void);
>> diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
>> index e301a48..e25c658 100644
>> --- a/arch/arm64/include/asm/kvm_psci.h
>> +++ b/arch/arm64/include/asm/kvm_psci.h
>> @@ -18,6 +18,10 @@
>> #ifndef __ARM64_KVM_PSCI_H__
>> #define __ARM64_KVM_PSCI_H__
>>
>> +#define KVM_ARM_PSCI_0_1 1
>> +#define KVM_ARM_PSCI_0_2 2
>> +
>> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>
>> #endif /* __ARM64_KVM_PSCI_H__ */
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
>> index eaf54a3..cadc318 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -77,6 +77,7 @@ struct kvm_regs {
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
>> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -177,7 +178,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -186,10 +187,42 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> #define KVM_PSCI_RET_NI ((unsigned long)-1)
>> #define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> kvmarm mailing list
>> kvmarm at lists.cs.columbia.edu
>> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
^ permalink raw reply
* [PATCH v3 04/15] ARM: at91: prepare common clk transition for sam9261 SoC
From: Boris BREZILLON @ 2014-02-07 8:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207082537.GU9558@ns203013.ovh.net>
Hello Jean-Christophe,
On 07/02/2014 09:25, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
>> This patch encloses sam9261 old clk registration in
>> "#if defined(CONFIG_OLD_CLK_AT91) #endif" sections.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>> ---
>> arch/arm/mach-at91/at91sam9261.c | 8 ++++++--
>> 1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
>> index 6a2c869..2c0e940 100644
>> --- a/arch/arm/mach-at91/at91sam9261.c
>> +++ b/arch/arm/mach-at91/at91sam9261.c
>> @@ -25,10 +25,12 @@
>> #include "at91_rstc.h"
>> #include "soc.h"
>> #include "generic.h"
>> -#include "clock.h"
>> #include "sam9_smc.h"
>> #include "pm.h"
>>
>> +#if defined(CONFIG_OLD_CLK_AT91)
>> +#include "clock.h"
>> +
>> /* --------------------------------------------------------------------
>> * Clocks
>> * -------------------------------------------------------------------- */
>> @@ -262,7 +264,7 @@ static void __init at91sam9261_register_clocks(void)
>> clk_register(&hck0);
>> clk_register(&hck1);
>> }
>> -
> do this here
>
> #else
> #define at91sam9261_register_clocks NULL
>> +#endif
>> /* --------------------------------------------------------------------
>> * GPIO
>> * -------------------------------------------------------------------- */
>> @@ -362,6 +364,8 @@ AT91_SOC_START(at91sam9261)
>> .extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
>> | (1 << AT91SAM9261_ID_IRQ2),
>> .ioremap_registers = at91sam9261_ioremap_registers,
>> +#if defined(CONFIG_OLD_CLK_AT91)
>> .register_clocks = at91sam9261_register_clocks,
>> +#endif
> so no ifdef here
I guess he did this based on what I did for the sama5 SoC, but you're right:
your proposal is cleaner.
Best Regards,
Boris
>> .init = at91sam9261_initialize,
>> AT91_SOC_END
>> --
>> 1.8.5.2
>>
^ permalink raw reply
* [PATCH 21/21] ARM: Kirkwood: Remove DT support
From: Thomas Petazzoni @ 2014-02-07 8:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391730137-14814-22-git-send-email-andrew@lunn.ch>
Dear Andrew Lunn,
On Fri, 7 Feb 2014 00:42:17 +0100, Andrew Lunn wrote:
> Now that all the device tree support is in mach-mvebu, remove it from
> mach-kirkwood.
>
> Regenerate kirkwood_defconfig, removing all DT support, and a couple
> of other redundent options have been removed in the process.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> arch/arm/configs/kirkwood_defconfig | 6 -
So after this series we have a mvebu_defconfig that only builds the
ARMv7 platforms of mach-mvebu. I believe this may look strange to
people looking at the code, seeing that Kirkwood DT support is in
mach-mvebu, but that mvebu_defconfig doesn't work to build a Kirkwood
kernel.
I don't really have a solution, except maybe having mvebu_v7_defconfig
and mvebu_v5_defconfig to build only the Marvell v7 and Marvell v5
platforms.
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH v3 00/15] Device Tree support for the at91sam9261ek
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-1-git-send-email-jjhiblot@traphandler.com>
Hi,
please re-organise your patch serie
first SoC patch
- first CCF
- one patch for the SoC
second add the board 1 patch
no need 15 patches
Best Regards,
J.
On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
> This patch set aims at bringing a basic device tree support for the sam9261.
> It's mostly based on the sam9263 and sam9x5 stuff.
>
> Changes since V2:
> * removed the smc driver from the serie. It'll be posted in an independent
> serie later.
> * removed the DM9000 support (it'll come with the smc driver)
> * the sam9261 now supports the Common Clock Framework (CCF). Note: to enable
> the CCF you must remove from the kernel config the platforms that don't
> support it.
> * Added basic DT binding for the bus matrix
> * Added support for USB host
> * Added support for USB gadget
> * in dts(i), replaced interrupt-parent with interrupts-extended
> * changed the nand partition plan (same as for the sama5d3)
> * removed 'mem' parameter in command line
> * re-ordered dt-nodes in ascending address order.
> * split the lcd support patch in 2 parts (SOC and board)
>
>
> Change since V1:
> * changed the DT representation to use address translation and separate the
> timings' configuration from the device properties by adding a "simple-bus"
> inetrmediate node.
> * moved the smc driver from drivers/bus to drivers/memmory
> * smc driver now accepts timings in nanoseconds as well as raw register values
> * smc driver can clip the timings if they're out of bound and dump them to the
> console
> * DM9000 timings are now described in nanosecs (for the virtue of example)
>
> supported features:
> * dbgu
> * nand
> * lcd
> * leds
> * user buttons
> * usb host
> * usb gadget
>
> This serie relies on the 3 following patchs:
> usb: ohci-at91: fix irq and iomem resource retrieval
> usb: at91-udc: fix irq and iomem resource retrieval
> ARM: at91: prepare sam9 dt boards transition to common
>
> Jean-Jacques
>
>
>
> Jean-Jacques Hiblot (15):
> at91: dt: Add at91sam9261 dt SoC support
> at91: dt: defconfig: Added the sam9261 to the list of supported SOCs
> at91: dt: sam9261: Basic Device Tree support for the at91sam9261ek
> ARM: at91: prepare common clk transition for sam9261 SoC
> ARM: at91: move sam9261 SoC to common clk
> at91: dt: at91sam9261ek: Adds DT entries for the 4 user buttons
> at91: dt: sam9261: Added the descriptions of hck0 and hck1 clocks
> (CCF)
> at91: dt: sam9261: Added hclk declaration for the fb driver (non-CCF)
> at91: dt: sam9261: Added support for the LCD display
> at91: dt: at91sam9261ek: Added support for the LCD display
> at91: dt: Adds support for the bus matrix declaration in the device
> tree
> at91: dt: sam9261: adds description for the bus matrix
> at91: dt: sam9261: CCF: Added USB clocks
> at91: dt: at91sam9261ek: Enabled the USB host port (OHCI)
> at91: dt: at91sam9261ek: Enabled the USB device port
>
> arch/arm/boot/dts/Makefile | 2 +
> arch/arm/boot/dts/at91sam9261.dtsi | 724 ++++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/at91sam9261ek.dts | 191 ++++++++++
> arch/arm/configs/at91_dt_defconfig | 1 +
> arch/arm/mach-at91/Kconfig | 1 -
> arch/arm/mach-at91/at91sam9261.c | 24 +-
> arch/arm/mach-at91/setup.c | 23 ++
> 7 files changed, 963 insertions(+), 3 deletions(-)
> create mode 100644 arch/arm/boot/dts/at91sam9261.dtsi
> create mode 100644 arch/arm/boot/dts/at91sam9261ek.dts
>
> --
> 1.8.5.2
>
^ permalink raw reply
* [PATCH 19/21] ARM: MVEBU: Simplifiy headers and make local
From: Thomas Petazzoni @ 2014-02-07 8:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391730137-14814-20-git-send-email-andrew@lunn.ch>
Dear Andrew Lunn,
On Fri, 7 Feb 2014 00:42:15 +0100, Andrew Lunn wrote:
> kirkwood is very nearly fully DT. Remove most of the address
> definitions from the header files and make it a local header file.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> arch/arm/mach-mvebu/include/mach/bridge-regs.h | 85 ---------------
> arch/arm/mach-mvebu/include/mach/kirkwood.h | 142 -------------------------
> arch/arm/mach-mvebu/kirkwood-pm.c | 2 +-
> arch/arm/mach-mvebu/kirkwood.c | 2 +-
> arch/arm/mach-mvebu/kirkwood.h | 22 ++++
> 5 files changed, 24 insertions(+), 229 deletions(-)
> delete mode 100644 arch/arm/mach-mvebu/include/mach/bridge-regs.h
> delete mode 100644 arch/arm/mach-mvebu/include/mach/kirkwood.h
> create mode 100644 arch/arm/mach-mvebu/kirkwood.h
Is there any particular reason why this isn't part of PATCH 14/21. I
was very surprised when reading PATCH 14/21 to see a file named
"bridge-regs.h" containing Kirkwood-specific definitions added to
mach-mvebu, and so many address constants being defined, while we are
DT-based only in mach-mvebu.
> +#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
> +#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
> +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
> +
> +#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
> +
> +#define CPU_CONFIG_PHYS (BRIDGE_PHYS_BASE + 0x0100)
> +#define CPU_CONFIG_ERROR_PROP 0x00000004
> +
> +#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104)
> +#define MEMORY_PM_CTRL_PHYS (BRIDGE_PHYS_BASE + 0x0118)
Are there plans to also get rid of those constants at some point?
Thanks!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH v3 03/15] at91: dt: sam9261: Basic Device Tree support for the at91sam9261ek
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-4-git-send-email-jjhiblot@traphandler.com>
On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
> This patch implements a simple DTS to boot a at91sam9261ek with a dt-enabled
> kernel (at91_dt_defconfig).
> Only dbgu, nand and watchdog are described in the DT.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> arch/arm/boot/dts/Makefile | 2 +
> arch/arm/boot/dts/at91sam9261ek.dts | 112 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 114 insertions(+)
> create mode 100644 arch/arm/boot/dts/at91sam9261ek.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 772a30e..ece523d 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -11,6 +11,8 @@ dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb
> dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb
> dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb
> dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb
> +# sam9261
> +dtb-$(CONFIG_ARCH_AT91) += at91sam9261ek.dtb
> # sam9263
> dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb
> dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
> new file mode 100644
> index 0000000..8909217
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
> @@ -0,0 +1,112 @@
> +/*
> + * at91sam9261ek.dts - Device Tree file for Atmel at91sam9261 reference board
> + *
> + * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> + *
> + * Licensed under GPLv2 only.
> + */
> +/dts-v1/;
> +#include "at91sam9261.dtsi"
> +
> +/ {
> + model = "Atmel at91sam9261ek";
> + compatible = "atmel,at91sam9261ek", "atmel,at91sam9261", "atmel,at91sam9";
> +
> + chosen {
> + bootargs = "mem=64M console=ttyS0,115200";
drop the mem=64M
and use linux,stdout for the console
> + };
> +
> + memory {
> + reg = <0x20000000 0x4000000>;
> + };
> +
> + clocks {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + main_clock: clock at 0 {
> + compatible = "atmel,osc", "fixed-clock";
> + clock-frequency = <18432000>;
> + };
> + };
> +
> + ahb {
> +
> + nand0: nand at 40000000 {
> + nand-bus-width = <8>;
> + nand-ecc-mode = "soft";
> + nand-on-flash-bbt = <1>;
it's a boolean just
nand-on-flash-bbt;
> + status = "okay";
> +
> + at91bootstrap at 0 {
> + label = "at91bootstrap";
> + reg = <0x0 0x40000>;
> + };
> +
> + bootloader at 40000 {
> + label = "bootloader";
> + reg = <0x40000 0x80000>;
> + };
> +
> + bootloaderenv at c0000 {
> + label = "bootloader env";
> + reg = <0xc0000 0xc0000>;
> + };
> +
> + dtb at 180000 {
> + label = "device tree";
> + reg = <0x180000 0x80000>;
> + };
> +
> + kernel at 200000 {
> + label = "kernel";
> + reg = <0x200000 0x600000>;
> + };
> +
> + rootfs at 800000 {
> + label = "rootfs";
> + reg = <0x800000 0x0f800000>;
> + };
we really need to switch to UBI
> + };
> +
> + apb {
> + dbgu: serial at fffff200 {
> + status = "okay";
> + };
> +
> + pinctrl at fffff400 {
> + leds {
> + pinctrl_leds: leds-0 {
> + atmel,pins = <AT91_PIOA 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 14 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
> + };
> + };
> + };
no need this drop it
you need to only describe the GPIO if you have specific pinctrl property such
as pull up & co
> +
> + watchdog at fffffd40 {
> + status = "okay";
> + };
> + };
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> + ds8 {
> + label = "ds8";
> + gpios = <&pioA 13 GPIO_ACTIVE_LOW>;
> + linux,default-trigger = "none";
> + };
> + ds7 {
> + label = "ds7";
> + gpios = <&pioA 14 GPIO_ACTIVE_LOW>;
> + linux,default-trigger = "nand-disk";
> + };
> + ds1 {
> + label = "ds1";
> + gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
> + linux,default-trigger = "heartbeat";
> + };
> + };
> +};
> --
> 1.8.5.2
>
^ permalink raw reply
* [PATCH v4 02/10] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
From: Jungseok Lee @ 2014-02-07 8:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391686302-19451-3-git-send-email-anup.patel@linaro.org>
On Thursday, February 06, 2014 8:32 PM, Anup Patel wrote:
> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to VCPUs. This patch extends
> current in-kernel PSCI emulation to provide PSCI v0.2 interface to VCPUs.
>
> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for keeping the ABI backward-
> compatible.
>
> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU init using KVM_ARM_VCPU_INIT
> ioctl.
>
> Signed-off-by: Anup Patel <anup.patel@linaro.org>
> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
> ---
> arch/arm/include/asm/kvm_host.h | 2 +-
> arch/arm/include/asm/kvm_psci.h | 4 ++
> arch/arm/include/uapi/asm/kvm.h | 35 ++++++++++++++-
> arch/arm/kvm/arm.c | 1 +
> arch/arm/kvm/psci.c | 85 +++++++++++++++++++++++++++++++------
> arch/arm64/include/asm/kvm_host.h | 2 +-
> arch/arm64/include/asm/kvm_psci.h | 4 ++
> arch/arm64/include/uapi/asm/kvm.h | 35 ++++++++++++++-
> 8 files changed, 152 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 09af149..193ceaf
> 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -36,7 +36,7 @@
> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #define KVM_HAVE_ONE_REG
>
> -#define KVM_VCPU_MAX_FEATURES 1
> +#define KVM_VCPU_MAX_FEATURES 2
>
> #include <kvm/arm_vgic.h>
>
> diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h index 9a83d98..4c0e3e1
> 100644
> --- a/arch/arm/include/asm/kvm_psci.h
> +++ b/arch/arm/include/asm/kvm_psci.h
> @@ -18,6 +18,10 @@
> #ifndef __ARM_KVM_PSCI_H__
> #define __ARM_KVM_PSCI_H__
>
> +#define KVM_ARM_PSCI_0_1 1
> +#define KVM_ARM_PSCI_0_2 2
> +
> +int kvm_psci_version(struct kvm_vcpu *vcpu);
> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>
> #endif /* __ARM_KVM_PSCI_H__ */
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index ef0c878..9c922d9
> 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -83,6 +83,7 @@ struct kvm_regs {
> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -192,7 +193,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -201,9 +202,41 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
Hi
This patch describes PSCI v0.2 specification well. Instead,
I have a question on interface types, not implementation.
According to PSCI v0.2 document, it does not cover DVFS.
Could I get an idea why DVFS is not supported?
Best Regards
Jungseok Lee
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> #define KVM_PSCI_RET_NI ((unsigned long)-1)
> #define KVM_PSCI_RET_INVAL ((unsigned long)-2)
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif /* __ARM_KVM_H__ */
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 1d8248e..c8a71df 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -197,6 +197,7 @@ int kvm_dev_ioctl_check_extension(long ext)
> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
> case KVM_CAP_ONE_REG:
> case KVM_CAP_ARM_PSCI:
> + case KVM_CAP_ARM_PSCI_0_2:
> r = 1;
> break;
> case KVM_CAP_COALESCED_MMIO:
> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 448f60e..e4ec4af 100644
> --- a/arch/arm/kvm/psci.c
> +++ b/arch/arm/kvm/psci.c
> @@ -85,17 +85,57 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> return KVM_PSCI_RET_SUCCESS;
> }
>
> -/**
> - * kvm_psci_call - handle PSCI call if r0 value is in range
> - * @vcpu: Pointer to the VCPU struct
> - *
> - * Handle PSCI calls from guests through traps from HVC instructions.
> - * The calling convention is similar to SMC calls to the secure world where
> - * the function number is placed in r0 and this function returns true if the
> - * function number specified in r0 is withing the PSCI range, and false
> - * otherwise.
> - */
> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
> +int kvm_psci_version(struct kvm_vcpu *vcpu) {
> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
> + return KVM_ARM_PSCI_0_2;
> +
> + return KVM_ARM_PSCI_0_1;
> +}
> +
> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu) {
> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> + unsigned long val;
> +
> + switch (psci_fn) {
> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
> + /*
> + * Bits[31:16] = Major Version = 0
> + * Bits[15:0] = Minor Version = 2
> + */
> + val = 2;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_OFF:
> + kvm_psci_vcpu_off(vcpu);
> + val = KVM_PSCI_RET_SUCCESS;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_ON:
> + case KVM_PSCI_0_2_FN64_CPU_ON:
> + val = kvm_psci_vcpu_on(vcpu);
> + break;
> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN_MIGRATE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN64_MIGRATE:
> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
> + val = KVM_PSCI_RET_NI;
> + break;
> + default:
> + return false;
> + }
> +
> + *vcpu_reg(vcpu, 0) = val;
> + return true;
> +}
> +
> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
> {
> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> unsigned long val;
> @@ -112,7 +152,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> case KVM_PSCI_FN_MIGRATE:
> val = KVM_PSCI_RET_NI;
> break;
> -
> default:
> return false;
> }
> @@ -120,3 +159,25 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> *vcpu_reg(vcpu, 0) = val;
> return true;
> }
> +
> +/**
> + * kvm_psci_call - handle PSCI call if r0 value is in range
> + * @vcpu: Pointer to the VCPU struct
> + *
> + * Handle PSCI calls from guests through traps from HVC instructions.
> + * The calling convention is similar to SMC calls to the secure world
> +where
> + * the function number is placed in r0 and this function returns true
> +if the
> + * function number specified in r0 is withing the PSCI range, and false
> + * otherwise.
> + */
> +bool kvm_psci_call(struct kvm_vcpu *vcpu) {
> + switch (kvm_psci_version(vcpu)) {
> + case KVM_ARM_PSCI_0_2:
> + return kvm_psci_0_2_call(vcpu);
> + case KVM_ARM_PSCI_0_1:
> + return kvm_psci_0_1_call(vcpu);
> + default:
> + return false;
> + };
> +}
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 0a1d697..92242ce 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -39,7 +39,7 @@
> #include <kvm/arm_vgic.h>
> #include <kvm/arm_arch_timer.h>
>
> -#define KVM_VCPU_MAX_FEATURES 2
> +#define KVM_VCPU_MAX_FEATURES 3
>
> struct kvm_vcpu;
> int kvm_target_cpu(void);
> diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
> index e301a48..e25c658 100644
> --- a/arch/arm64/include/asm/kvm_psci.h
> +++ b/arch/arm64/include/asm/kvm_psci.h
> @@ -18,6 +18,10 @@
> #ifndef __ARM64_KVM_PSCI_H__
> #define __ARM64_KVM_PSCI_H__
>
> +#define KVM_ARM_PSCI_0_1 1
> +#define KVM_ARM_PSCI_0_2 2
> +
> +int kvm_psci_version(struct kvm_vcpu *vcpu);
> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>
> #endif /* __ARM64_KVM_PSCI_H__ */
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index eaf54a3..cadc318 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -77,6 +77,7 @@ struct kvm_regs {
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -177,7 +178,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -186,10 +187,42 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> #define KVM_PSCI_RET_NI ((unsigned long)-1)
> #define KVM_PSCI_RET_INVAL ((unsigned long)-2)
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif
>
> --
> 1.7.9.5
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
^ permalink raw reply
* [PATCH v3 06/15] at91: dt: at91sam9261ek: Adds DT entries for the 4 user buttons
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-7-git-send-email-jjhiblot@traphandler.com>
On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> arch/arm/boot/dts/at91sam9261ek.dts | 39 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
do only one patch for the 9261ek support no nned to clean
>
> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
> index 8909217..5555e9f5 100644
> --- a/arch/arm/boot/dts/at91sam9261ek.dts
> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
> @@ -83,6 +83,15 @@
> AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
> };
> };
> +
> + keys {
> + pinctrl_keys: keys-0 {
> + atmel,pins = <AT91_PIOA 27 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 26 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 25 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
> + };
> + };
no need this you can drop it
you just describe a gpio which we do not describe in pinctrl
> };
>
> watchdog at fffffd40 {
> @@ -109,4 +118,34 @@
> linux,default-trigger = "heartbeat";
> };
> };
> +
> + gpio_keys {
> + compatible = "gpio-keys";
> + pinctrl-0 = <&pinctrl_keys>;
> +
> + button_0 {
> + label = "button_0";
> + gpios = <&pioA 27 GPIO_ACTIVE_LOW>;
> + linux,code = <256>;
> + gpio-key,wakeup;
> + };
> + button_1 {
> + label = "button_1";
> + gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
> + linux,code = <257>;
> + gpio-key,wakeup;
> + };
> + button_2 {
> + label = "button_2";
> + gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
> + linux,code = <258>;
> + gpio-key,wakeup;
> + };
> + button_3 {
> + label = "button_3";
> + gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
> + linux,code = <259>;
> + gpio-key,wakeup;
> + };
> + };
> };
> --
> 1.8.5.2
>
^ permalink raw reply
* renesas-backport.git: Linux-3.10.28 Marzen (R8A7779) missing Audio Support
From: srikanth krishnakar @ 2014-02-07 8:27 UTC (permalink / raw)
To: linux-arm-kernel
I am trying to boot the Renesas R-Car H1 (Marzen) board with 3.10 LTSi
kernel which is present at :
https://git.kernel.org/cgit/linux/kernel/git/horms/renesas-backport.git/
Branch: backport/v3.10.28-ltsi-rc1/snapshot
There are no sound cards detected on booting this kernel, although
graphics is found to be working. Are there any updates which adds the
RCAR_SOUND support to Marzen on v3.10 LTSi kernel ?
--------------------------
root <at> marzenh1:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
29: 5840 17228 5026 14491 GIC twd
59: 0 0 0 0 GIC renesas_intc_irqpin
60: 8094 0 0 0 GIC renesas_intc_irqpin
61: 0 0 0 0 GIC renesas_intc_irqpin
62: 0 0 0 0 GIC renesas_intc_irqpin
63: 0 0 0 0 GIC
rcar-du-r8a7779, rcar-du-r8a7779
64: 13 0 0 0 GIC sh_tmu.0
76: 60 0 0 0 GIC
ehci_hcd:usb1, ohci_hcd:usb3
77: 1 0 0 0 GIC
ehci_hcd:usb2, ohci_hcd:usb4
96: 0 0 0 0 GIC r8a7779-vin.1
98: 0 0 0 0 GIC r8a7779-vin.3
111: 82 0 0 0 GIC i2c-rcar.0
112: 0 0 0 0 GIC i2c-rcar.2
113: 0 0 0 0 GIC i2c-rcar.3
114: 0 0 0 0 GIC i2c-rcar.1
122: 982 0 0 0 GIC sh-sci.2:mux
132: 0 0 0 0 GIC sata_rcar
136: 52 0 0 0 GIC sh_mobile_sdhi.0
173: 0 0 0 0 GIC gpio_rcar.0
174: 0 0 0 0 GIC gpio_rcar.1
175: 0 0 0 0 GIC gpio_rcar.2
176: 0 0 0 0 GIC gpio_rcar.3
177: 0 0 0 0 GIC gpio_rcar.4
178: 0 0 0 0 GIC gpio_rcar.5
179: 0 0 0 0 GIC gpio_rcar.6
2001: 8094 0 0 0 renesas_intc_irqpin eth0
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 476 1715 1732 1236 Rescheduling interrupts
IPI3: 50 62 112 112 Function call interrupts
IPI4: 0 0 0 0 Single function
call interrupts
IPI5: 0 0 0 0 CPU stop interrupts
Err: 0
...
....
.....
root <at> marzenh1:~# aplay -l
aplay: device_list:268: no soundcards found...
---------------------------
When will be the Audio support available for R-Car Marzen (R8A7779) on
v3.10 LTSi kernel ?
Your inputs are highly appreciated.
**********************
^ permalink raw reply
* [PATCH v3 04/15] ARM: at91: prepare common clk transition for sam9261 SoC
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-5-git-send-email-jjhiblot@traphandler.com>
On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
> This patch encloses sam9261 old clk registration in
> "#if defined(CONFIG_OLD_CLK_AT91) #endif" sections.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> arch/arm/mach-at91/at91sam9261.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
> index 6a2c869..2c0e940 100644
> --- a/arch/arm/mach-at91/at91sam9261.c
> +++ b/arch/arm/mach-at91/at91sam9261.c
> @@ -25,10 +25,12 @@
> #include "at91_rstc.h"
> #include "soc.h"
> #include "generic.h"
> -#include "clock.h"
> #include "sam9_smc.h"
> #include "pm.h"
>
> +#if defined(CONFIG_OLD_CLK_AT91)
> +#include "clock.h"
> +
> /* --------------------------------------------------------------------
> * Clocks
> * -------------------------------------------------------------------- */
> @@ -262,7 +264,7 @@ static void __init at91sam9261_register_clocks(void)
> clk_register(&hck0);
> clk_register(&hck1);
> }
> -
do this here
#else
#define at91sam9261_register_clocks NULL
> +#endif
> /* --------------------------------------------------------------------
> * GPIO
> * -------------------------------------------------------------------- */
> @@ -362,6 +364,8 @@ AT91_SOC_START(at91sam9261)
> .extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
> | (1 << AT91SAM9261_ID_IRQ2),
> .ioremap_registers = at91sam9261_ioremap_registers,
> +#if defined(CONFIG_OLD_CLK_AT91)
> .register_clocks = at91sam9261_register_clocks,
> +#endif
so no ifdef here
> .init = at91sam9261_initialize,
> AT91_SOC_END
> --
> 1.8.5.2
>
^ permalink raw reply
* [PATCH 03/21] ARM: Kirkwood: Convert mv88f6281gtw_ge switch setup to DT
From: Thomas Petazzoni @ 2014-02-07 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391730137-14814-4-git-send-email-andrew@lunn.ch>
Dear Andrew Lunn,
On Fri, 7 Feb 2014 00:41:59 +0100, Andrew Lunn wrote:
> The mv88f6281gtw_ge has a ethernet switch connected to the ethernet
> port of the SoC. Convert the platform device instantiationn to a DT
> instantiation.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> arch/arm/mach-kirkwood/Kconfig | 7 ----
> arch/arm/mach-kirkwood/Makefile | 1 -
> arch/arm/mach-kirkwood/Module.symvers | 0
> arch/arm/mach-kirkwood/board-dt.c | 3 --
> arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c | 50 --------------------------
> arch/arm/mach-kirkwood/common.h | 7 ----
> 6 files changed, 68 deletions(-)
> create mode 100644 arch/arm/mach-kirkwood/Module.symvers
This is probably a mistake.
> delete mode 100644 arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c
Hum, I maybe missed something, but where are the corresponding DT
informations added to replace the C description of the Ethernet switch?
Thanks!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH v3 01/15] at91: dt: Add at91sam9261 dt SoC support
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390492639-7299-2-git-send-email-jjhiblot@traphandler.com>
On 16:57 Thu 23 Jan , Jean-Jacques Hiblot wrote:
> This patch adds the basics to support the Device Tree on a sam9261-based platform
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> arch/arm/boot/dts/at91sam9261.dtsi | 627 +++++++++++++++++++++++++++++++++++++
> arch/arm/mach-at91/at91sam9261.c | 15 +
> 2 files changed, 642 insertions(+)
> create mode 100644 arch/arm/boot/dts/at91sam9261.dtsi
>
> diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
> new file mode 100644
> index 0000000..2730611
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91sam9261.dtsi
> @@ -0,0 +1,627 @@
> +/*
> + * at91sam9261.dtsi - Device Tree Include file for AT91SAM9261 SoC
> + *
> + * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> + *
> + * Licensed under GPLv2 only.
> + */
> +
> +#include "skeleton.dtsi"
> +#include <dt-bindings/pinctrl/at91.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clk/at91.h>
> +
> +/ {
> + model = "Atmel AT91SAM9261 family SoC";
> + compatible = "atmel,at91sam9261";
> + interrupt-parent = <&aic>;
> +
> + aliases {
> + serial0 = &dbgu;
> + serial1 = &usart0;
> + serial2 = &usart1;
> + serial3 = &usart2;
> + gpio0 = &pioA;
> + gpio1 = &pioB;
> + gpio2 = &pioC;
> + tcb0 = &tcb0;
> + i2c0 = &i2c0;
> + ssc0 = &ssc0;
> + ssc1 = &ssc1;
> + };
> + cpus {
> + #address-cells = <0>;
> + #size-cells = <0>;
> +
> + cpu {
> + compatible = "arm,arm926ej-s";
> + device_type = "cpu";
> + };
> + };
> +
> + memory {
> + reg = <0x20000000 0x08000000>;
> + };
> +
> + ahb {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + usb0: ohci at 00500000 {
> + compatible = "atmel,at91rm9200-ohci", "usb-ohci";
> + reg = <0x00500000 0x100000>;
> + interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
as requested before use the new interrupt property
interrupts-extended (mandatory)
there is missing
pinctrl-names = "default";
on mmc & co
> + status = "disabled";
> + };
> +
> + nand0: nand at 40000000 {
> + compatible = "atmel,at91rm9200-nand";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x40000000 0x10000000>;
> + atmel,nand-addr-offset = <22>;
> + atmel,nand-cmd-offset = <21>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_nand>;
> +
> + gpios = <&pioC 15 GPIO_ACTIVE_HIGH
> + &pioC 14 GPIO_ACTIVE_HIGH
> + 0
> + >;
> + status = "disabled";
> + };
> +
> + apb {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + tcb0: timer at fffa0000 {
> + compatible = "atmel,at91rm9200-tcb";
> + reg = <0xfffa0000 0x100>;
> + interrupts = < 17 IRQ_TYPE_LEVEL_HIGH 0
> + 18 IRQ_TYPE_LEVEL_HIGH 0
> + 19 IRQ_TYPE_LEVEL_HIGH 0
> + >;
> + clocks = <&tcb0_clk>;
> + clock-names = "t0_clk";
> + status = "disabled";
we use the tcb as shedule clock this should be on by default
> + };
> +
> + usb1: gadget at fffa4000 {
> + compatible = "atmel,at91rm9200-udc";
> + reg = <0xfffa4000 0x4000>;
> + interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
> + status = "disabled";
> + };
> +
> + mmc0: mmc at fffa8000 {
> + compatible = "atmel,hsmci";
> + reg = <0xfffa8000 0x600>;
> + interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clocks = <&mci0_clk>;
> + clock-names = "mci_clk";
> + status = "disabled";
> + };
> +
> + i2c0: i2c at fffac000 {
> + compatible = "atmel,at91sam9261-i2c";
> + pinctrl-0 = <&pinctrl_i2c_twi>;
> + reg = <0xfffac000 0x100>;
> + interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clocks = <&twi0_clk>;
> + status = "disabled";
> + };
> +
> + usart0: serial at fffb0000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfffb0000 0x200>;
> + interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart0>;
> + clocks = <&usart0_clk>;
> + clock-names = "usart";
> + status = "disabled";
> + };
> +
> + usart1: serial at fffb4000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfffb4000 0x200>;
> + interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart1>;
> + clocks = <&usart1_clk>;
> + clock-names = "usart";
> + status = "disabled";
> + };
> +
> + usart2: serial at fffb8000{
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfffb8000 0x200>;
> + interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart2>;
> + clocks = <&usart2_clk>;
> + clock-names = "usart";
> + status = "disabled";
> + };
> +
> + ssc0: ssc at fffbc000 {
> + compatible = "atmel,at91rm9200-ssc";
> + reg = <0xfffbc000 0x4000>;
> + interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
> + status = "disabled";
> + };
> +
> + ssc1: ssc at fffc0000 {
> + compatible = "atmel,at91rm9200-ssc";
> + reg = <0xfffc0000 0x4000>;
> + interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
> + status = "disabled";
> + };
> +
> + spi0: spi at fffc8000 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "atmel,at91rm9200-spi";
> + reg = <0xfffc8000 0x200>;
> + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_spi0>;
> + clocks = <&spi0_clk>;
> + clock-names = "spi_clk";
> + status = "disabled";
> + };
> +
> + spi1: spi at fffcc000 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "atmel,at91rm9200-spi";
> + reg = <0xfffcc000 0x200>;
> + interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_spi1>;
> + clocks = <&spi1_clk>;
> + clock-names = "spi_clk";
> + status = "disabled";
> + };
as said for sama5d3 we need to have macro for the hw CS as GPIO to make it
more clear to use and read
> +
> + ramc: ramc at ffffea00 {
> + compatible = "atmel,at91sam9260-sdramc";
> + reg = <0xffffea00 0x200>;
> + };
> +
> + aic: interrupt-controller at fffff000 {
> + #interrupt-cells = <3>;
> + compatible = "atmel,at91rm9200-aic";
> + interrupt-controller;
> + reg = <0xfffff000 0x200>;
> + atmel,external-irqs = <29 30 31>;
> + };
one missing empty line
> + dbgu: serial at fffff200 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfffff200 0x200>;
> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_dbgu>;
> + clocks = <&mck>;
> + clock-names = "usart";
> + status = "disabled";
> + };
> +
> + pinctrl at fffff400 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
> + ranges = <0xfffff400 0xfffff400 0xa00>;
> +
> + atmel,mux-mask = <
> + /* A B */
> + 0xffffffff 0xfffffff7 /* pioA */
> + 0xffffffff 0xfffffff4 /* pioB */
> + 0xffffffff 0xffffff07 /* pioC */
> + >;
> +
> + /* shared pinctrl settings */
> + dbgu {
> + pinctrl_dbgu: dbgu-0 {
> + atmel,pins =
> + <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
> + };
> + };
> +
> + usart0 {
> + pinctrl_usart0: usart0-0 {
> + atmel,pins =
> + <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
> + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart0_rts: usart0_rts-0 {
> + atmel,pins =
> + <AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart0_cts: usart0_cts-0 {
> + atmel,pins =
> + <AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + usart1 {
> + pinctrl_usart1: usart1-0 {
> + atmel,pins =
> + <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
> + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart1_rts: usart1_rts-0 {
> + atmel,pins =
> + <AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart1_cts: usart1_cts-0 {
> + atmel,pins =
> + <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + usart2 {
> + pinctrl_usart2: usart2-0 {
> + atmel,pins =
> + <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
> + AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart2_rts: usart2_rts-0 {
> + atmel,pins =
> + <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_usart2_cts: usart2_cts-0 {
> + atmel,pins =
> + <AT91_PIOA 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + nand {
> + pinctrl_nand: nand-0 {
> + atmel,pins =
> + <AT91_PIOC 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP
> + AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
> + };
> + };
> +
> + mmc0 {
> + pinctrl_mmc0_clk: mmc0_clk-0 {
> + atmel,pins =
> + <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
> + atmel,pins =
> + <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
> + AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
> + };
> +
> + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
> + atmel,pins =
> + <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
> + AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
> + AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
> + };
> + };
> +
> + ssc0 {
> + pinctrl_ssc0_tx: ssc0_tx-0 {
> + atmel,pins =
> + <AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_ssc0_rx: ssc0_rx-0 {
> + atmel,pins =
> + <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + ssc1 {
> + pinctrl_ssc1_tx: ssc1_tx-0 {
> + atmel,pins =
> + <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE
> + AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE
> + AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_ssc1_rx: ssc1_rx-0 {
> + atmel,pins =
> + <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE
> + AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE
> + AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + spi0 {
> + pinctrl_spi0: spi0-0 {
> + atmel,pins =
> + <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + spi1 {
> + pinctrl_spi1: spi1-0 {
> + atmel,pins =
> + <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + tcb0 {
> + pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
> + atmel,pins = <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
> + atmel,pins = <AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
> + atmel,pins = <AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
> + atmel,pins = <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
> + atmel,pins = <AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
> + atmel,pins = <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
> + atmel,pins = <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
> + atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> +
> + pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
> + atmel,pins = <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + i2c0 {
> + pinctrl_i2c_bitbang: i2c-0-bitbang {
> + atmel,pins =
> + <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
> + AT91_PIOA 8 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
> + };
> + pinctrl_i2c_twi: i2c-0-twi {
> + atmel,pins =
> + <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE
> + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
> + };
> + };
> +
> + pioA: gpio at fffff400 {
> + compatible = "atmel,at91rm9200-gpio";
> + reg = <0xfffff400 0x200>;
> + interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + clocks = <&pioA_clk>;
> + };
> +
> + pioB: gpio at fffff600 {
> + compatible = "atmel,at91rm9200-gpio";
> + reg = <0xfffff600 0x200>;
> + interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + clocks = <&pioB_clk>;
> + };
> +
> + pioC: gpio at fffff800 {
> + compatible = "atmel,at91rm9200-gpio";
> + reg = <0xfffff800 0x200>;
> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + clocks = <&pioC_clk>;
> + };
> + };
> +
> + pmc: pmc at fffffc00 {
> + compatible = "atmel,at91rm9200-pmc";
> + reg = <0xfffffc00 0x100>;
> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
> + interrupt-controller;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + #interrupt-cells = <1>;
> +
> + clk32k: slck {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <32768>;
> + };
> +
> + main: mainck {
> + compatible = "atmel,at91rm9200-clk-main";
> + #clock-cells = <0>;
> + interrupts-extended = <&pmc AT91_PMC_MOSCS>;
> + clocks = <&clk32k>;
> + };
> +
> + plla: pllack {
> + compatible = "atmel,at91rm9200-clk-pll";
> + #clock-cells = <0>;
> + interrupts-extended = <&pmc AT91_PMC_LOCKA>;
> + clocks = <&main>;
> + reg = <0>;
> + atmel,clk-input-range = <1000000 32000000>;
> + #atmel,pll-clk-output-range-cells = <4>;
> + atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
> + };
> +
> + pllb: pllbck {
> + compatible = "atmel,at91rm9200-clk-pll";
> + #clock-cells = <0>;
> + interrupts-extended = <&pmc AT91_PMC_LOCKB>;
> + clocks = <&main>;
> + reg = <1>;
> + atmel,clk-input-range = <1000000 32000000>;
> + #atmel,pll-clk-output-range-cells = <4>;
> + atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
> + };
> +
> + mck: masterck {
> + compatible = "atmel,at91rm9200-clk-master";
> + #clock-cells = <0>;
> + interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
> + clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
> + atmel,clk-output-range = <0 94000000>;
> + atmel,clk-divisors = <1 2 4 3>;
> + };
> + periphck {
> + compatible = "atmel,at91rm9200-clk-peripheral";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clocks = <&mck>;
> +
> + pioA_clk: pioA_clk {
> + #clock-cells = <0>;
> + reg = <2>;
> + };
> +
> + pioB_clk: pioB_clk {
> + #clock-cells = <0>;
> + reg = <3>;
> + };
> +
> + pioC_clk: pioC_clk {
> + #clock-cells = <0>;
> + reg = <4>;
> + };
> +
> + usart0_clk: usart0_clk {
> + #clock-cells = <0>;
> + reg = <6>;
> + };
> +
> + usart1_clk: usart1_clk {
> + #clock-cells = <0>;
> + reg = <7>;
> + };
> +
> + usart2_clk: usart2_clk {
> + #clock-cells = <0>;
> + reg = <8>;
> + };
> +
> + mci0_clk: mci0_clk {
> + #clock-cells = <0>;
> + reg = <9>;
> + };
> +
> + twi0_clk: twi0_clk {
> + reg = <11>;
> + #clock-cells = <0>;
> + };
> +
> + spi0_clk: spi0_clk {
> + #clock-cells = <0>;
> + reg = <12>;
> + };
> +
> + spi1_clk: spi1_clk {
> + #clock-cells = <0>;
> + reg = <13>;
> + };
> +
> + tcb0_clk: tcb0_clk {
> + #clock-cells = <0>;
> + reg = <17>;
> + };
> +
> + lcd_clk: lcd_clk {
> + #clock-cells = <0>;
> + reg = <21>;
> + };
> + };
> + };
> +
> + rstc at fffffd00 {
> + compatible = "atmel,at91sam9260-rstc";
> + reg = <0xfffffd00 0x10>;
> + };
> +
> + shdwc at fffffd10 {
> + compatible = "atmel,at91sam9260-shdwc";
> + reg = <0xfffffd10 0x10>;
> + };
> +
> + pit: timer at fffffd30 {
> + compatible = "atmel,at91sam9260-pit";
> + reg = <0xfffffd30 0xf>;
> + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
> + clocks = <&mck>;
> + };
> +
> + watchdog at fffffd40 {
> + compatible = "atmel,at91sam9260-wdt";
> + reg = <0xfffffd40 0x10>;
> + status = "disabled";
> + };
> + };
> + };
> +
> + i2c at 0 {
> + compatible = "i2c-gpio";
> + pinctrl-0 = <&pinctrl_i2c_bitbang>;
> + gpios = <&pioA 7 GPIO_ACTIVE_HIGH /* sda */
> + &pioA 8 GPIO_ACTIVE_HIGH /* scl */
> + >;
> + i2c-gpio,sda-open-drain;
> + i2c-gpio,scl-open-drain;
> + i2c-gpio,delay-us = <2>; /* ~100 kHz */
> + #address-cells = <1>;
> + #size-cells = <0>;
> + status = "disabled";
> + };
> +};
> diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
> index 6276b4c..6a2c869 100644
> --- a/arch/arm/mach-at91/at91sam9261.c
> +++ b/arch/arm/mach-at91/at91sam9261.c
> @@ -189,6 +189,21 @@ static struct clk_lookup periph_clocks_lookups[] = {
> CLKDEV_CON_ID("pioA", &pioA_clk),
> CLKDEV_CON_ID("pioB", &pioB_clk),
> CLKDEV_CON_ID("pioC", &pioC_clk),
> + /* more usart lookup table for DT entries */
> + CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
> + CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
> + CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk),
> + CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk),
> + /* more tc lookup table for DT entries */
> + CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
> + CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &hck0),
> + CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk),
> + CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk),
> + CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
> + CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk),
> + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
> + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
> + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
do we really need this with ccf?
> };
>
> static struct clk_lookup usart_clocks_lookups[] = {
> --
> 1.8.5.2
>
^ permalink raw reply
* [PATCH 1/4] ARM: STi: add stid127 soc support
From: srinivas kandagatla @ 2014-02-07 8:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402061746.30248.arnd@arndb.de>
On 06/02/14 16:46, Arnd Bergmann wrote:
> On Wednesday 05 February 2014, srinivas kandagatla wrote:
>> Currently l2cc bindings has few optional properties like.
>>
>> - arm,data-latency
>> - arm,tag-latency
>> - arm,dirty-latency
>> - arm,filter-ranges
>> - interrupts :
>> - cache-id-part:
>> - wt-override:
>>
>> These does not include properties to set "way-size", "associativity",
>> "enabling prefetching", "Prefetch drop enable", "prefetch offset",
>> "Double linefill" and few more in prefect control register and
>> aux-control register.
>>
>> This is not just a issue with STi SOCs, having a quick look, I can see
>> that few more SOCs have similar requirements to set these properties.
>>
>> We could do two things to get l2 setup automatically on STi SOCS.
>>
>> 1> Either define these properties case-by-case basic, which might be
>> useful for other SOCs too.
>>
>> 2> Or Add new compatible string for STi SoCs so that they can
>> automatically setup these values in cache-l2x0.c
>>
>> Am Ok with either approaches.
>>
>
> I suggested 1 in the past, but the objection that I saw (can't
> find the email at the moment) was that the additional settings
> are "configuration" rather than "hardware properties". What I'd
> really need to know from you is which of properties you listed
> as missing above are actually needed for your platform, and whether
> they can be classified as hardware specific or just configuration.
On STi Platforms we need below properties to got for option 1.
arm,way-size;
arm,instruction-prefetch-enable;
arm,data-prefetch-enable;
we also want a property or a way to set
"Shareable attribute Override Enable" bit in the Auxiliary Control
Register, bit[22].
Thanks,
srini
>
> Arnd
>
>
^ permalink raw reply
* [PATCH v2 1/2] at91: gpio: use gpiolib API to mark a GPIO used as an IRQ
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52EB657A.4040601@atmel.com>
On 09:57 Fri 31 Jan , Nicolas Ferre wrote:
> On 31/01/2014 08:55, Linus Walleij :
> > On Thu, Jan 23, 2014 at 11:37 AM, Jean-Jacques Hiblot
> > <jjhiblot@traphandler.com> wrote:
> >
> >> When an IRQ is started on a GPIO line, mark this GPIO as IRQ in
> >> the gpiolib so we can keep track of the usage centrally.
> >>
> >> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> >
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> >
> > Nicolas, are you queueing this patch?
>
> Yes, I will.
>
> > I guess this custom GPIO implementation is going away with
> > the transition to pinctrl else I'd requested that it be moved to
> > drivers/gpio...
>
> Absolutely. But I suspect it will still be around for some time...
moved no
I'm not even sure we need to update it at all to simply for the switch to DT
nearly all the support for old SoC is here so I see no reason to do not switch
I even a big patch serie to switch old board to DT
So for me no do not touch the old stuff
Best Regards,
J.
>
> Thanks for your review. Bye,
> --
> Nicolas Ferre
^ permalink raw reply
* [PATCH v2] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-02-07 8:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589347-26019-1-git-send-email-nicolas.ferre@atmel.com>
On 09:35 Wed 05 Feb , Nicolas Ferre wrote:
> Add DT file for new SAMA5D3 Xpained board.
> This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
> 2 files changed, 234 insertions(+)
> create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index b9d6a8b485e0..6d1e43d46187 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
> dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
> dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
> # sama5d3
> +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb
> dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb
> dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb
> dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb
> diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
> new file mode 100644
> index 000000000000..fb1349ca60a4
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
> @@ -0,0 +1,233 @@
> +/*
> + * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
> + *
> + * Copyright (C) 2014 Atmel,
> + * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +/dts-v1/;
> +#include "sama5d36.dtsi"
> +
> +/ {
> + model = "SAMA5D3 Xplained";
> + compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
> +
> + chosen {
> + bootargs = "console=ttyS0,115200";
can you describe it via linux,stdout
> + };
> +
> + memory {
> + reg = <0x20000000 0x10000000>;
> + };
> +
> + ahb {
> + apb {
> + mmc0: mmc at f0000000 {
> + pinc?trl-names = "default";
?? this is SoC should never been seen here
> + pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
> + status = "okay";
> + slot at 0 {
> + reg = <0>;
> + bus-width = <8>;
> + cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
> + };
> + };
> +
> + spi0: spi at f0004000 {
> + cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
if you use only one CS no need to specified all
we need to add macro per SoC for the hw CS used as GPIO so it's more clear
> + status = "okay";
> + };
> +
> + can0: can at f000c000 {
> + status = "okay";
> + };
> +
> + i2c0: i2c at f0014000 {
> + status = "okay";
> + };
> +
> + i2c1: i2c at f0018000 {
> + status = "okay";
> + };
> +
> + macb0: ethernet at f0028000 {
> + phy-mode = "rgmii";
> + status = "okay";
> + };
> +
> + usart0: serial at f001c000 {
> + status = "okay";
> + };
> +
> + usart1: serial at f0020000 {
> + pinctrl-names = "default";
same as mmc
> + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
> + status = "okay";
> + };
> +
> + uart0: serial at f0024000 {
> + status = "okay";
> + };
> +
> + mmc1: mmc at f8000000 {
> + pinctrl-names = "default";
ditto
> + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
> + status = "okay";
> + slot at 0 {
> + reg = <0>;
> + bus-width = <4>;
> + cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
> + };
> + };
> +
> + spi1: spi at f8008000 {
> + cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
> + status = "okay";
> + };
> +
> + adc0: adc at f8018000 {
> + pinctrl-names = "default";
ditto
> + pinctrl-0 = <
> + &pinctrl_adc0_adtrg
> + &pinctrl_adc0_ad0
> + &pinctrl_adc0_ad1
> + &pinctrl_adc0_ad2
> + &pinctrl_adc0_ad3
> + &pinctrl_adc0_ad4
> + &pinctrl_adc0_ad5
> + &pinctrl_adc0_ad6
> + &pinctrl_adc0_ad7
> + &pinctrl_adc0_ad8
> + &pinctrl_adc0_ad9
> + >;
> + status = "okay";
> + };
> +
> + i2c2: i2c at f801c000 {
> + dmas = <0>, <0>; /* Do not use DMA for i2c2 */
why?
> + status = "okay";
> + };
> +
> + macb1: ethernet at f802c000 {
> + phy-mode = "rmii";
> + status = "okay";
> + };
> +
> + dbgu: serial at ffffee00 {
> + status = "okay";
> + };
> +
> + pinctrl at fffff200 {
> + board {
> + pinctrl_mmc0_cd: mmc0_cd {
> + atmel,pins =
> + <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
> + };
> +
> + pinctrl_mmc1_cd: mmc1_cd {
> + atmel,pins =
> + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
> + };
> +
> + pinctrl_usba_vbus: usba_vbus {
> + atmel,pins =
> + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */
in this case we should have ifdef so we could choose what we want via make
file
> + };
> + };
> + };
> +
> + pmc: pmc at fffffc00 {
> + main: mainck {
> + clock-frequency = <12000000>;
> + };
> + };
> + };
> +
> + nand0: nand at 60000000 {
> + nand-bus-width = <8>;
> + nand-ecc-mode = "hw";
> + atmel,has-pmecc;
> + atmel,pmecc-cap = <4>;
> + atmel,pmecc-sector-size = <512>;
> + nand-on-flash-bbt;
> + status = "okay";
> +
> + at91bootstrap at 0 {
> + label = "at91bootstrap";
> + reg = <0x0 0x40000>;
> + };
> +
> + bootloader at 40000 {
> + label = "bootloader";
> + reg = <0x40000 0x80000>;
> + };
> +
> + bootloaderenv at c0000 {
> + label = "bootloader env";
> + reg = <0xc0000 0xc0000>;
> + };
> +
> + dtb at 180000 {
> + label = "device tree";
> + reg = <0x180000 0x80000>;
> + };
> +
> + kernel at 200000 {
> + label = "kernel";
> + reg = <0x200000 0x600000>;
> + };
> +
> + rootfs at 800000 {
> + label = "rootfs";
> + reg = <0x800000 0x0f800000>;
> + };
more I read this partition more it's seems wrong those days
we really need to switch to UBI
> + };
> +
> + usb0: gadget at 00500000 {
> + atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usba_vbus>;
> + status = "okay";
> + };
> +
> + usb1: ohci at 00600000 {
> + num-ports = <3>;
> + atmel,vbus-gpio = <0
> + &pioE 3 GPIO_ACTIVE_LOW
> + &pioE 4 GPIO_ACTIVE_LOW
> + >;
> + status = "okay";
> + };
> +
> + usb2: ehci at 00700000 {
> + status = "okay";
> + };
> + };
> +
> + gpio_keys {
> + compatible = "gpio-keys";
> +
> + bp3 {
> + label = "PB_USER";
> + gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
> + linux,code = <0x104>;
> + gpio-key,wakeup;
> + };
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> +
> + d2 {
> + label = "d2";
> + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */
> + linux,default-trigger = "heartbeat";
> + };
> +
> + d3 {
> + label = "d3";
> + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
> + };
> + };
> +};
> --
> 1.8.2.2
>
^ permalink raw reply
* [PATCH v1 1/3] net: stmmac:sti: Add STi SOC glue driver.
From: srinivas kandagatla @ 2014-02-07 7:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140206.195342.1998479313077409827.davem@davemloft.net>
Thankyou Dave,
On 07/02/14 03:53, David Miller wrote:
> From: <srinivas.kandagatla@st.com>
> Date: Mon, 3 Feb 2014 12:01:08 +0000
>
>> + res = platform_get_resource_byname(pdev,
>> + IORESOURCE_MEM, "sti-ethconf");
>
> This is not the correct way to format multi-line function calls,
> you'll need to fix this up in this entire series.
I will fix this in next version.
>
> The arguments on the second and subsequent lines must start at
> the first column after the openning parenthesis of the function
> call. You must use the appropriate number of both space and
> TAB characters necessary to do so.
>
> If you're only using TAB characters to indent, you're doing it
> wrong.
>
> Thank you.
>
>
Thanks,
srini
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox