forked from Minki/linux
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:
commit
6ce041aba3
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -87,6 +87,8 @@
|
||||
ramc0: ramc@ffffe800 {
|
||||
compatible = "atmel,at91sam9g45-ddramc";
|
||||
reg = <0xffffe800 0x200>;
|
||||
clocks = <&ddrck>;
|
||||
clock-names = "ddrck";
|
||||
};
|
||||
|
||||
pmc: pmc@fffffc00 {
|
||||
|
@ -95,6 +95,8 @@
|
||||
ramc0: ramc@ffffe800 {
|
||||
compatible = "atmel,at91sam9g45-ddramc";
|
||||
reg = <0xffffe800 0x200>;
|
||||
clocks = <&ddrck>;
|
||||
clock-names = "ddrck";
|
||||
};
|
||||
|
||||
pmc: pmc@fffffc00 {
|
||||
|
@ -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>;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 .
|
@ -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
|
||||
|
@ -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 .
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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", ®)) {
|
||||
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();
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
98
drivers/memory/atmel-sdramc.c
Normal file
98
drivers/memory/atmel-sdramc.c
Normal 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");
|
@ -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
|
||||
|
@ -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
|
||||
|
156
drivers/power/reset/at91-poweroff.c
Normal file
156
drivers/power/reset/at91-poweroff.c
Normal 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);
|
252
drivers/power/reset/at91-reset.c
Normal file
252
drivers/power/reset/at91-reset.c
Normal 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);
|
Loading…
Reference in New Issue
Block a user