Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
25e9b4db
Commit
25e9b4db
authored
Mar 06, 2003
by
Russell King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] Add better PM support to SA1111 and SA11x0.
This follows our existing PM interfaces.
parent
7725cb81
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
161 additions
and
74 deletions
+161
-74
arch/arm/common/sa1111.c
arch/arm/common/sa1111.c
+53
-49
arch/arm/mach-sa1100/irq.c
arch/arm/mach-sa1100/irq.c
+94
-1
arch/arm/mach-sa1100/pm.c
arch/arm/mach-sa1100/pm.c
+14
-24
No files found.
arch/arm/common/sa1111.c
View file @
25e9b4db
...
@@ -743,25 +743,23 @@ struct sa1111_save_data {
...
@@ -743,25 +743,23 @@ struct sa1111_save_data {
static
int
sa1111_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
static
int
sa1111_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
{
struct
sa1111
*
sachip
=
dev_get_drvdata
(
dev
);
struct
sa1111
*
sachip
=
dev_get_drvdata
(
dev
);
struct
sa1111_save_data
*
save
;
unsigned
long
flags
;
unsigned
long
flags
;
char
*
base
;
char
*
base
;
/*
if
(
!
dev
->
saved_state
&&
level
==
SUSPEND_NOTIFY
)
* Save state.
dev
->
saved_state
=
kmalloc
(
sizeof
(
struct
sa1111_save_data
),
GFP_KERNEL
);
*/
if
(
!
dev
->
saved_state
)
if
(
level
==
SUSPEND_SAVE_STATE
||
return
-
ENOMEM
;
level
==
SUSPEND_DISABLE
||
level
==
SUSPEND_POWER_DOWN
)
{
struct
sa1111_save_data
*
save
;
if
(
!
dev
->
saved_state
)
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
dev
->
saved_state
=
kmalloc
(
sizeof
(
struct
sa1111_save_data
),
GFP_KERNEL
);
if
(
!
dev
->
saved_state
)
return
-
ENOMEM
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
)
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
/*
* Save state.
*/
if
(
level
==
SUSPEND_SAVE_STATE
)
{
base
=
sachip
->
base
;
base
=
sachip
->
base
;
save
->
skcr
=
sa1111_readl
(
base
+
SA1111_SKCR
);
save
->
skcr
=
sa1111_readl
(
base
+
SA1111_SKCR
);
save
->
skpcr
=
sa1111_readl
(
base
+
SA1111_SKPCR
);
save
->
skpcr
=
sa1111_readl
(
base
+
SA1111_SKPCR
);
...
@@ -779,26 +777,21 @@ static int sa1111_suspend(struct device *dev, u32 state, u32 level)
...
@@ -779,26 +777,21 @@ static int sa1111_suspend(struct device *dev, u32 state, u32 level)
save
->
wakepol1
=
sa1111_readl
(
base
+
SA1111_WAKEPOL1
);
save
->
wakepol1
=
sa1111_readl
(
base
+
SA1111_WAKEPOL1
);
save
->
wakeen0
=
sa1111_readl
(
base
+
SA1111_WAKEEN0
);
save
->
wakeen0
=
sa1111_readl
(
base
+
SA1111_WAKEEN0
);
save
->
wakeen1
=
sa1111_readl
(
base
+
SA1111_WAKEEN1
);
save
->
wakeen1
=
sa1111_readl
(
base
+
SA1111_WAKEEN1
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
}
/*
/*
* Disable.
* Disable.
*/
*/
if
(
level
==
SUSPEND_DISABLE
&&
state
==
4
)
{
if
(
level
==
SUSPEND_POWER_DOWN
&&
state
==
4
)
{
unsigned
int
val
;
unsigned
int
val
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKCR
);
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
base
=
sachip
->
base
;
sa1111_writel
(
0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
val
|
SKCR_SLEEP
,
sachip
->
base
+
SA1111_SKCR
);
sa1111_writel
(
0
,
base
+
SA1111_SKPWM1
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_SKPWM0
);
val
=
sa1111_readl
(
base
+
SA1111_SKCR
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_SKPWM1
);
sa1111_writel
(
val
|
SKCR_SLEEP
,
base
+
SA1111_SKCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
}
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
return
0
;
return
0
;
}
}
...
@@ -819,17 +812,15 @@ static int sa1111_resume(struct device *dev, u32 level)
...
@@ -819,17 +812,15 @@ static int sa1111_resume(struct device *dev, u32 level)
unsigned
long
flags
,
id
;
unsigned
long
flags
,
id
;
char
*
base
;
char
*
base
;
if
(
level
!=
RESUME_RESTORE_STATE
&&
level
!=
RESUME_ENABLE
)
return
0
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
if
(
!
save
)
if
(
!
save
)
return
0
;
return
0
;
dev
->
saved_state
=
NULL
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
)
;
/*
/*
* Ensure that the SA1111 is still here.
* Ensure that the SA1111 is still here.
* FIXME: shouldn't do this here.
*/
*/
id
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKID
);
id
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKID
);
if
((
id
&
SKID_ID_MASK
)
!=
SKID_SA1111_ID
)
{
if
((
id
&
SKID_ID_MASK
)
!=
SKID_SA1111_ID
)
{
...
@@ -839,29 +830,42 @@ static int sa1111_resume(struct device *dev, u32 level)
...
@@ -839,29 +830,42 @@ static int sa1111_resume(struct device *dev, u32 level)
return
0
;
return
0
;
}
}
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
/*
sa1111_wake
(
sachip
);
* First of all, wake up the chip.
*/
if
(
level
==
RESUME_POWER_ON
)
{
sa1111_wake
(
sachip
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_INTC
+
SA1111_INTEN0
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_INTC
+
SA1111_INTEN1
);
}
if
(
level
==
RESUME_RESTORE_STATE
)
{
base
=
sachip
->
base
;
sa1111_writel
(
save
->
skcr
,
base
+
SA1111_SKCR
);
sa1111_writel
(
save
->
skpcr
,
base
+
SA1111_SKPCR
);
sa1111_writel
(
save
->
skcdr
,
base
+
SA1111_SKCDR
);
sa1111_writel
(
save
->
skaud
,
base
+
SA1111_SKAUD
);
sa1111_writel
(
save
->
skpwm0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
save
->
skpwm1
,
base
+
SA1111_SKPWM1
);
base
=
sachip
->
base
+
SA1111_INTC
;
sa1111_writel
(
save
->
intpol0
,
base
+
SA1111_INTPOL0
);
sa1111_writel
(
save
->
intpol1
,
base
+
SA1111_INTPOL1
);
sa1111_writel
(
save
->
inten0
,
base
+
SA1111_INTEN0
);
sa1111_writel
(
save
->
inten1
,
base
+
SA1111_INTEN1
);
sa1111_writel
(
save
->
wakepol0
,
base
+
SA1111_WAKEPOL0
);
sa1111_writel
(
save
->
wakepol1
,
base
+
SA1111_WAKEPOL1
);
sa1111_writel
(
save
->
wakeen0
,
base
+
SA1111_WAKEEN0
);
sa1111_writel
(
save
->
wakeen1
,
base
+
SA1111_WAKEEN1
);
}
base
=
sachip
->
base
;
sa1111_writel
(
save
->
skcr
,
base
+
SA1111_SKCR
);
sa1111_writel
(
save
->
skpcr
,
base
+
SA1111_SKPCR
);
sa1111_writel
(
save
->
skcdr
,
base
+
SA1111_SKCDR
);
sa1111_writel
(
save
->
skaud
,
base
+
SA1111_SKAUD
);
sa1111_writel
(
save
->
skpwm0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
save
->
skpwm1
,
base
+
SA1111_SKPWM1
);
base
=
sachip
->
base
+
SA1111_INTC
;
sa1111_writel
(
save
->
intpol0
,
base
+
SA1111_INTPOL0
);
sa1111_writel
(
save
->
intpol1
,
base
+
SA1111_INTPOL1
);
sa1111_writel
(
save
->
inten0
,
base
+
SA1111_INTEN0
);
sa1111_writel
(
save
->
inten1
,
base
+
SA1111_INTEN1
);
sa1111_writel
(
save
->
wakepol0
,
base
+
SA1111_WAKEPOL0
);
sa1111_writel
(
save
->
wakepol1
,
base
+
SA1111_WAKEPOL1
);
sa1111_writel
(
save
->
wakeen0
,
base
+
SA1111_WAKEEN0
);
sa1111_writel
(
save
->
wakeen1
,
base
+
SA1111_WAKEEN1
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
kfree
(
save
);
if
(
level
==
RESUME_ENABLE
)
{
dev
->
saved_state
=
NULL
;
kfree
(
save
);
}
return
0
;
return
0
;
}
}
...
...
arch/arm/mach-sa1100/irq.c
View file @
25e9b4db
...
@@ -68,7 +68,7 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
...
@@ -68,7 +68,7 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
}
}
/*
/*
* GPIO IRQs must be acknoledged. This is for IRQs from 0 to 10.
* GPIO IRQs must be ackno
w
ledged. This is for IRQs from 0 to 10.
*/
*/
static
void
sa1100_low_gpio_ack
(
unsigned
int
irq
)
static
void
sa1100_low_gpio_ack
(
unsigned
int
irq
)
{
{
...
@@ -211,6 +211,99 @@ static struct resource irq_resource = {
...
@@ -211,6 +211,99 @@ static struct resource irq_resource = {
.
end
=
0x9005ffff
,
.
end
=
0x9005ffff
,
};
};
struct
sa1100irq_state
{
unsigned
int
saved
;
unsigned
int
icmr
;
unsigned
int
iclr
;
unsigned
int
iccr
;
};
static
int
sa1100irq_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
struct
sa1100irq_state
*
st
;
if
(
!
dev
->
saved_state
&&
level
==
SUSPEND_NOTIFY
)
dev
->
saved_state
=
kmalloc
(
sizeof
(
struct
sa1100irq_state
),
GFP_KERNEL
);
if
(
!
dev
->
saved_state
)
return
-
ENOMEM
;
if
(
level
==
SUSPEND_POWER_DOWN
)
{
st
=
(
struct
sa1100irq_state
*
)
dev
->
saved_state
;
st
->
saved
=
1
;
st
->
icmr
=
ICMR
;
st
->
iclr
=
ICLR
;
st
->
iccr
=
ICCR
;
/*
* Disable all GPIO-based interrupts.
*/
ICMR
&=
~
(
IC_GPIO11_27
|
IC_GPIO10
|
IC_GPIO9
|
IC_GPIO8
|
IC_GPIO7
|
IC_GPIO6
|
IC_GPIO5
|
IC_GPIO4
|
IC_GPIO3
|
IC_GPIO2
|
IC_GPIO1
|
IC_GPIO0
);
/*
* Set the appropriate edges for wakeup.
*/
GRER
=
PWER
&
GPIO_IRQ_rising_edge
;
GFER
=
PWER
&
GPIO_IRQ_falling_edge
;
/*
* Clear any pending GPIO interrupts.
*/
GEDR
=
GEDR
;
}
return
0
;
}
static
int
sa1100irq_resume
(
struct
device
*
dev
,
u32
level
)
{
struct
sa1100irq_state
*
st
;
if
(
level
==
RESUME_POWER_ON
)
{
st
=
(
struct
sa1100irq_state
*
)
dev
->
saved_state
;
dev
->
saved_state
=
NULL
;
if
(
st
->
saved
)
{
ICCR
=
st
->
iccr
;
ICLR
=
st
->
iclr
;
GRER
=
GPIO_IRQ_rising_edge
&
GPIO_IRQ_mask
;
GFER
=
GPIO_IRQ_falling_edge
&
GPIO_IRQ_mask
;
ICMR
=
st
->
icmr
;
}
kfree
(
st
);
}
return
0
;
}
static
struct
device_driver
sa1100irq_driver
=
{
.
name
=
"sa11x0-irq"
,
.
bus
=
&
system_bus_type
,
.
suspend
=
sa1100irq_suspend
,
.
resume
=
sa1100irq_resume
,
};
static
struct
sys_device
sa1100irq_device
=
{
.
name
=
"irq"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"Intel SA11x0 [Interrupt Controller]"
,
.
driver
=
&
sa1100irq_driver
,
},
};
static
int
__init
sa1100irq_init_devicefs
(
void
)
{
driver_register
(
&
sa1100irq_driver
);
return
sys_device_register
(
&
sa1100irq_device
);
}
device_initcall
(
sa1100irq_init_devicefs
);
void
__init
sa1100_init_irq
(
void
)
void
__init
sa1100_init_irq
(
void
)
{
{
unsigned
int
irq
;
unsigned
int
irq
;
...
...
arch/arm/mach-sa1100/pm.c
View file @
25e9b4db
...
@@ -45,10 +45,9 @@ enum { SLEEP_SAVE_SP = 0,
...
@@ -45,10 +45,9 @@ enum { SLEEP_SAVE_SP = 0,
SLEEP_SAVE_OSCR
,
SLEEP_SAVE_OIER
,
SLEEP_SAVE_OSCR
,
SLEEP_SAVE_OIER
,
SLEEP_SAVE_OSMR0
,
SLEEP_SAVE_OSMR1
,
SLEEP_SAVE_OSMR2
,
SLEEP_SAVE_OSMR3
,
SLEEP_SAVE_OSMR0
,
SLEEP_SAVE_OSMR1
,
SLEEP_SAVE_OSMR2
,
SLEEP_SAVE_OSMR3
,
SLEEP_SAVE_GPDR
,
SLEEP_SAVE_G
RER
,
SLEEP_SAVE_GFER
,
SLEEP_SAVE_G
AFR
,
SLEEP_SAVE_GPDR
,
SLEEP_SAVE_GAFR
,
SLEEP_SAVE_PPDR
,
SLEEP_SAVE_PPSR
,
SLEEP_SAVE_PPAR
,
SLEEP_SAVE_PSDR
,
SLEEP_SAVE_PPDR
,
SLEEP_SAVE_PPSR
,
SLEEP_SAVE_PPAR
,
SLEEP_SAVE_PSDR
,
SLEEP_SAVE_ICMR
,
SLEEP_SAVE_Ser1SDCR0
,
SLEEP_SAVE_Ser1SDCR0
,
SLEEP_SAVE_SIZE
SLEEP_SAVE_SIZE
...
@@ -71,8 +70,6 @@ int pm_do_suspend(void)
...
@@ -71,8 +70,6 @@ int pm_do_suspend(void)
SAVE
(
OIER
);
SAVE
(
OIER
);
SAVE
(
GPDR
);
SAVE
(
GPDR
);
SAVE
(
GRER
);
SAVE
(
GFER
);
SAVE
(
GAFR
);
SAVE
(
GAFR
);
SAVE
(
PPDR
);
SAVE
(
PPDR
);
...
@@ -82,13 +79,6 @@ int pm_do_suspend(void)
...
@@ -82,13 +79,6 @@ int pm_do_suspend(void)
SAVE
(
Ser1SDCR0
);
SAVE
(
Ser1SDCR0
);
SAVE
(
ICMR
);
/* ... maybe a global variable initialized by arch code to set this? */
GRER
=
PWER
;
GFER
=
0
;
GEDR
=
GEDR
;
/* Clear previous reset status */
/* Clear previous reset status */
RCSR
=
RCSR_HWR
|
RCSR_SWR
|
RCSR_WDR
|
RCSR_SMR
;
RCSR
=
RCSR_HWR
|
RCSR_SWR
|
RCSR_WDR
|
RCSR_SMR
;
...
@@ -98,22 +88,23 @@ int pm_do_suspend(void)
...
@@ -98,22 +88,23 @@ int pm_do_suspend(void)
/* go zzz */
/* go zzz */
sa1100_cpu_suspend
();
sa1100_cpu_suspend
();
/* ensure not to come back here if it wasn't intended */
/*
* Ensure not to come back here if it wasn't intended
*/
PSPR
=
0
;
PSPR
=
0
;
#ifdef DEBUG
/*
printk
(
KERN_DEBUG
"*** made it back from resume
\n
"
);
* Ensure interrupt sources are disabled; we will re-init
#endif
* the interrupt subsystem via the device manager.
*/
ICLR
=
0
;
ICCR
=
1
;
ICMR
=
0
;
/* restore registers */
/* restore registers */
RESTORE
(
GPDR
);
RESTORE
(
GPDR
);
RESTORE
(
GRER
);
RESTORE
(
GFER
);
RESTORE
(
GAFR
);
RESTORE
(
GAFR
);
/* clear any edge detect bit */
GEDR
=
GEDR
;
RESTORE
(
PPDR
);
RESTORE
(
PPDR
);
RESTORE
(
PPSR
);
RESTORE
(
PPSR
);
RESTORE
(
PPAR
);
RESTORE
(
PPAR
);
...
@@ -121,6 +112,9 @@ int pm_do_suspend(void)
...
@@ -121,6 +112,9 @@ int pm_do_suspend(void)
RESTORE
(
Ser1SDCR0
);
RESTORE
(
Ser1SDCR0
);
/*
* Clear the peripheral sleep-hold bit.
*/
PSSR
=
PSSR_PH
;
PSSR
=
PSSR_PH
;
RESTORE
(
OSMR0
);
RESTORE
(
OSMR0
);
...
@@ -130,10 +124,6 @@ int pm_do_suspend(void)
...
@@ -130,10 +124,6 @@ int pm_do_suspend(void)
RESTORE
(
OSCR
);
RESTORE
(
OSCR
);
RESTORE
(
OIER
);
RESTORE
(
OIER
);
ICLR
=
0
;
ICCR
=
1
;
RESTORE
(
ICMR
);
/* restore current time */
/* restore current time */
xtime
.
tv_sec
=
RCNR
;
xtime
.
tv_sec
=
RCNR
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment