Commit 6ce041ab authored by Arnd Bergmann's avatar Arnd Bergmann

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: default avatarArnd 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
  ...
parents 52addcf9 405a72c5
...@@ -61,8 +61,8 @@ RAMC SDRAM/DDR Controller required properties: ...@@ -61,8 +61,8 @@ RAMC SDRAM/DDR Controller required properties:
- compatible: Should be "atmel,at91rm9200-sdramc", - compatible: Should be "atmel,at91rm9200-sdramc",
"atmel,at91sam9260-sdramc", "atmel,at91sam9260-sdramc",
"atmel,at91sam9g45-ddramc", "atmel,at91sam9g45-ddramc",
"atmel,sama5d3-ddramc",
- reg: Should contain registers location and length - reg: Should contain registers location and length
For at91sam9263 and at91sam9g45 you must specify 2 entries.
Examples: Examples:
...@@ -71,12 +71,6 @@ Examples: ...@@ -71,12 +71,6 @@ Examples:
reg = <0xffffe800 0x200>; reg = <0xffffe800 0x200>;
}; };
ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200
0xffffe600 0x200>;
};
SHDWC Shutdown Controller SHDWC Shutdown Controller
required properties: required properties:
......
...@@ -345,10 +345,14 @@ ohci_clk: ohci_clk { ...@@ -345,10 +345,14 @@ ohci_clk: ohci_clk {
}; };
}; };
ramc: ramc@ffffe200 { ramc0: ramc@ffffe200 {
compatible = "atmel,at91sam9260-sdramc"; compatible = "atmel,at91sam9260-sdramc";
reg = <0xffffe200 0x200 reg = <0xffffe200 0x200>;
0xffffe800 0x200>; };
ramc1: ramc@ffffe800 {
compatible = "atmel,at91sam9260-sdramc";
reg = <0xffffe800 0x200>;
}; };
pit: timer@fffffd30 { pit: timer@fffffd30 {
......
...@@ -96,8 +96,14 @@ aic: interrupt-controller@fffff000 { ...@@ -96,8 +96,14 @@ aic: interrupt-controller@fffff000 {
ramc0: ramc@ffffe400 { ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc"; compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200 reg = <0xffffe400 0x200>;
0xffffe600 0x200>; clocks = <&ddrck>;
clock-names = "ddrck";
};
ramc1: ramc@ffffe600 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe600 0x200>;
clocks = <&ddrck>; clocks = <&ddrck>;
clock-names = "ddrck"; clock-names = "ddrck";
}; };
......
...@@ -87,6 +87,8 @@ aic: interrupt-controller@fffff000 { ...@@ -87,6 +87,8 @@ aic: interrupt-controller@fffff000 {
ramc0: ramc@ffffe800 { ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc"; compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>; reg = <0xffffe800 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
}; };
pmc: pmc@fffffc00 { pmc: pmc@fffffc00 {
......
...@@ -95,6 +95,8 @@ aic: interrupt-controller@fffff000 { ...@@ -95,6 +95,8 @@ aic: interrupt-controller@fffff000 {
ramc0: ramc@ffffe800 { ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc"; compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>; reg = <0xffffe800 0x200>;
clocks = <&ddrck>;
clock-names = "ddrck";
}; };
pmc: pmc@fffffc00 { pmc: pmc@fffffc00 {
......
...@@ -402,8 +402,10 @@ dma1: dma-controller@ffffe800 { ...@@ -402,8 +402,10 @@ dma1: dma-controller@ffffe800 {
}; };
ramc0: ramc@ffffea00 { ramc0: ramc@ffffea00 {
compatible = "atmel,at91sam9g45-ddramc"; compatible = "atmel,sama5d3-ddramc";
reg = <0xffffea00 0x200>; reg = <0xffffea00 0x200>;
clocks = <&ddrck>, <&mpddr_clk>;
clock-names = "ddrck", "mpddr";
}; };
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
...@@ -1170,6 +1172,11 @@ fuse_clk: fuse_clk { ...@@ -1170,6 +1172,11 @@ fuse_clk: fuse_clk {
#clock-cells = <0>; #clock-cells = <0>;
reg = <48>; reg = <48>;
}; };
mpddr_clk: mpddr_clk {
#clock-cells = <0>;
reg = <49>;
};
}; };
}; };
...@@ -1178,6 +1185,11 @@ rstc@fffffe00 { ...@@ -1178,6 +1185,11 @@ rstc@fffffe00 {
reg = <0xfffffe00 0x10>; reg = <0xfffffe00 0x10>;
}; };
shutdown-controller@fffffe10 {
compatible = "atmel,at91sam9x5-shdwc";
reg = <0xfffffe10 0x10>;
};
pit: timer@fffffe30 { pit: timer@fffffe30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>; reg = <0xfffffe30 0xf>;
......
...@@ -28,13 +28,10 @@ config OLD_CLK_AT91 ...@@ -28,13 +28,10 @@ config OLD_CLK_AT91
bool bool
default AT91_PMC_UNIT && AT91_USE_OLD_CLK default AT91_PMC_UNIT && AT91_USE_OLD_CLK
config AT91_SAM9_ALT_RESET config OLD_IRQ_AT91
bool bool
default !ARCH_AT91X40 select MULTI_IRQ_HANDLER
select SPARSE_IRQ
config AT91_SAM9G45_RESET
bool
default !ARCH_AT91X40
config AT91_SAM9_TIME config AT91_SAM9_TIME
bool bool
...@@ -45,19 +42,21 @@ config HAVE_AT91_SMD ...@@ -45,19 +42,21 @@ config HAVE_AT91_SMD
config SOC_AT91SAM9 config SOC_AT91SAM9
bool bool
select AT91_SAM9_TIME select AT91_SAM9_TIME
select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM926T select CPU_ARM926T
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER select MEMORY if USE_OF
select SPARSE_IRQ select ATMEL_SDRAMC if USE_OF
config SOC_SAMA5 config SOC_SAMA5
bool bool
select AT91_SAM9_TIME select AT91_SAM9_TIME
select ATMEL_AIC5_IRQ
select CPU_V7 select CPU_V7
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select USE_OF select USE_OF
select MEMORY
select ATMEL_SDRAMC
menu "Atmel AT91 System-on-Chip" menu "Atmel AT91 System-on-Chip"
...@@ -70,8 +69,7 @@ config ARCH_AT91X40 ...@@ -70,8 +69,7 @@ config ARCH_AT91X40
depends on !MMU depends on !MMU
select CPU_ARM7TDMI select CPU_ARM7TDMI
select ARCH_USES_GETTIMEOFFSET select ARCH_USES_GETTIMEOFFSET
select MULTI_IRQ_HANDLER select OLD_IRQ_AT91
select SPARSE_IRQ
help help
Select this if you are using one of Atmel's AT91X40 SoC. Select this if you are using one of Atmel's AT91X40 SoC.
...@@ -108,11 +106,10 @@ endif ...@@ -108,11 +106,10 @@ endif
if SOC_SAM_V4_V5 if SOC_SAM_V4_V5
config SOC_AT91RM9200 config SOC_AT91RM9200
bool "AT91RM9200" bool "AT91RM9200"
select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
select CPU_ARM920T select CPU_ARM920T
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0 select HAVE_AT91_DBGU0
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select HAVE_AT91_USB_CLK select HAVE_AT91_USB_CLK
config SOC_AT91SAM9260 config SOC_AT91SAM9260
......
...@@ -14,31 +14,37 @@ config ARCH_AT91RM9200 ...@@ -14,31 +14,37 @@ config ARCH_AT91RM9200
bool "AT91RM9200" bool "AT91RM9200"
select SOC_AT91RM9200 select SOC_AT91RM9200
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9260 config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
select SOC_AT91SAM9260 select SOC_AT91SAM9260
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9261 config ARCH_AT91SAM9261
bool "AT91SAM9261 or AT91SAM9G10" bool "AT91SAM9261 or AT91SAM9G10"
select SOC_AT91SAM9261 select SOC_AT91SAM9261
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9263 config ARCH_AT91SAM9263
bool "AT91SAM9263" bool "AT91SAM9263"
select SOC_AT91SAM9263 select SOC_AT91SAM9263
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9RL config ARCH_AT91SAM9RL
bool "AT91SAM9RL" bool "AT91SAM9RL"
select SOC_AT91SAM9RL select SOC_AT91SAM9RL
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
config ARCH_AT91SAM9G45 config ARCH_AT91SAM9G45
bool "AT91SAM9G45" bool "AT91SAM9G45"
select SOC_AT91SAM9G45 select SOC_AT91SAM9G45
select AT91_USE_OLD_CLK select AT91_USE_OLD_CLK
select OLD_IRQ_AT91
endchoice endchoice
......
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
# Makefile for the linux kernel. # 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-m :=
obj-n := obj-n :=
obj- := obj- :=
obj-$(CONFIG_OLD_IRQ_AT91) += irq.o
obj-$(CONFIG_OLD_CLK_AT91) += clock.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_AT91_SAM9_TIME) += at91sam926x_time.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
......
/*
* 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
/*
* 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
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
...@@ -24,7 +25,6 @@ ...@@ -24,7 +25,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h" #include "soc.h"
#include "generic.h" #include "generic.h"
#include "sam9_smc.h" #include "sam9_smc.h"
...@@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void) ...@@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void)
static void __init at91sam9260_ioremap_registers(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); at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
...@@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void) ...@@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void)
static void __init at91sam9260_initialize(void) static void __init at91sam9260_initialize(void)
{ {
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
...@@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void) ...@@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void)
at91_gpio_init(at91sam9260_gpio, 3); 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 * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -411,5 +447,6 @@ AT91_SOC_START(at91sam9260) ...@@ -411,5 +447,6 @@ AT91_SOC_START(at91sam9260)
| (1 << AT91SAM9260_ID_IRQ2), | (1 << AT91SAM9260_ID_IRQ2),
.ioremap_registers = at91sam9260_ioremap_registers, .ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks, .register_clocks = at91sam9260_register_clocks,
.register_devices = at91sam9260_register_devices,
.init = at91sam9260_initialize, .init = at91sam9260_initialize,
AT91_SOC_END AT91_SOC_END
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
...@@ -23,7 +24,6 @@ ...@@ -23,7 +24,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h" #include "soc.h"
#include "generic.h" #include "generic.h"
#include "sam9_smc.h" #include "sam9_smc.h"
...@@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void) ...@@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void)
static void __init at91sam9261_ioremap_registers(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); at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
...@@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void) ...@@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void)
static void __init at91sam9261_initialize(void) static void __init at91sam9261_initialize(void)
{ {
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
...@@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void) ...@@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void)
at91_gpio_init(at91sam9261_gpio, 3); 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 * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -370,5 +406,6 @@ AT91_SOC_START(at91sam9261) ...@@ -370,5 +406,6 @@ AT91_SOC_START(at91sam9261)
| (1 << AT91SAM9261_ID_IRQ2), | (1 << AT91SAM9261_ID_IRQ2),
.ioremap_registers = at91sam9261_ioremap_registers, .ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks, .register_clocks = at91sam9261_register_clocks,
.register_devices = at91sam9261_register_devices,
.init = at91sam9261_initialize, .init = at91sam9261_initialize,
AT91_SOC_END AT91_SOC_END
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
...@@ -22,7 +23,6 @@ ...@@ -22,7 +23,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h" #include "soc.h"
#include "generic.h" #include "generic.h"
#include "sam9_smc.h" #include "sam9_smc.h"
...@@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void) ...@@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void)
static void __init at91sam9263_ioremap_registers(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(0, AT91SAM9263_BASE_SDRAMC0, 512);
at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
...@@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void) ...@@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void)
static void __init at91sam9263_initialize(void) static void __init at91sam9263_initialize(void)
{ {
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
...@@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void) ...@@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void)
at91_gpio_init(at91sam9263_gpio, 5); 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 * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -392,5 +428,6 @@ AT91_SOC_START(at91sam9263) ...@@ -392,5 +428,6 @@ AT91_SOC_START(at91sam9263)
.extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1), .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
.ioremap_registers = at91sam9263_ioremap_registers, .ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks, .register_clocks = at91sam9263_register_clocks,
.register_devices = at91sam9263_register_devices,
.init = at91sam9263_initialize, .init = at91sam9263_initialize,
AT91_SOC_END AT91_SOC_END
/*
* 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 .
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <linux/platform_device.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void) ...@@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void)
static void __init at91sam9g45_ioremap_registers(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(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
...@@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void) ...@@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void)
static void __init at91sam9g45_initialize(void) static void __init at91sam9g45_initialize(void)
{ {
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9g45_restart;
at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
...@@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void) ...@@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void)
at91_gpio_init(at91sam9g45_gpio, 5); 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 * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -441,5 +483,6 @@ AT91_SOC_START(at91sam9g45) ...@@ -441,5 +483,6 @@ AT91_SOC_START(at91sam9g45)
.extern_irq = (1 << AT91SAM9G45_ID_IRQ0), .extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
.ioremap_registers = at91sam9g45_ioremap_registers, .ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks, .register_clocks = at91sam9g45_register_clocks,
.register_devices = at91sam9g45_register_devices,
.init = at91sam9g45_initialize, .init = at91sam9g45_initialize,
AT91_SOC_END AT91_SOC_END
/*
* 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 .
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
...@@ -23,7 +24,6 @@ ...@@ -23,7 +24,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_rstc.h"
#include "soc.h" #include "soc.h"
#include "generic.h" #include "generic.h"
#include "sam9_smc.h" #include "sam9_smc.h"
...@@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void) ...@@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void)
static void __init at91sam9rl_ioremap_registers(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); at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
...@@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void) ...@@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void)
static void __init at91sam9rl_initialize(void) static void __init at91sam9rl_initialize(void)
{ {
arm_pm_idle = at91sam9_idle; arm_pm_idle = at91sam9_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
...@@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void) ...@@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void)
at91_gpio_init(at91sam9rl_gpio, 4); 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 * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -382,5 +418,6 @@ AT91_SOC_START(at91sam9rl) ...@@ -382,5 +418,6 @@ AT91_SOC_START(at91sam9rl)
#if defined(CONFIG_OLD_CLK_AT91) #if defined(CONFIG_OLD_CLK_AT91)
.register_clocks = at91sam9rl_register_clocks, .register_clocks = at91sam9rl_register_clocks,
#endif #endif
.register_devices = at91sam9rl_register_devices,
.init = at91sam9rl_initialize, .init = at91sam9rl_initialize,
AT91_SOC_END AT91_SOC_END
...@@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = { ...@@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = {
static void __init afeb9260_board_init(void) static void __init afeb9260_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void) ...@@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void)
static void __init cam60_board_init(void) static void __init cam60_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = { ...@@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = {
static void __init cpu9krea_board_init(void) static void __init cpu9krea_board_init(void)
{ {
at91_register_devices();
/* NOR */ /* NOR */
cpu9krea_add_device_nor(); cpu9krea_add_device_nor();
/* Serial */ /* Serial */
......
...@@ -24,17 +24,6 @@ ...@@ -24,17 +24,6 @@
#include "at91_aic.h" #include "at91_aic.h"
#include "generic.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 = { static const char *at91rm9200_dt_board_compat[] __initdata = {
"atmel,at91rm9200", "atmel,at91rm9200",
NULL NULL
...@@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = { ...@@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = {
DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
.init_time = at91rm9200_timer_init, .init_time = at91rm9200_timer_init,
.map_io = at91_map_io, .map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = at91rm9200_dt_initialize, .init_early = at91rm9200_dt_initialize,
.init_irq = at91rm9200_dt_init_irq,
.dt_compat = at91rm9200_dt_board_compat, .dt_compat = at91rm9200_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -34,17 +34,6 @@ static void __init sam9_dt_timer_init(void) ...@@ -34,17 +34,6 @@ static void __init sam9_dt_timer_init(void)
at91sam926x_pit_init(); 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 = { static const char *at91_dt_board_compat[] __initdata = {
"atmel,at91sam9", "atmel,at91sam9",
NULL NULL
...@@ -54,8 +43,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") ...@@ -54,8 +43,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.init_time = sam9_dt_timer_init, .init_time = sam9_dt_timer_init,
.map_io = at91_map_io, .map_io = at91_map_io,
.handle_irq = at91_aic_handle_irq,
.init_early = at91_dt_initialize, .init_early = at91_dt_initialize,
.init_irq = at91_dt_init_irq,
.dt_compat = at91_dt_board_compat, .dt_compat = at91_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void) ...@@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void)
at91sam926x_pit_init(); 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) static int ksz9021rn_phy_fixup(struct phy_device *phy)
{ {
int value; int value;
...@@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") ...@@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.init_time = sama5_dt_timer_init, .init_time = sama5_dt_timer_init,
.map_io = at91_map_io, .map_io = at91_map_io,
.handle_irq = at91_aic5_handle_irq,
.init_early = at91_dt_initialize, .init_early = at91_dt_initialize,
.init_irq = at91_dt_init_irq,
.init_machine = sama5_dt_device_init, .init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat, .dt_compat = sama5_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = { ...@@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = {
static void __init flexibity_board_init(void) static void __init flexibity_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = { ...@@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include <mach/system_rev.h> #include <mach/system_rev.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h" #include "board.h"
#include "sam9_smc.h" #include "sam9_smc.h"
#include "generic.h" #include "generic.h"
...@@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {} ...@@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include <mach/system_rev.h> #include <mach/system_rev.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h" #include "board.h"
#include "sam9_smc.h" #include "sam9_smc.h"
#include "generic.h" #include "generic.h"
...@@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = { ...@@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
#include <mach/system_rev.h> #include <mach/system_rev.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h" #include "board.h"
#include "sam9_smc.h" #include "sam9_smc.h"
#include "generic.h" #include "generic.h"
...@@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = { ...@@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
#include <mach/system_rev.h> #include <mach/system_rev.h>
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h" #include "board.h"
#include "sam9_smc.h" #include "sam9_smc.h"
#include "generic.h" #include "generic.h"
...@@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = { ...@@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = {
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DGBU on ttyS0. (Rx & Tx only) */ /* DGBU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "at91_aic.h" #include "at91_aic.h"
#include "at91_shdwc.h"
#include "board.h" #include "board.h"
#include "sam9_smc.h" #include "sam9_smc.h"
#include "generic.h" #include "generic.h"
...@@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {} ...@@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {}
static void __init ek_board_init(void) static void __init ek_board_init(void)
{ {
at91_register_devices();
/* Serial */ /* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0); at91_register_uart(0, 0, 0);
......
...@@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void) ...@@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void)
static void __init snapper9260_board_init(void) static void __init snapper9260_board_init(void)
{ {
at91_register_devices();
at91_add_device_i2c(snapper9260_i2c_devices, at91_add_device_i2c(snapper9260_i2c_devices,
ARRAY_SIZE(snapper9260_i2c_devices)); ARRAY_SIZE(snapper9260_i2c_devices));
......
...@@ -37,6 +37,8 @@ extern int __init at91_aic5_of_init(struct device_node *node, ...@@ -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_rtc(u32 rtc_base);
extern void __init at91_sysirq_mask_rtt(u32 rtt_base); extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Devices */
extern void __init at91_register_devices(void);
/* Timer */ /* Timer */
extern void at91rm9200_ioremap_st(u32 addr); extern void at91rm9200_ioremap_st(u32 addr);
...@@ -62,14 +64,6 @@ extern void at91_irq_resume(void); ...@@ -62,14 +64,6 @@ extern void at91_irq_resume(void);
/* idle */ /* idle */
extern void at91sam9_idle(void); 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 */ /* Matrix */
extern void at91_ioremap_matrix(u32 base_addr); extern void at91_ioremap_matrix(u32 base_addr);
......
...@@ -48,11 +48,6 @@ void __iomem *at91_aic_base; ...@@ -48,11 +48,6 @@ void __iomem *at91_aic_base;
static struct irq_domain *at91_aic_domain; static struct irq_domain *at91_aic_domain;
static struct device_node *at91_aic_np; static struct device_node *at91_aic_np;
static unsigned int n_irqs = NR_AIC_IRQS; 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 #ifdef CONFIG_PM
...@@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) ...@@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
void at91_irq_suspend(void) void at91_irq_suspend(void)
{ {
int bit = -1; at91_aic_write(AT91_AIC_IDCR, *backups);
at91_aic_write(AT91_AIC_IECR, *wakeups);
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);
}
} }
void at91_irq_resume(void) void at91_irq_resume(void)
{ {
int bit = -1; at91_aic_write(AT91_AIC_IDCR, *wakeups);
at91_aic_write(AT91_AIC_IECR, *backups);
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);
}
} }
#else #else
...@@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs) ...@@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs)
handle_IRQ(irqnr, 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) static void at91_aic_mask_irq(struct irq_data *d)
{ {
/* Disable interrupt on AIC */ /* Disable interrupt on AIC */
...@@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d) ...@@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d)
clear_backup(d->hwirq); 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) static void at91_aic_unmask_irq(struct irq_data *d)
{ {
/* Enable interrupt on AIC */ /* Enable interrupt on AIC */
...@@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d) ...@@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d)
set_backup(d->hwirq); 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) static void at91_aic_eoi(struct irq_data *d)
{ {
/* /*
...@@ -227,11 +153,6 @@ 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); 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; static unsigned long *at91_extern_irq;
u32 at91_get_extern_irq(void) u32 at91_get_extern_irq(void)
...@@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) ...@@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
if (srctype < 0) if (srctype < 0)
return srctype; return srctype;
if (has_aic5()) { smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
at91_aic_write(AT91_AIC5_SSR, at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
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);
}
return 0; return 0;
} }
...@@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector) ...@@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector)
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); 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. * Initialize the AIC interrupt controller.
*/ */
......
...@@ -34,79 +34,8 @@ ...@@ -34,79 +34,8 @@
#include "pm.h" #include "pm.h"
#include "gpio.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 (*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) static int at91_pm_valid_state(suspend_state_t state)
{ {
switch (state) { switch (state) {
...@@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state)
at91_pinctrl_gpio_suspend(); at91_pinctrl_gpio_suspend();
else else
at91_gpio_suspend(); at91_gpio_suspend();
at91_irq_suspend();
pr_debug("AT91: PM - wake mask %08x, pm state %d\n", if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) {
/* remember all the always-wake irqs */ at91_irq_suspend();
(at91_pmc_read(AT91_PMC_PCSR)
| (1 << AT91_ID_FIQ) pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
| (1 << AT91_ID_SYS) /* remember all the always-wake irqs */
| (at91_get_extern_irq())) (at91_pmc_read(AT91_PMC_PCSR)
& at91_aic_read(AT91_AIC_IMR), | (1 << AT91_ID_FIQ)
state); | (1 << AT91_ID_SYS)
| (at91_get_extern_irq()))
& at91_aic_read(AT91_AIC_IMR),
state);
}
switch (state) { switch (state) {
/* /*
...@@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state)
goto error; goto error;
} }
pr_debug("AT91: PM - wakeup %08x\n", if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); pr_debug("AT91: PM - wakeup %08x\n",
at91_aic_read(AT91_AIC_IPR) &
at91_aic_read(AT91_AIC_IMR));
error: error:
target_state = PM_SUSPEND_ON; 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()) if (of_have_populated_dt())
at91_pinctrl_gpio_resume(); at91_pinctrl_gpio_resume();
else else
...@@ -338,7 +275,6 @@ static int __init at91_pm_init(void) ...@@ -338,7 +275,6 @@ static int __init at91_pm_init(void)
suspend_set_ops(&at91_pm_ops); suspend_set_ops(&at91_pm_ops);
show_reset_status();
return 0; return 0;
} }
arch_initcall(at91_pm_init); arch_initcall(at91_pm_init);
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* Under GPLv2 * Under GPLv2
*/ */
#define pr_fmt(fmt) "AT91: " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -20,7 +22,6 @@ ...@@ -20,7 +22,6 @@
#include <mach/cpu.h> #include <mach/cpu.h>
#include <mach/at91_dbgu.h> #include <mach/at91_dbgu.h>
#include "at91_shdwc.h"
#include "soc.h" #include "soc.h"
#include "generic.h" #include "generic.h"
#include "pm.h" #include "pm.h"
...@@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type) ...@@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type)
else else
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; 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)); at91_get_soc_subtype(&at91_soc_initdata));
} }
...@@ -49,7 +50,8 @@ void __init at91_init_irq_default(void) ...@@ -49,7 +50,8 @@ void __init at91_init_irq_default(void)
void __init at91_init_interrupts(unsigned int *priority) void __init at91_init_interrupts(unsigned int *priority)
{ {
/* Initialize the AIC interrupt controller */ /* 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 */ /* Enable GPIO interrupts */
at91_gpio_irq_setup(); at91_gpio_irq_setup();
...@@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size) ...@@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
} }
at91_ramc_base[id] = ioremap(addr, size); at91_ramc_base[id] = ioremap(addr, size);
if (!at91_ramc_base[id]) 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; 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) ...@@ -83,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
desc->length = length; desc->length = length;
desc->type = MT_MEMORY_RWX_NONCACHED; 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); base, length, desc->virtual);
iotable_init(desc, 1); iotable_init(desc, 1);
...@@ -302,45 +304,21 @@ void __init at91_map_io(void) ...@@ -302,45 +304,21 @@ void __init at91_map_io(void)
soc_detect(AT91_BASE_DBGU1); soc_detect(AT91_BASE_DBGU1);
if (!at91_soc_is_detected()) 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)); at91_get_soc_type(&at91_soc_initdata));
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) 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)); at91_get_soc_subtype(&at91_soc_initdata));
if (!at91_soc_is_enabled()) if (!at91_soc_is_enabled())
panic("AT91: Soc not enabled"); panic(pr_fmt("Soc not enabled"));
if (at91_boot_soc.map_io) if (at91_boot_soc.map_io)
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; void __iomem *at91_matrix_base;
EXPORT_SYMBOL_GPL(at91_matrix_base); EXPORT_SYMBOL_GPL(at91_matrix_base);
...@@ -348,42 +326,15 @@ void __init at91_ioremap_matrix(u32 base_addr) ...@@ -348,42 +326,15 @@ void __init at91_ioremap_matrix(u32 base_addr)
{ {
at91_matrix_base = ioremap(base_addr, 512); at91_matrix_base = ioremap(base_addr, 512);
if (!at91_matrix_base) 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) #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[] = { static struct of_device_id ramc_ids[] = {
{ .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
{ .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
{ .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
{ /*sentinel*/ } { /*sentinel*/ }
}; };
...@@ -391,100 +342,29 @@ static void at91_dt_ramc(void) ...@@ -391,100 +342,29 @@ static void at91_dt_ramc(void)
{ {
struct device_node *np; struct device_node *np;
const struct of_device_id *of_id; const struct of_device_id *of_id;
int idx = 0;
const void *standby = NULL;
np = of_find_matching_node(NULL, ramc_ids); for_each_matching_node_and_match(np, ramc_ids, &of_id) {
if (!np) at91_ramc_base[idx] = of_iomap(np, 0);
panic("unable to find compatible ram controller node in dtb\n"); 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 (!standby)
if (!at91_ramc_base[0]) standby = of_id->data;
panic("unable to map ramc[0] cpu registers\n");
/* the controller may have 2 banks */
at91_ramc_base[1] = of_iomap(np, 1);
of_id = of_match_node(ramc_ids, np); idx++;
if (!of_id)
pr_warn("AT91: ramc no standby function available\n");
else
at91_pm_set_standby(of_id->data);
of_node_put(np);
}
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");
return;
} }
at91_shdwc_base = of_iomap(np, 0); if (!idx)
if (!at91_shdwc_base) panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
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 (!standby) {
if (reg > AT91_SHDW_CPTWK0_MAX) { pr_warn("ramc no standby function available\n");
pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n", return;
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")) at91_pm_set_standby(standby);
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);
} }
void __init at91rm9200_dt_initialize(void) void __init at91rm9200_dt_initialize(void)
...@@ -503,9 +383,7 @@ void __init at91rm9200_dt_initialize(void) ...@@ -503,9 +383,7 @@ void __init at91rm9200_dt_initialize(void)
void __init at91_dt_initialize(void) void __init at91_dt_initialize(void)
{ {
at91_dt_rstc();
at91_dt_ramc(); at91_dt_ramc();
at91_dt_shdwc();
/* Init clock subsystem */ /* Init clock subsystem */
at91_dt_clock_init(); at91_dt_clock_init();
...@@ -533,3 +411,8 @@ void __init at91_initialize(unsigned long main_clock) ...@@ -533,3 +411,8 @@ void __init at91_initialize(unsigned long main_clock)
pinctrl_provide_dummies(); pinctrl_provide_dummies();
} }
void __init at91_register_devices(void)
{
at91_boot_soc.register_devices();
}
...@@ -11,6 +11,7 @@ struct at91_init_soc { ...@@ -11,6 +11,7 @@ struct at91_init_soc {
void (*map_io)(void); void (*map_io)(void);
void (*ioremap_registers)(void); void (*ioremap_registers)(void);
void (*register_clocks)(void); void (*register_clocks)(void);
void (*register_devices)(void);
void (*init)(void); void (*init)(void);
}; };
......
...@@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name, ...@@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
init.ops = &system_ops; init.ops = &system_ops;
init.parent_names = &parent_name; init.parent_names = &parent_name;
init.num_parents = 1; init.num_parents = 1;
/* init.flags = CLK_SET_RATE_PARENT;
* 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;
sys->id = id; sys->id = id;
sys->hw.init = &init; sys->hw.init = &init;
......
...@@ -7,6 +7,16 @@ menuconfig MEMORY ...@@ -7,6 +7,16 @@ menuconfig MEMORY
if 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 config TI_AEMIF
tristate "Texas Instruments AEMIF driver" tristate "Texas Instruments AEMIF driver"
depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
ifeq ($(CONFIG_DDR),y) ifeq ($(CONFIG_DDR),y)
obj-$(CONFIG_OF) += of_memory.o obj-$(CONFIG_OF) += of_memory.o
endif endif
obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
......
/*
* 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");
...@@ -6,15 +6,33 @@ menuconfig POWER_RESET ...@@ -6,15 +6,33 @@ menuconfig POWER_RESET
Say Y here to enable board reset and power off Say Y here to enable board reset and power off
if POWER_RESET
config POWER_RESET_AS3722 config POWER_RESET_AS3722
bool "ams AS3722 power-off driver" bool "ams AS3722 power-off driver"
depends on MFD_AS3722 && POWER_RESET depends on MFD_AS3722
help help
This driver supports turning off board via a ams AS3722 power-off. 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 config POWER_RESET_AXXIA
bool "LSI Axxia reset driver" bool "LSI Axxia reset driver"
depends on POWER_RESET && ARCH_AXXIA depends on ARCH_AXXIA
help help
This driver supports restart for Axxia SoC. This driver supports restart for Axxia SoC.
...@@ -33,7 +51,7 @@ config POWER_RESET_BRCMSTB ...@@ -33,7 +51,7 @@ config POWER_RESET_BRCMSTB
config POWER_RESET_GPIO config POWER_RESET_GPIO
bool "GPIO power-off driver" bool "GPIO power-off driver"
depends on OF_GPIO && POWER_RESET depends on OF_GPIO
help help
This driver supports turning off your board via a GPIO line. 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 If your board needs a GPIO high/low to power down, say Y and
...@@ -47,13 +65,13 @@ config POWER_RESET_HISI ...@@ -47,13 +65,13 @@ config POWER_RESET_HISI
config POWER_RESET_MSM config POWER_RESET_MSM
bool "Qualcomm MSM power-off driver" bool "Qualcomm MSM power-off driver"
depends on POWER_RESET && ARCH_QCOM depends on ARCH_QCOM
help help
Power off and restart support for Qualcomm boards. Power off and restart support for Qualcomm boards.
config POWER_RESET_QNAP config POWER_RESET_QNAP
bool "QNAP power-off driver" bool "QNAP power-off driver"
depends on OF_GPIO && POWER_RESET && PLAT_ORION depends on OF_GPIO && PLAT_ORION
help help
This driver supports turning off QNAP NAS devices by sending This driver supports turning off QNAP NAS devices by sending
commands to the microcontroller which controls the main power. commands to the microcontroller which controls the main power.
...@@ -71,14 +89,13 @@ config POWER_RESET_RESTART ...@@ -71,14 +89,13 @@ config POWER_RESET_RESTART
config POWER_RESET_SUN6I config POWER_RESET_SUN6I
bool "Allwinner A31 SoC reset driver" bool "Allwinner A31 SoC reset driver"
depends on ARCH_SUNXI depends on ARCH_SUNXI
depends on POWER_RESET
help help
Reboot support for the Allwinner A31 SoCs. Reboot support for the Allwinner A31 SoCs.
config POWER_RESET_VEXPRESS config POWER_RESET_VEXPRESS
bool "ARM Versatile Express power-off and reset driver" bool "ARM Versatile Express power-off and reset driver"
depends on ARM || ARM64 depends on ARM || ARM64
depends on POWER_RESET && VEXPRESS_CONFIG depends on VEXPRESS_CONFIG
help help
Power off and reset support for the ARM Ltd. Versatile Power off and reset support for the ARM Ltd. Versatile
Express boards. Express boards.
...@@ -86,7 +103,6 @@ config POWER_RESET_VEXPRESS ...@@ -86,7 +103,6 @@ config POWER_RESET_VEXPRESS
config POWER_RESET_XGENE config POWER_RESET_XGENE
bool "APM SoC X-Gene reset driver" bool "APM SoC X-Gene reset driver"
depends on ARM64 depends on ARM64
depends on POWER_RESET
help help
Reboot support for the APM SoC X-Gene Eval boards. Reboot support for the APM SoC X-Gene Eval boards.
...@@ -97,3 +113,4 @@ config POWER_RESET_KEYSTONE ...@@ -97,3 +113,4 @@ config POWER_RESET_KEYSTONE
help help
Reboot support for the KEYSTONE SoCs. Reboot support for the KEYSTONE SoCs.
endif
obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o 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_AXXIA) += axxia-reset.o
obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
......
/*
* 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);
/*
* 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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment