First batch of AT91 drivers for 3.18:

- reset, poweroff and ram drivers are moved to their proper
   location instead of being in mach-at91 directory. They now use
   the appropriate frameworks.
 - big amount of removal of these machine specific drivers and use
   of the newly created drivers. This lead to an overhaul of the setup.c AT91
   startup code.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQEcBAABAgAGBQJUBKc2AAoJEAf03oE53VmQ0BkIAL1t9foWRqNmU5EaSDKvZRQ2
 6pN5995VeU05cmK5v5FwsxDAoGulo0l7klegZiA+dspUfNUPzNQ87dU/xlfCsQiJ
 rJvOxE1NYNUtM6IcnKw+JU8s7RoPl1mhgh5KXdFckjgwwEmAiAoX4Tdx15gcRGaE
 3BEYlNGDudqMaQ+r/NE1IRti5cExQKiEBwktSqZC3eVMMfJ4niaCYy69t6z4hWds
 nbX6FQd6mHzxW8uYd/C85Blb5IhktFp0lgIChAYRXRdVRcMrTSHVhs0x6zh30o3T
 n2xeWgad0qmSsZCSXf59UT9MWK7woLWBUTUSEkgGWksM91om6EC9FJS4zcijp4E=
 =MqpU
 -----END PGP SIGNATURE-----

Merge tag 'at91-drivers' of git://github.com/at91linux/linux-at91 into next/drivers

Merge "First batch of AT91 drivers for 3.18" from Nicolas Ferre:

- reset, poweroff and ram drivers are moved to their proper
  location instead of being in mach-at91 directory. They now use
  the appropriate frameworks.
- big amount of removal of these machine specific drivers and use
  of the newly created drivers. This lead to an overhaul of the setup.c AT91
  startup code.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

* tag 'at91-drivers' of git://github.com/at91linux/linux-at91: (31 commits)
  power: reset: at91-poweroff: fix wakeup status register index
  ARM: at91/power/reset: fix Kconfig "depends on" directive
  ARM: at91: fix ramc standby function registration
  ARM: at91: Remove rstc and shdwc headers
  ARM: at91: Remove rstc and shdwnc global base addresses
  ARM: at91/pm: Remove show_reset_status function
  ARM: at91: Remove poweroff code
  ARM: at91: Register the poweroff driver
  ARM: at91: Remove poweroff DT probing
  ARM: at91: Remove reset code from the machine code
  ARM: at91: Call at91_register_devices in the board files
  ARM: at91: Probe the reset driver
  ARM: at91/soc: Introduce register_devices callback
  ARM: at91: Remove the old-style reset probing
  ARM: at91: Rework ramc mapping code
  ARM: at91: setup: Switch to pr_fmt
  ARM: at91: remove old irq material
  ARM: at91: make use of the new AIC driver for dt enabled boards
  ARM: at91: enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks
  ARM: at91: introduce OLD_IRQ_AT91 Kconfig option
  ...
This commit is contained in:
Arnd Bergmann 2014-09-05 22:26:40 +02:00
commit 6ce041aba3
45 changed files with 891 additions and 802 deletions

View File

@ -61,8 +61,8 @@ RAMC SDRAM/DDR Controller required properties:
- compatible: Should be "atmel,at91rm9200-sdramc",
"atmel,at91sam9260-sdramc",
"atmel,at91sam9g45-ddramc",
"atmel,sama5d3-ddramc",
- reg: Should contain registers location and length
For at91sam9263 and at91sam9g45 you must specify 2 entries.
Examples:
@ -71,12 +71,6 @@ Examples:
reg = <0xffffe800 0x200>;
};
ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200
0xffffe600 0x200>;
};
SHDWC Shutdown Controller
required properties:

View File

@ -345,10 +345,14 @@
};
};
ramc: ramc@ffffe200 {
ramc0: ramc@ffffe200 {
compatible = "atmel,at91sam9260-sdramc";
reg = <0xffffe200 0x200
0xffffe800 0x200>;
reg = <0xffffe200 0x200>;
};
ramc1: ramc@ffffe800 {
compatible = "atmel,at91sam9260-sdramc";
reg = <0xffffe800 0x200>;
};
pit: timer@fffffd30 {

View File

@ -96,8 +96,14 @@
ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200
0xffffe600 0x200>;
reg = <0xffffe400 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
};
ramc1: ramc@ffffe600 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe600 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
};

View File

@ -87,6 +87,8 @@
ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
};
pmc: pmc@fffffc00 {

View File

@ -95,6 +95,8 @@
ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
};
pmc: pmc@fffffc00 {

View File

@ -402,8 +402,10 @@
};
ramc0: ramc@ffffea00 {
compatible = "atmel,at91sam9g45-ddramc";
compatible = "atmel,sama5d3-ddramc";
reg = <0xffffea00 0x200>;
clocks = <&ddrck>, <&mpddr_clk>;
clock-names = "ddrck", "mpddr";
};
dbgu: serial@ffffee00 {
@ -1170,6 +1172,11 @@
#clock-cells = <0>;
reg = <48>;
};
mpddr_clk: mpddr_clk {
#clock-cells = <0>;
reg = <49>;
};
};
};
@ -1178,6 +1185,11 @@
reg = <0xfffffe00 0x10>;
};
shutdown-controller@fffffe10 {
compatible = "atmel,at91sam9x5-shdwc";
reg = <0xfffffe10 0x10>;
};
pit: timer@fffffe30 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>;

View File

@ -28,13 +28,10 @@ config OLD_CLK_AT91
bool
default AT91_PMC_UNIT && AT91_USE_OLD_CLK
config AT91_SAM9_ALT_RESET
config OLD_IRQ_AT91
bool
default !ARCH_AT91X40
config AT91_SAM9G45_RESET
bool
default !ARCH_AT91X40
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
config AT91_SAM9_TIME
bool
@ -45,19 +42,21 @@ config HAVE_AT91_SMD
config SOC_AT91SAM9
bool
select AT91_SAM9_TIME
select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM926T
select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select MEMORY if USE_OF
select ATMEL_SDRAMC if USE_OF
config SOC_SAMA5
bool
select AT91_SAM9_TIME
select ATMEL_AIC5_IRQ
select CPU_V7
select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select USE_OF
select MEMORY
select ATMEL_SDRAMC
menu "Atmel AT91 System-on-Chip"
@ -70,8 +69,7 @@ config ARCH_AT91X40
depends on !MMU
select CPU_ARM7TDMI
select ARCH_USES_GETTIMEOFFSET
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select OLD_IRQ_AT91
help
Select this if you are using one of Atmel's AT91X40 SoC.
@ -108,11 +106,10 @@ endif
if SOC_SAM_V4_V5
config SOC_AT91RM9200
bool "AT91RM9200"
select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM920T
select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select HAVE_AT91_USB_CLK
config SOC_AT91SAM9260

View File

