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
nexedi
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 {
static
int
sa1111_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
struct
sa1111
*
sachip
=
dev_get_drvdata
(
dev
);
struct
sa1111_save_data
*
save
;
unsigned
long
flags
;
char
*
base
;
/*
* Save state.
*/
if
(
level
==
SUSPEND_SAVE_STATE
||
level
==
SUSPEND_DISABLE
||
level
==
SUSPEND_POWER_DOWN
)
{
struct
sa1111_save_data
*
save
;
if
(
!
dev
->
saved_state
&&
level
==
SUSPEND_NOTIFY
)
dev
->
saved_state
=
kmalloc
(
sizeof
(
struct
sa1111_save_data
),
GFP_KERNEL
);
if
(
!
dev
->
saved_state
)
return
-
ENOMEM
;
if
(
!
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
;
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
;
save
->
skcr
=
sa1111_readl
(
base
+
SA1111_SKCR
);
save
->
skpcr
=
sa1111_readl
(
base
+
SA1111_SKPCR
);
...
...
@@ -779,26 +777,21 @@ static int sa1111_suspend(struct device *dev, u32 state, u32 level)
save
->
wakepol1
=
sa1111_readl
(
base
+
SA1111_WAKEPOL1
);
save
->
wakeen0
=
sa1111_readl
(
base
+
SA1111_WAKEEN0
);
save
->
wakeen1
=
sa1111_readl
(
base
+
SA1111_WAKEEN1
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/*
* Disable.
*/
if
(
level
==
SUSPEND_DISABLE
&&
state
==
4
)
{
unsigned
int
val
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
base
=
sachip
->
base
;
if
(
level
==
SUSPEND_POWER_DOWN
&&
state
==
4
)
{
unsigned
int
val
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKCR
);
sa1111_writel
(
0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
0
,
base
+
SA1111_SKPWM1
);
val
=
sa1111_readl
(
base
+
SA1111_SKCR
);
sa1111_writel
(
val
|
SKCR_SLEEP
,
base
+
SA1111_SKCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
sa1111_writel
(
val
|
SKCR_SLEEP
,
sachip
->
base
+
SA1111_SKCR
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_SKPWM0
);
sa1111_writel
(
0
,
sachip
->
base
+
SA1111_SKPWM1
);
}
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
return
0
;
}
...
...
@@ -819,17 +812,15 @@ static int sa1111_resume(struct device *dev, u32 level)
unsigned
long
flags
,
id
;
char
*
base
;
if
(
level
!=
RESUME_RESTORE_STATE
&&
level
!=
RESUME_ENABLE
)
return
0
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
if
(
!
save
)
return
0
;
dev
->
saved_state
=
NULL
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
)
;
/*
* Ensure that the SA1111 is still here.
* FIXME: shouldn't do this here.
*/
id
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKID
);
if
((
id
&
SKID_ID_MASK
)
!=
SKID_SA1111_ID
)
{
...
...
@@ -839,29 +830,42 @@ static int sa1111_resume(struct device *dev, u32 level)
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
);
kfree
(
save
);
if
(
level
==
RESUME_ENABLE
)
{
dev
->
saved_state
=
NULL
;
kfree
(
save
);
}
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)
}
/*
* 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
)
{
...
...
@@ -211,6 +211,99 @@ static struct resource irq_resource = {
.
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
)
{
unsigned
int
irq
;
...
...
arch/arm/mach-sa1100/pm.c
View file @
25e9b4db
...
...
@@ -45,10 +45,9 @@ enum { SLEEP_SAVE_SP = 0,
SLEEP_SAVE_OSCR
,
SLEEP_SAVE_OIER
,
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_ICMR
,
SLEEP_SAVE_Ser1SDCR0
,
SLEEP_SAVE_SIZE
...
...
@@ -71,8 +70,6 @@ int pm_do_suspend(void)
SAVE
(
OIER
);
SAVE
(
GPDR
);
SAVE
(
GRER
);
SAVE
(
GFER
);
SAVE
(
GAFR
);
SAVE
(
PPDR
);
...
...
@@ -82,13 +79,6 @@ int pm_do_suspend(void)
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 */
RCSR
=
RCSR_HWR
|
RCSR_SWR
|
RCSR_WDR
|
RCSR_SMR
;
...
...
@@ -98,22 +88,23 @@ int pm_do_suspend(void)
/* go zzz */
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
;
#ifdef DEBUG
printk
(
KERN_DEBUG
"*** made it back from resume
\n
"
);
#endif
/*
* Ensure interrupt sources are disabled; we will re-init
* the interrupt subsystem via the device manager.
*/
ICLR
=
0
;
ICCR
=
1
;
ICMR
=
0
;
/* restore registers */
RESTORE
(
GPDR
);
RESTORE
(
GRER
);
RESTORE
(
GFER
);
RESTORE
(
GAFR
);
/* clear any edge detect bit */
GEDR
=
GEDR
;
RESTORE
(
PPDR
);
RESTORE
(
PPSR
);
RESTORE
(
PPAR
);
...
...
@@ -121,6 +112,9 @@ int pm_do_suspend(void)
RESTORE
(
Ser1SDCR0
);
/*
* Clear the peripheral sleep-hold bit.
*/
PSSR
=
PSSR_PH
;
RESTORE
(
OSMR0
);
...
...
@@ -130,10 +124,6 @@ int pm_do_suspend(void)
RESTORE
(
OSCR
);
RESTORE
(
OIER
);
ICLR
=
0
;
ICCR
=
1
;
RESTORE
(
ICMR
);
/* restore current time */
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