@ -14,31 +14,37 @@ config ARCH_AT91RM9200
bool "AT91RM9200"
select SOC_AT91RM9200
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
select SOC_AT91SAM9260
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9261
bool "AT91SAM9261 or AT91SAM9G10"
select SOC_AT91SAM9261
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9263
bool "AT91SAM9263"
select SOC_AT91SAM9263
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
select SOC_AT91SAM9RL
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
select SOC_AT91SAM9G45
select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
endchoice

View File

@ -2,14 +2,13 @@
# Makefile for the linux kernel.
#
obj-y := irq.o gpio.o setup.o sysirq_mask.o
obj-y := gpio.o setup.o sysirq_mask.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_OLD_IRQ_AT91) += irq.o
obj-$(CONFIG_OLD_CLK_AT91) += clock.o
obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o

View File

@ -1,53 +0,0 @@
/*
* arch/arm/mach-at91/include/mach/at91_rstc.h
*
* Copyright (C) 2007 Andrew Victor
* Copyright (C) 2007 Atmel Corporation.
*
* Reset Controller (RSTC) - System peripherals regsters.
* Based on AT91SAM9261 datasheet revision D.
*
* 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.
*/
#ifndef AT91_RSTC_H
#define AT91_RSTC_H
#ifndef __ASSEMBLY__
extern void __iomem *at91_rstc_base;
#define at91_rstc_read(field) \
__raw_readl(at91_rstc_base + field)
#define at91_rstc_write(field, value) \
__raw_writel(value, at91_rstc_base + field)
#else
.extern at91_rstc_base
#endif
#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8)
#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8)
#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8)
#define AT91_RSTC_RSTTYP_USER (4 << 8)
#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
#endif

View File

@ -1,50 +0,0 @@
/*
* arch/arm/mach-at91/include/mach/at91_shdwc.h
*
* Copyright (C) 2007 Andrew Victor
* Copyright (C) 2007 Atmel Corporation.
*
* Shutdown Controller (SHDWC) - System peripherals regsters.
* Based on AT91SAM9261 datasheet revision D.
*
* 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.
*/
#ifndef AT91_SHDWC_H
#define AT91_SHDWC_H
#ifndef __ASSEMBLY__
extern void __iomem *at91_shdwc_base;
#define at91_shdwc_read(field) \
__raw_readl(at91_shdwc_base + field)
#define at91_shdwc_write(field, value) \
__raw_writel(value, at91_shdwc_base + field)
#endif
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
#define AT91_SHDW_WKMODE0_NONE 0
#define AT91_SHDW_WKMODE0_HIGH 1
#define AT91_SHDW_WKMODE0_LOW 2
#define AT91_SHDW_WKMODE0_ANYLEVEL 3
#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */
#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
#endif

View File

@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@ -24,7 +25,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void)
static void __init at91sam9260_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void)
static void __init at91sam9260_initialize(void)
{
arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void)
at91_gpio_init(at91sam9260_gpio, 3);
}
static struct resource rstc_resources[] = {
[0] = {
.start = AT91SAM9260_BASE_RSTC,
.end = AT91SAM9260_BASE_RSTC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9260_BASE_SDRAMC,
.end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device rstc_device = {
.name = "at91-sam9260-reset",
.resource = rstc_resources,
.num_resources = ARRAY_SIZE(rstc_resources),
};
static struct resource shdwc_resources[] = {
[0] = {
.start = AT91SAM9260_BASE_SHDWC,
.end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device shdwc_device = {
.name = "at91-poweroff",
.resource = shdwc_resources,
.num_resources = ARRAY_SIZE(shdwc_resources),
};
static void __init at91sam9260_register_devices(void)
{
platform_device_register(&rstc_device);
platform_device_register(&shdwc_device);
}
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@ -411,5 +447,6 @@ AT91_SOC_START(at91sam9260)
| (1 << AT91SAM9260_ID_IRQ2),
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
.register_devices = at91sam9260_register_devices,
.init = at91sam9260_initialize,
AT91_SOC_END

View File

@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@ -23,7 +24,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void)
static void __init at91sam9261_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void)
static void __init at91sam9261_initialize(void)
{
arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void)
at91_gpio_init(at91sam9261_gpio, 3);
}
static struct resource rstc_resources[] = {
[0] = {
.start = AT91SAM9261_BASE_RSTC,
.end = AT91SAM9261_BASE_RSTC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9261_BASE_SDRAMC,
.end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device rstc_device = {
.name = "at91-sam9260-reset",
.resource = rstc_resources,
.num_resources = ARRAY_SIZE(rstc_resources),
};
static struct resource shdwc_resources[] = {
[0] = {
.start = AT91SAM9261_BASE_SHDWC,
.end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device shdwc_device = {
.name = "at91-poweroff",
.resource = shdwc_resources,
.num_resources = ARRAY_SIZE(shdwc_resources),
};
static void __init at91sam9261_register_devices(void)
{
platform_device_register(&rstc_device);
platform_device_register(&shdwc_device);
}
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@ -370,5 +406,6 @@ AT91_SOC_START(at91sam9261)
| (1 << AT91SAM9261_ID_IRQ2),
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
.register_devices = at91sam9261_register_devices,
.init = at91sam9261_initialize,
AT91_SOC_END

View File

@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@ -22,7 +23,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void)
static void __init at91sam9263_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512);
at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void)
static void __init at91sam9263_initialize(void)
{
arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void)
at91_gpio_init(at91sam9263_gpio, 5);
}
static struct resource rstc_resources[] = {
[0] = {
.start = AT91SAM9263_BASE_RSTC,
.end = AT91SAM9263_BASE_RSTC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9263_BASE_SDRAMC0,
.end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device rstc_device = {
.name = "at91-sam9260-reset",
.resource = rstc_resources,
.num_resources = ARRAY_SIZE(rstc_resources),
};
static struct resource shdwc_resources[] = {
[0] = {
.start = AT91SAM9263_BASE_SHDWC,
.end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device shdwc_device = {
.name = "at91-poweroff",
.resource = shdwc_resources,
.num_resources = ARRAY_SIZE(shdwc_resources),
};
static void __init at91sam9263_register_devices(void)
{
platform_device_register(&rstc_device);
platform_device_register(&shdwc_device);
}
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@ -392,5 +428,6 @@ AT91_SOC_START(at91sam9263)
.extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
.register_devices = at91sam9263_register_devices,
.init = at91sam9263_initialize,
AT91_SOC_END

View File

@ -1,40 +0,0 @@
/*
* reset AT91SAM9G20 as per errata
*
* (C) BitBox Ltd 2010
*
* unless the SDRAM is cleanly shutdown before we hit the
* reset register it can be left driving the data bus and
* killing the chance of a subsequent boot from NAND
*
* 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.
*/
#include <linux/linkage.h>
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
#include "at91_rstc.h"
.arm
.globl at91sam9_alt_restart
at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants
ldr r0, [r0]
ldr r4, =at91_rstc_base
ldr r1, [r4]
mov r2, #1
mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
.balign 32 @ align to cache line
str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
str r4, [r1, #AT91_RSTC_CR] @ reset processor
b .

View File

@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/clk/at91_pmc.h>
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void)
static void __init at91sam9g45_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void)
static void __init at91sam9g45_initialize(void)
{
arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9g45_restart;
at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void)
at91_gpio_init(at91sam9g45_gpio, 5);
}
static struct resource rstc_resources[] = {
[0] = {
.start = AT91SAM9G45_BASE_RSTC,
.end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9G45_BASE_DDRSDRC1,
.end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = AT91SAM9G45_BASE_DDRSDRC0,
.end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device rstc_device = {
.name = "at91-sam9g45-reset",
.resource = rstc_resources,
.num_resources = ARRAY_SIZE(rstc_resources),
};
static struct resource shdwc_resources[] = {
[0] = {
.start = AT91SAM9G45_BASE_SHDWC,
.end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device shdwc_device = {
.name = "at91-poweroff",
.resource = shdwc_resources,
.num_resources = ARRAY_SIZE(shdwc_resources),
};
static void __init at91sam9g45_register_devices(void)
{
platform_device_register(&rstc_device);
platform_device_register(&shdwc_device);
}
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@ -441,5 +483,6 @@ AT91_SOC_START(at91sam9g45)
.extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
.register_devices = at91sam9g45_register_devices,
.init = at91sam9g45_initialize,
AT91_SOC_END

View File

@ -1,45 +0,0 @@
/*
* reset AT91SAM9G45 as per errata
*
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
*
* unless the SDRAM is cleanly shutdown before we hit the
* reset register it can be left driving the data bus and
* killing the chance of a subsequent boot from NAND
*
* GPLv2 Only
*/
#include <linux/linkage.h>
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
#include "at91_rstc.h"
.arm
/*
* at91_ramc_base is an array void*
* init at NULL if only one DDR controler is present in or DT
*/
.globl at91sam9g45_restart
at91sam9g45_restart:
ldr r5, =at91_ramc_base @ preload constants
ldr r0, [r5]
ldr r5, [r5, #4] @ ddr1
cmp r5, #0
ldr r4, =at91_rstc_base
ldr r1, [r4]
mov r2, #1
mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
.balign 32 @ align to cache line
strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access
strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1
str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
str r4, [r1, #AT91_RSTC_CR] @ reset processor
b .

View File

@ -10,6 +10,7 @@
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h>
@ -23,7 +24,6 @@
#include <mach/hardware.h>
#include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h"
#include "generic.h"
#include "sam9_smc.h"
@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void)
static void __init at91sam9rl_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void)
static void __init at91sam9rl_initialize(void)
{
arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void)
at91_gpio_init(at91sam9rl_gpio, 4);
}
static struct resource rstc_resources[] = {
[0] = {
.start = AT91SAM9RL_BASE_RSTC,
.end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9RL_BASE_SDRAMC,
.end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device rstc_device = {
.name = "at91-sam9260-reset",
.resource = rstc_resources,
.num_resources = ARRAY_SIZE(rstc_resources),
};
static struct resource shdwc_resources[] = {
[0] = {
.start = AT91SAM9RL_BASE_SHDWC,
.end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device shdwc_device = {
.name = "at91-poweroff",
.resource = shdwc_resources,
.num_resources = ARRAY_SIZE(shdwc_resources),
};
static void __init at91sam9rl_register_devices(void)
{
platform_device_register(&rstc_device);
platform_device_register(&shdwc_device);
}
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@ -382,5 +418,6 @@ AT91_SOC_START(at91sam9rl)
#if defined(CONFIG_OLD_CLK_AT91)
.register_clocks = at91sam9rl_register_clocks,
#endif
.register_devices = at91sam9rl_register_devices,
.init = at91sam9rl_initialize,
AT91_SOC_END

View File

@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = {
static void __init afeb9260_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void)
static void __init cam60_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = {
static void __init cpu9krea_board_init(void)
{
at91_register_devices();
/* NOR */
cpu9krea_add_device_nor();
/* Serial */

View File

@ -24,17 +24,6 @@
#include "at91_aic.h"
#include "generic.h"
static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
{ /*sentinel*/ }
};
static void __init at91rm9200_dt_init_irq(void)
{
of_irq_init(irq_of_match);
}
static const char *at91rm9200_dt_board_compat[] __initdata = {
"atmel,at91rm9200",
NULL
@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = {
DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
.init_time = at91rm9200_timer_init,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = at91rm9200_dt_initialize,
.init_irq = at91rm9200_dt_init_irq,
.dt_compat = at91rm9200_dt_board_compat,
MACHINE_END

View File

@ -34,17 +34,6 @@ static void __init sam9_dt_timer_init(void)
at91sam926x_pit_init();
}
static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
{ /*sentinel*/ }
};
static void __init at91_dt_init_irq(void)
{
of_irq_init(irq_of_match);
}
static const char *at91_dt_board_compat[] __initdata = {
"atmel,at91sam9",
NULL
@ -54,8 +43,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
/* Maintainer: Atmel */
.init_time = sam9_dt_timer_init,
.map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = at91_dt_initialize,
.init_irq = at91_dt_init_irq,
.dt_compat = at91_dt_board_compat,
MACHINE_END

View File

@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void)
at91sam926x_pit_init();
}
static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init },
{ /*sentinel*/ }
};
static void __init at91_dt_init_irq(void)
{
of_irq_init(irq_of_match);
}
static int ksz9021rn_phy_fixup(struct phy_device *phy)
{
int value;
@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */
.init_time = sama5_dt_timer_init,
.map_io = at91_map_io,
.handle_irq = at91_aic5_handle_irq,
.init_early = at91_dt_initialize,
.init_irq = at91_dt_init_irq,
.init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat,
MACHINE_END

View File

@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = {
static void __init flexibity_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -45,7 +45,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -49,7 +49,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -50,7 +50,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -48,7 +48,6 @@
#include <mach/system_rev.h>
#include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DGBU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -35,7 +35,6 @@
#include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void)
{
at91_register_devices();
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void)
static void __init snapper9260_board_init(void)
{
at91_register_devices();
at91_add_device_i2c(snapper9260_i2c_devices,
ARRAY_SIZE(snapper9260_i2c_devices));

View File

@ -37,6 +37,8 @@ extern int __init at91_aic5_of_init(struct device_node *node,
extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Devices */
extern void __init at91_register_devices(void);
/* Timer */
extern void at91rm9200_ioremap_st(u32 addr);
@ -62,14 +64,6 @@ extern void at91_irq_resume(void);
/* idle */
extern void at91sam9_idle(void);
/* reset */
extern void at91_ioremap_rstc(u32 base_addr);
extern void at91sam9_alt_restart(enum reboot_mode, const char *);
extern void at91sam9g45_restart(enum reboot_mode, const char *);
/* shutdown */
extern void at91_ioremap_shdwc(u32 base_addr);
/* Matrix */
extern void at91_ioremap_matrix(u32 base_addr);

View File

@ -48,11 +48,6 @@ void __iomem *at91_aic_base;
static struct irq_domain *at91_aic_domain;
static struct device_node *at91_aic_np;
static unsigned int n_irqs = NR_AIC_IRQS;
static unsigned long at91_aic_caps = 0;
/* AIC5 introduces a Source Select Register */
#define AT91_AIC_CAP_AIC5 (1 << 0)
#define has_aic5() (at91_aic_caps & AT91_AIC_CAP_AIC5)
#ifdef CONFIG_PM
@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
void at91_irq_suspend(void)
{
int bit = -1;
if (has_aic5()) {
/* disable enabled irqs */
while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
at91_aic_write(AT91_AIC5_SSR,
bit & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IDCR, 1);
}
/* enable wakeup irqs */
bit = -1;
while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
at91_aic_write(AT91_AIC5_SSR,
bit & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IECR, 1);
}
} else {
at91_aic_write(AT91_AIC_IDCR, *backups);
at91_aic_write(AT91_AIC_IECR, *wakeups);
}
at91_aic_write(AT91_AIC_IDCR, *backups);
at91_aic_write(AT91_AIC_IECR, *wakeups);
}
void at91_irq_resume(void)
{
int bit = -1;
if (has_aic5()) {
/* disable wakeup irqs */
while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
at91_aic_write(AT91_AIC5_SSR,
bit & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IDCR, 1);
}
/* enable irqs disabled for suspend */
bit = -1;
while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
at91_aic_write(AT91_AIC5_SSR,
bit & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IECR, 1);
}
} else {
at91_aic_write(AT91_AIC_IDCR, *wakeups);
at91_aic_write(AT91_AIC_IECR, *backups);
}
at91_aic_write(AT91_AIC_IDCR, *wakeups);
at91_aic_write(AT91_AIC_IECR, *backups);
}
#else
@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs)
handle_IRQ(irqnr, regs);
}
asmlinkage void __exception_irq_entry
at91_aic5_handle_irq(struct pt_regs *regs)
{
u32 irqnr;
u32 irqstat;
irqnr = at91_aic_read(AT91_AIC5_IVR);
irqstat = at91_aic_read(AT91_AIC5_ISR);
if (!irqstat)
at91_aic_write(AT91_AIC5_EOICR, 0);
else
handle_IRQ(irqnr, regs);
}
static void at91_aic_mask_irq(struct irq_data *d)
{
/* Disable interrupt on AIC */
@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d)
clear_backup(d->hwirq);
}
static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d)
{
/* Disable interrupt on AIC5 */
at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IDCR, 1);
/* Update ISR cache */
clear_backup(d->hwirq);
}
static void at91_aic_unmask_irq(struct irq_data *d)
{
/* Enable interrupt on AIC */
@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d)
set_backup(d->hwirq);
}
static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d)
{
/* Enable interrupt on AIC5 */
at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IECR, 1);
/* Update ISR cache */
set_backup(d->hwirq);
}
static void at91_aic_eoi(struct irq_data *d)
{
/*
@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d)
at91_aic_write(AT91_AIC_EOICR, 0);
}
static void __maybe_unused at91_aic5_eoi(struct irq_data *d)
{
at91_aic_write(AT91_AIC5_EOICR, 0);
}
static unsigned long *at91_extern_irq;
u32 at91_get_extern_irq(void)
@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
if (srctype < 0)
return srctype;
if (has_aic5()) {
at91_aic_write(AT91_AIC5_SSR,
d->hwirq & AT91_AIC5_INTSEL_MSK);
smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE;
at91_aic_write(AT91_AIC5_SMR, smr | srctype);
} else {
smr = at91_aic_read(AT91_AIC_SMR(d->hwirq))
& ~AT91_AIC_SRCTYPE;
at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
}
smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
return 0;
}
@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector)
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
}
static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector)
{
int i;
/*
* Perform 8 End Of Interrupt Command to make sure AIC
* will not Lock out nIRQ
*/
for (i = 0; i < 8; i++)
at91_aic_write(AT91_AIC5_EOICR, 0);
/*
* Spurious Interrupt ID in Spurious Vector Register.
* When there is no current interrupt, the IRQ Vector Register
* reads the value stored in AIC_SPU
*/
at91_aic_write(AT91_AIC5_SPU, spu_vector);
/* No debugging in AIC: Debug (Protect) Control Register */
at91_aic_write(AT91_AIC5_DCR, 0);
/* Disable and clear all interrupts initially */
for (i = 0; i < n_irqs; i++) {
at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK);
at91_aic_write(AT91_AIC5_IDCR, 1);
at91_aic_write(AT91_AIC5_ICCR, 1);
}
}
#if defined(CONFIG_OF)
static unsigned int *at91_aic_irq_priorities;
static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
/* Put virq number in Source Vector Register */
at91_aic_write(AT91_AIC_SVR(hw), virq);
/* Active Low interrupt, with priority */
at91_aic_write(AT91_AIC_SMR(hw),
AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
return 0;
}
static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK);
/* Put virq number in Source Vector Register */
at91_aic_write(AT91_AIC5_SVR, virq);
/* Active Low interrupt, with priority */
at91_aic_write(AT91_AIC5_SMR,
AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
return 0;
}
static int at91_aic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type)
{
if (WARN_ON(intsize < 3))
return -EINVAL;
if (WARN_ON(intspec[0] >= n_irqs))
return -EINVAL;
if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY)
|| (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
return -EINVAL;
*out_hwirq = intspec[0];
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
at91_aic_irq_priorities[*out_hwirq] = intspec[2];
return 0;
}
static struct irq_domain_ops at91_aic_irq_ops = {
.map = at91_aic_irq_map,
.xlate = at91_aic_irq_domain_xlate,
};
int __init at91_aic_of_common_init(struct device_node *node,
struct device_node *parent)
{
struct property *prop;
const __be32 *p;
u32 val;
at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs)
* sizeof(*at91_extern_irq), GFP_KERNEL);
if (!at91_extern_irq)
return -ENOMEM;
if (at91_aic_pm_init()) {
kfree(at91_extern_irq);
return -ENOMEM;
}
at91_aic_irq_priorities = kzalloc(n_irqs
* sizeof(*at91_aic_irq_priorities),
GFP_KERNEL);
if (!at91_aic_irq_priorities)
return -ENOMEM;
at91_aic_base = of_iomap(node, 0);
at91_aic_np = node;
at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs,
&at91_aic_irq_ops, NULL);
if (!at91_aic_domain)
panic("Unable to add AIC irq domain (DT)\n");
of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) {
if (val >= n_irqs)
pr_warn("AIC: external irq %d >= %d skip it\n",
val, n_irqs);
else
set_bit(val, at91_extern_irq);
}
irq_set_default_host(at91_aic_domain);
return 0;
}
int __init at91_aic_of_init(struct device_node *node,
struct device_node *parent)
{
int err;
err = at91_aic_of_common_init(node, parent);
if (err)
return err;
at91_aic_hw_init(n_irqs);
return 0;
}
int __init at91_aic5_of_init(struct device_node *node,
struct device_node *parent)
{
int err;
at91_aic_caps |= AT91_AIC_CAP_AIC5;
n_irqs = NR_AIC5_IRQS;
at91_aic_chip.irq_ack = at91_aic5_mask_irq;
at91_aic_chip.irq_mask = at91_aic5_mask_irq;
at91_aic_chip.irq_unmask = at91_aic5_unmask_irq;
at91_aic_chip.irq_eoi = at91_aic5_eoi;
at91_aic_irq_ops.map = at91_aic5_irq_map;
err = at91_aic_of_common_init(node, parent);
if (err)
return err;
at91_aic5_hw_init(n_irqs);
return 0;
}
#endif
/*
* Initialize the AIC interrupt controller.
*/

View File

@ -34,79 +34,8 @@
#include "pm.h"
#include "gpio.h"
/*
* Show the reason for the previous system reset.
*/
#include "at91_rstc.h"
#include "at91_shdwc.h"
static void (*at91_pm_standby)(void);
static void __init show_reset_status(void)
{
static char reset[] __initdata = "reset";
static char general[] __initdata = "general";
static char wakeup[] __initdata = "wakeup";
static char watchdog[] __initdata = "watchdog";
static char software[] __initdata = "software";
static char user[] __initdata = "user";
static char unknown[] __initdata = "unknown";
static char signal[] __initdata = "signal";
static char rtc[] __initdata = "rtc";
static char rtt[] __initdata = "rtt";
static char restore[] __initdata = "power-restored";
char *reason, *r2 = reset;
u32 reset_type, wake_type;
if (!at91_shdwc_base || !at91_rstc_base)
return;
reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
wake_type = at91_shdwc_read(AT91_SHDW_SR);
switch (reset_type) {
case AT91_RSTC_RSTTYP_GENERAL:
reason = general;
break;
case AT91_RSTC_RSTTYP_WAKEUP:
/* board-specific code enabled the wakeup sources */
reason = wakeup;
/* "wakeup signal" */
if (wake_type & AT91_SHDW_WAKEUP0)
r2 = signal;
else {
r2 = reason;
if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
reason = rtt;
else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
reason = rtc;
else if (wake_type == 0) /* power-restored wakeup */
reason = restore;
else /* unknown wakeup */
reason = unknown;
}
break;
case AT91_RSTC_RSTTYP_WATCHDOG:
reason = watchdog;
break;
case AT91_RSTC_RSTTYP_SOFTWARE:
reason = software;
break;
case AT91_RSTC_RSTTYP_USER:
reason = user;
break;
default:
reason = unknown;
break;
}
pr_info("AT91: Starting after %s %s\n", reason, r2);
}
static int at91_pm_valid_state(suspend_state_t state)
{
switch (state) {
@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state)
at91_pinctrl_gpio_suspend();
else
at91_gpio_suspend();
at91_irq_suspend();
pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
/* remember all the always-wake irqs */
(at91_pmc_read(AT91_PMC_PCSR)
| (1 << AT91_ID_FIQ)
| (1 << AT91_ID_SYS)
| (at91_get_extern_irq()))
& at91_aic_read(AT91_AIC_IMR),
state);
if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) {
at91_irq_suspend();
pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
/* remember all the always-wake irqs */
(at91_pmc_read(AT91_PMC_PCSR)
| (1 << AT91_ID_FIQ)
| (1 << AT91_ID_SYS)
| (at91_get_extern_irq()))
& at91_aic_read(AT91_AIC_IMR),
state);
}
switch (state) {
/*
@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state)
goto error;
}
pr_debug("AT91: PM - wakeup %08x\n",
at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));
if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
pr_debug("AT91: PM - wakeup %08x\n",
at91_aic_read(AT91_AIC_IPR) &
at91_aic_read(AT91_AIC_IMR));
error:
target_state = PM_SUSPEND_ON;
at91_irq_resume();
if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
at91_irq_resume();
if (of_have_populated_dt())
at91_pinctrl_gpio_resume();
else
@ -338,7 +275,6 @@ static int __init at91_pm_init(void)
suspend_set_ops(&at91_pm_ops);
show_reset_status();
return 0;
}
arch_initcall(at91_pm_init);

View File

@ -5,6 +5,8 @@
* Under GPLv2
*/
#define pr_fmt(fmt) "AT91: " fmt
#include <linux/module.h>
#include <linux/io.h>
#include <linux/mm.h>
@ -20,7 +22,6 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include "at91_shdwc.h"
#include "soc.h"
#include "generic.h"
#include "pm.h"
@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type)
else
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
pr_info("AT91: filled in soc subtype: %s\n",
pr_info("filled in soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
}
@ -49,7 +50,8 @@ void __init at91_init_irq_default(void)
void __init at91_init_interrupts(unsigned int *priority)
{
/* Initialize the AIC interrupt controller */
at91_aic_init(priority, at91_boot_soc.extern_irq);
if (IS_ENABLED(CONFIG_OLD_IRQ_AT91))
at91_aic_init(priority, at91_boot_soc.extern_irq);
/* Enable GPIO interrupts */
at91_gpio_irq_setup();
@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
}
at91_ramc_base[id] = ioremap(addr, size);
if (!at91_ramc_base[id])
panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr);
panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr);
}
static struct map_desc sram_desc[2] __initdata;
@ -83,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
desc->length = length;
desc->type = MT_MEMORY_RWX_NONCACHED;
pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n",
pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
base, length, desc->virtual);
iotable_init(desc, 1);
@ -302,45 +304,21 @@ void __init at91_map_io(void)
soc_detect(AT91_BASE_DBGU1);
if (!at91_soc_is_detected())
panic("AT91: Impossible to detect the SOC type");
panic(pr_fmt("Impossible to detect the SOC type"));
pr_info("AT91: Detected soc type: %s\n",
pr_info("Detected soc type: %s\n",
at91_get_soc_type(&at91_soc_initdata));
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("AT91: Detected soc subtype: %s\n",
pr_info("Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
if (!at91_soc_is_enabled())
panic("AT91: Soc not enabled");
panic(pr_fmt("Soc not enabled"));
if (at91_boot_soc.map_io)
at91_boot_soc.map_io();
}
void __iomem *at91_shdwc_base = NULL;
static void at91sam9_poweroff(void)
{
at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
}
void __init at91_ioremap_shdwc(u32 base_addr)
{
at91_shdwc_base = ioremap(base_addr, 16);
if (!at91_shdwc_base)
panic("Impossible to ioremap at91_shdwc_base\n");
pm_power_off = at91sam9_poweroff;
}
void __iomem *at91_rstc_base;
void __init at91_ioremap_rstc(u32 base_addr)
{
at91_rstc_base = ioremap(base_addr, 16);
if (!at91_rstc_base)
panic("Impossible to ioremap at91_rstc_base\n");
}
void __iomem *at91_matrix_base;
EXPORT_SYMBOL_GPL(at91_matrix_base);
@ -348,42 +326,15 @@ void __init at91_ioremap_matrix(u32 base_addr)
{
at91_matrix_base = ioremap(base_addr, 512);
if (!at91_matrix_base)
panic("Impossible to ioremap at91_matrix_base\n");
panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
}
#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40)
static struct of_device_id rstc_ids[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
{ /*sentinel*/ }
};
static void at91_dt_rstc(void)
{
struct device_node *np;
const struct of_device_id *of_id;
np = of_find_matching_node(NULL, rstc_ids);
if (!np)
panic("unable to find compatible rstc node in dtb\n");
at91_rstc_base = of_iomap(np, 0);
if (!at91_rstc_base)
panic("unable to map rstc cpu registers\n");
of_id = of_match_node(rstc_ids, np);
if (!of_id)
panic("AT91: rtsc no restart function available\n");
arm_pm_restart = of_id->data;
of_node_put(np);
}
static struct of_device_id ramc_ids[] = {
{ .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
{ .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
{ .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
{ /*sentinel*/ }
};
@ -391,100 +342,29 @@ static void at91_dt_ramc(void)
{
struct device_node *np;
const struct of_device_id *of_id;
int idx = 0;
const void *standby = NULL;
np = of_find_matching_node(NULL, ramc_ids);
if (!np)
panic("unable to find compatible ram controller node in dtb\n");
for_each_matching_node_and_match(np, ramc_ids, &of_id) {
at91_ramc_base[idx] = of_iomap(np, 0);
if (!at91_ramc_base[idx])
panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
at91_ramc_base[0] = of_iomap(np, 0);
if (!at91_ramc_base[0])
panic("unable to map ramc[0] cpu registers\n");
/* the controller may have 2 banks */
at91_ramc_base[1] = of_iomap(np, 1);
if (!standby)
standby = of_id->data;
of_id = of_match_node(ramc_ids, np);
if (!of_id)
pr_warn("AT91: ramc no standby function available\n");
else
at91_pm_set_standby(of_id->data);
idx++;
}
of_node_put(np);
}
if (!idx)
panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
static struct of_device_id shdwc_ids[] = {
{ .compatible = "atmel,at91sam9260-shdwc", },
{ .compatible = "atmel,at91sam9rl-shdwc", },
{ .compatible = "atmel,at91sam9x5-shdwc", },
{ /*sentinel*/ }
};
static const char *shdwc_wakeup_modes[] = {
[AT91_SHDW_WKMODE0_NONE] = "none",
[AT91_SHDW_WKMODE0_HIGH] = "high",
[AT91_SHDW_WKMODE0_LOW] = "low",
[AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
};
const int at91_dtget_shdwc_wakeup_mode(struct device_node *np)
{
const char *pm;
int err, i;
err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
if (err < 0)
return AT91_SHDW_WKMODE0_ANYLEVEL;
for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
return i;
return -ENODEV;
}
static void at91_dt_shdwc(void)
{
struct device_node *np;
int wakeup_mode;
u32 reg;
u32 mode = 0;
np = of_find_matching_node(NULL, shdwc_ids);
if (!np) {
pr_debug("AT91: unable to find compatible shutdown (shdwc) controller node in dtb\n");
if (!standby) {
pr_warn("ramc no standby function available\n");
return;
}
at91_shdwc_base = of_iomap(np, 0);
if (!at91_shdwc_base)
panic("AT91: unable to map shdwc cpu registers\n");
wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
if (wakeup_mode < 0) {
pr_warn("AT91: shdwc unknown wakeup mode\n");
goto end;
}
if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) {
if (reg > AT91_SHDW_CPTWK0_MAX) {
pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
reg = AT91_SHDW_CPTWK0_MAX;
}
mode |= AT91_SHDW_CPTWK0_(reg);
}
if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
mode |= AT91_SHDW_RTCWKEN;
if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
mode |= AT91_SHDW_RTTWKEN;
at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
end:
pm_power_off = at91sam9_poweroff;
of_node_put(np);
at91_pm_set_standby(standby);
}
void __init at91rm9200_dt_initialize(void)
@ -503,9 +383,7 @@ void __init at91rm9200_dt_initialize(void)
void __init at91_dt_initialize(void)
{
at91_dt_rstc();
at91_dt_ramc();
at91_dt_shdwc();
/* Init clock subsystem */
at91_dt_clock_init();
@ -533,3 +411,8 @@ void __init at91_initialize(unsigned long main_clock)
pinctrl_provide_dummies();
}
void __init at91_register_devices(void)
{
at91_boot_soc.register_devices();
}

View File

@ -11,6 +11,7 @@ struct at91_init_soc {
void (*map_io)(void);
void (*ioremap_registers)(void);
void (*register_clocks)(void);
void (*register_devices)(void);
void (*init)(void);
};

View File

@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
init.ops = &system_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
/*
* CLK_IGNORE_UNUSED is used to avoid ddrck switch off.
* TODO : we should implement a driver supporting at91 ddr controller
* (see drivers/memory) which would request and enable the ddrck clock.
* When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
*/
init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
init.flags = CLK_SET_RATE_PARENT;
sys->id = id;
sys->hw.init = &init;

View File

@ -7,6 +7,16 @@ menuconfig MEMORY
if MEMORY
config ATMEL_SDRAMC
bool "Atmel (Multi-port DDR-)SDRAM Controller"
default y
depends on ARCH_AT91 && OF
help
This driver is for Atmel SDRAM Controller or Atmel Multi-port
DDR-SDRAM Controller available on Atmel AT91SAM9 and SAMA5 SoCs.
Starting with the at91sam9g45, this controller supports SDR, DDR and
LP-DDR memories.
config TI_AEMIF
tristate "Texas Instruments AEMIF driver"
depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF

View File

@ -5,6 +5,7 @@
ifeq ($(CONFIG_DDR),y)
obj-$(CONFIG_OF) += of_memory.o
endif
obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o

View File

@ -0,0 +1,98 @@
/*
* Atmel (Multi-port DDR-)SDRAM Controller driver
*
* Copyright (C) 2014 Atmel
*
* 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 version 2 of the License.
*
* 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/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
struct at91_ramc_caps {
bool has_ddrck;
bool has_mpddr_clk;
};
static const struct at91_ramc_caps at91rm9200_caps = { };
static const struct at91_ramc_caps at91sam9g45_caps = {
.has_ddrck = 1,
.has_mpddr_clk = 0,
};
static const struct at91_ramc_caps sama5d3_caps = {
.has_ddrck = 1,
.has_mpddr_clk = 1,
};
static const struct of_device_id atmel_ramc_of_match[] = {
{ .compatible = "atmel,at91rm9200-sdramc", .data = &at91rm9200_caps, },
{ .compatible = "atmel,at91sam9260-sdramc", .data = &at91rm9200_caps, },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = &at91sam9g45_caps, },
{ .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, },
{},
};
MODULE_DEVICE_TABLE(of, atmel_ramc_of_match);
static int atmel_ramc_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
const struct at91_ramc_caps *caps;
struct clk *clk;
match = of_match_device(atmel_ramc_of_match, &pdev->dev);
caps = match->data;
if (caps->has_ddrck) {
clk = devm_clk_get(&pdev->dev, "ddrck");
if (IS_ERR(clk))
return PTR_ERR(clk);
clk_prepare_enable(clk);
}
if (caps->has_mpddr_clk) {
clk = devm_clk_get(&pdev->dev, "mpddr");
if (IS_ERR(clk)) {
pr_err("AT91 RAMC: couldn't get mpddr clock\n");
return PTR_ERR(clk);
}
clk_prepare_enable(clk);
}
return 0;
}
static struct platform_driver atmel_ramc_driver = {
.probe = atmel_ramc_probe,
.driver = {
.name = "atmel-ramc",
.owner = THIS_MODULE,
.of_match_table = atmel_ramc_of_match,
},
};
static int __init atmel_ramc_init(void)
{
return platform_driver_register(&atmel_ramc_driver);
}
module_init(atmel_ramc_init);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
MODULE_DESCRIPTION("Atmel (Multi-port DDR-)SDRAM Controller");

View File

@ -6,15 +6,33 @@ menuconfig POWER_RESET
Say Y here to enable board reset and power off
if POWER_RESET
config POWER_RESET_AS3722
bool "ams AS3722 power-off driver"
depends on MFD_AS3722 && POWER_RESET
depends on MFD_AS3722
help
This driver supports turning off board via a ams AS3722 power-off.
config POWER_RESET_AT91_POWEROFF
bool "Atmel AT91 poweroff driver"
depends on ARCH_AT91
default SOC_AT91SAM9 || SOC_SAMA5
help
This driver supports poweroff for Atmel AT91SAM9 and SAMA5
SoCs
config POWER_RESET_AT91_RESET
bool "Atmel AT91 reset driver"
depends on ARCH_AT91
default SOC_AT91SAM9 || SOC_SAMA5
help
This driver supports restart for Atmel AT91SAM9 and SAMA5
SoCs
config POWER_RESET_AXXIA
bool "LSI Axxia reset driver"
depends on POWER_RESET && ARCH_AXXIA
depends on ARCH_AXXIA
help
This driver supports restart for Axxia SoC.
@ -33,7 +51,7 @@ config POWER_RESET_BRCMSTB
config POWER_RESET_GPIO
bool "GPIO power-off driver"
depends on OF_GPIO && POWER_RESET
depends on OF_GPIO
help
This driver supports turning off your board via a GPIO line.
If your board needs a GPIO high/low to power down, say Y and
@ -47,13 +65,13 @@ config POWER_RESET_HISI
config POWER_RESET_MSM
bool "Qualcomm MSM power-off driver"
depends on POWER_RESET && ARCH_QCOM
depends on ARCH_QCOM
help
Power off and restart support for Qualcomm boards.
config POWER_RESET_QNAP
bool "QNAP power-off driver"
depends on OF_GPIO && POWER_RESET && PLAT_ORION
depends on OF_GPIO && PLAT_ORION
help
This driver supports turning off QNAP NAS devices by sending
commands to the microcontroller which controls the main power.
@ -71,14 +89,13 @@ config POWER_RESET_RESTART
config POWER_RESET_SUN6I
bool "Allwinner A31 SoC reset driver"
depends on ARCH_SUNXI
depends on POWER_RESET
help
Reboot support for the Allwinner A31 SoCs.
config POWER_RESET_VEXPRESS
bool "ARM Versatile Express power-off and reset driver"
depends on ARM || ARM64
depends on POWER_RESET && VEXPRESS_CONFIG
depends on VEXPRESS_CONFIG
help
Power off and reset support for the ARM Ltd. Versatile
Express boards.
@ -86,7 +103,6 @@ config POWER_RESET_VEXPRESS
config POWER_RESET_XGENE
bool "APM SoC X-Gene reset driver"
depends on ARM64
depends on POWER_RESET
help
Reboot support for the APM SoC X-Gene Eval boards.
@ -97,3 +113,4 @@ config POWER_RESET_KEYSTONE
help
Reboot support for the KEYSTONE SoCs.
endif

View File

@ -1,4 +1,6 @@
obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o
obj-$(CONFIG_POWER_RESET_AT91_POWEROFF) += at91-poweroff.o
obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o
obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o
obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o

View File

@ -0,0 +1,156 @@
/*
* Atmel AT91 SAM9 SoCs reset code
*
* Copyright (C) 2007 Atmel Corporation.
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
* Copyright (C) 2014 Free Electrons
*
* 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/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
#define AT91_SHDW_WKMODE0 GENMASK(2, 0) /* Wake-up 0 Mode Selection */
#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
#define AT91_SHDW_RTTWKEN BIT(16) /* Real Time Timer Wake-up Enable */
#define AT91_SHDW_RTCWKEN BIT(17) /* Real Time Clock Wake-up Enable */
#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
#define AT91_SHDW_WAKEUP0 BIT(0) /* Wake-up 0 Status */
#define AT91_SHDW_RTTWK BIT(16) /* Real-time Timer Wake-up */
#define AT91_SHDW_RTCWK BIT(17) /* Real-time Clock Wake-up [SAM9RL] */
enum wakeup_type {
AT91_SHDW_WKMODE0_NONE = 0,
AT91_SHDW_WKMODE0_HIGH = 1,
AT91_SHDW_WKMODE0_LOW = 2,
AT91_SHDW_WKMODE0_ANYLEVEL = 3,
};
static const char *shdwc_wakeup_modes[] = {
[AT91_SHDW_WKMODE0_NONE] = "none",
[AT91_SHDW_WKMODE0_HIGH] = "high",
[AT91_SHDW_WKMODE0_LOW] = "low",
[AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
};
static void __iomem *at91_shdwc_base;
static void __init at91_wakeup_status(void)
{
u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
char *reason = "unknown";
/* Simple power-on, just bail out */
if (!reg)
return;
if (reg & AT91_SHDW_RTTWK)
reason = "RTT";
else if (reg & AT91_SHDW_RTCWK)
reason = "RTC";
pr_info("AT91: Wake-Up source: %s\n", reason);
}
static void at91_poweroff(void)
{
writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
}
const enum wakeup_type at91_poweroff_get_wakeup_mode(struct device_node *np)
{
const char *pm;
int err, i;
err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
if (err < 0)
return AT91_SHDW_WKMODE0_ANYLEVEL;
for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
return i;
return -ENODEV;
}
static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
enum wakeup_type wakeup_mode;
u32 mode = 0, tmp;
wakeup_mode = at91_poweroff_get_wakeup_mode(np);
if (wakeup_mode < 0) {
dev_warn(&pdev->dev, "shdwc unknown wakeup mode\n");
return;
}
if (!of_property_read_u32(np, "atmel,wakeup-counter", &tmp)) {
if (tmp > AT91_SHDW_CPTWK0_MAX) {
dev_warn(&pdev->dev,
"shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
tmp, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
tmp = AT91_SHDW_CPTWK0_MAX;
}
mode |= AT91_SHDW_CPTWK0_(tmp);
}
if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
mode |= AT91_SHDW_RTCWKEN;
if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
mode |= AT91_SHDW_RTTWKEN;
writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
}
static int at91_poweroff_probe(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(at91_shdwc_base)) {
dev_err(&pdev->dev, "Could not map reset controller address\n");
return PTR_ERR(at91_shdwc_base);
}
at91_wakeup_status();
if (pdev->dev.of_node)
at91_poweroff_dt_set_wakeup_mode(pdev);
pm_power_off = at91_poweroff;
return 0;
}
static struct of_device_id at91_poweroff_of_match[] = {
{ .compatible = "atmel,at91sam9260-shdwc", },
{ .compatible = "atmel,at91sam9rl-shdwc", },
{ .compatible = "atmel,at91sam9x5-shdwc", },
{ /*sentinel*/ }
};
static struct platform_driver at91_poweroff_driver = {
.probe = at91_poweroff_probe,
.driver = {
.name = "at91-poweroff",
.of_match_table = at91_poweroff_of_match,
},
};
module_platform_driver(at91_poweroff_driver);

View File

@ -0,0 +1,252 @@
/*
* Atmel AT91 SAM9 SoCs reset code
*
* Copyright (C) 2007 Atmel Corporation.
* Copyright (C) BitBox Ltd 2010
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
* Copyright (C) 2014 Free Electrons
*
* 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/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <asm/system_misc.h>
#include <mach/at91sam9_ddrsdr.h>
#include <mach/at91sam9_sdramc.h>
#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
#define AT91_RSTC_PROCRST BIT(0) /* Processor Reset */
#define AT91_RSTC_PERRST BIT(2) /* Peripheral Reset */
#define AT91_RSTC_EXTRST BIT(3) /* External Reset */
#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
#define AT91_RSTC_URSTS BIT(0) /* User Reset Status */
#define AT91_RSTC_RSTTYP GENMASK(10, 8) /* Reset Type */
#define AT91_RSTC_NRSTL BIT(16) /* NRST Pin Level */
#define AT91_RSTC_SRCMP BIT(17) /* Software Reset Command in Progress */
#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
enum reset_type {
RESET_TYPE_GENERAL = 0,
RESET_TYPE_WAKEUP = 1,
RESET_TYPE_WATCHDOG = 2,
RESET_TYPE_SOFTWARE = 3,
RESET_TYPE_USER = 4,
};
static void __iomem *at91_ramc_base[2], *at91_rstc_base;
/*
* unless the SDRAM is cleanly shutdown before we hit the
* reset register it can be left driving the data bus and
* killing the chance of a subsequent boot from NAND
*/
static void at91sam9260_restart(enum reboot_mode mode, const char *cmd)
{
asm volatile(
/* Align to cache lines */
".balign 32\n\t"
/* Disable SDRAM accesses */
"str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t"
/* Power down SDRAM */
"str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t"
/* Reset CPU */
"str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t"
"b .\n\t"
:
: "r" (at91_ramc_base[0]),
"r" (at91_rstc_base),
"r" (1),
"r" (AT91_SDRAMC_LPCB_POWER_DOWN),
"r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST));
}
static void at91sam9g45_restart(enum reboot_mode mode, const char *cmd)
{
asm volatile(
/*
* Test wether we have a second RAM controller to care
* about.
*
* First, test that we can dereference the virtual address.
*/
"cmp %1, #0\n\t"
"beq 1f\n\t"
/* Then, test that the RAM controller is enabled */
"ldr r0, [%1]\n\t"
"cmp r0, #0\n\t"
/* Align to cache lines */
".balign 32\n\t"
/* Disable SDRAM0 accesses */
"1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
/* Power down SDRAM0 */
" str %4, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
/* Disable SDRAM1 accesses */
" strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
/* Power down SDRAM1 */
" strne %4, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
/* Reset CPU */
" str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
" b .\n\t"
:
: "r" (at91_ramc_base[0]),
"r" (at91_ramc_base[1]),
"r" (at91_rstc_base),
"r" (1),
"r" (AT91_DDRSDRC_LPCB_POWER_DOWN),
"r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)
: "r0");
}
static void __init at91_reset_status(struct platform_device *pdev)
{
u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
char *reason;
switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
case RESET_TYPE_GENERAL:
reason = "general reset";
break;
case RESET_TYPE_WAKEUP:
reason = "wakeup";
break;
case RESET_TYPE_WATCHDOG:
reason = "watchdog reset";
break;
case RESET_TYPE_SOFTWARE:
reason = "software reset";
break;
case RESET_TYPE_USER:
reason = "user reset";
break;
default:
reason = "unknown reset";
break;
}
pr_info("AT91: Starting after %s\n", reason);
}
static struct of_device_id at91_ramc_of_match[] = {
{ .compatible = "atmel,at91sam9260-sdramc", },
{ .compatible = "atmel,at91sam9g45-ddramc", },
{ .compatible = "atmel,sama5d3-ddramc", },
{ /* sentinel */ }
};
static struct of_device_id at91_reset_of_match[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart },
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
{ /* sentinel */ }
};
static int at91_reset_of_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device_node *np;
int idx = 0;
at91_rstc_base = of_iomap(pdev->dev.of_node, 0);
if (!at91_rstc_base) {
dev_err(&pdev->dev, "Could not map reset controller address\n");
return -ENODEV;
}
for_each_matching_node(np, at91_ramc_of_match) {
at91_ramc_base[idx] = of_iomap(np, 0);
if (!at91_ramc_base[idx]) {
dev_err(&pdev->dev, "Could not map ram controller address\n");
return -ENODEV;
}
idx++;
}
match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
arm_pm_restart = match->data;
return 0;
}
static int at91_reset_platform_probe(struct platform_device *pdev)
{
const struct platform_device_id *match;
struct resource *res;
int idx = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_rstc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(at91_rstc_base)) {
dev_err(&pdev->dev, "Could not map reset controller address\n");
return PTR_ERR(at91_rstc_base);
}
for (idx = 0; idx < 2; idx++) {
res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (IS_ERR(at91_ramc_base[idx])) {
dev_err(&pdev->dev, "Could not map ram controller address\n");
return PTR_ERR(at91_ramc_base[idx]);
}
}
match = platform_get_device_id(pdev);
arm_pm_restart = (void (*)(enum reboot_mode, const char*))
match->driver_data;
return 0;
}
static int at91_reset_probe(struct platform_device *pdev)
{
int ret;
if (pdev->dev.of_node)
ret = at91_reset_of_probe(pdev);
else
ret = at91_reset_platform_probe(pdev);
if (ret)
return ret;
at91_reset_status(pdev);
return 0;
}
static struct platform_device_id at91_reset_plat_match[] = {
{ "at91-sam9260-reset", (unsigned long)at91sam9260_restart },
{ "at91-sam9g45-reset", (unsigned long)at91sam9g45_restart },
{ /* sentinel */ }
};
static struct platform_driver at91_reset_driver = {
.probe = at91_reset_probe,
.driver = {
.name = "at91-reset",
.of_match_table = at91_reset_of_match,
},
.id_table = at91_reset_plat_match,
};
module_platform_driver(at91_reset_driver);