Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
e902be56
Commit
e902be56
authored
Nov 27, 2008
by
Russell King
Committed by
Russell King
Nov 27, 2008
Browse files
Merge branches 'core' and 'clks' into devel
parents
c750815e
5e1dbdb4
Changes
44
Hide whitespace changes
Inline
Side-by-side
arch/arm/Kconfig
View file @
e902be56
...
...
@@ -211,6 +211,7 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARM_AMBA
select HAVE_CLK
select COMMON_CLKDEV
select ICST525
help
Support for ARM's Integrator platform.
...
...
@@ -219,6 +220,7 @@ config ARCH_REALVIEW
bool "ARM Ltd. RealView family"
select ARM_AMBA
select HAVE_CLK
select COMMON_CLKDEV
select ICST307
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
...
...
@@ -230,6 +232,7 @@ config ARCH_VERSATILE
select ARM_AMBA
select ARM_VIC
select HAVE_CLK
select COMMON_CLKDEV
select ICST307
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
...
...
@@ -477,6 +480,7 @@ config ARCH_PXA
select ARCH_MTD_XIP
select GENERIC_GPIO
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
...
...
arch/arm/common/Kconfig
View file @
e902be56
...
...
@@ -33,3 +33,6 @@ config SHARPSL_PM
config SHARP_SCOOP
bool
config COMMON_CLKDEV
bool
arch/arm/common/Makefile
View file @
e902be56
...
...
@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000)
+=
uengine.o
obj-$(CONFIG_ARCH_IXP23XX)
+=
uengine.o
obj-$(CONFIG_PCI_HOST_ITE8152)
+=
it8152.o
obj-$(CONFIG_COMMON_CLKDEV)
+=
clkdev.o
arch/arm/common/clkdev.c
0 → 100644
View file @
e902be56
/*
* arch/arm/common/clkdev.c
*
* Copyright (C) 2008 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Helper for the clk API to assist looking up a struct clk.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
static
LIST_HEAD
(
clocks
);
static
DEFINE_MUTEX
(
clocks_mutex
);
static
struct
clk
*
clk_find
(
const
char
*
dev_id
,
const
char
*
con_id
)
{
struct
clk_lookup
*
p
;
struct
clk
*
clk
=
NULL
;
int
match
,
best
=
0
;
list_for_each_entry
(
p
,
&
clocks
,
node
)
{
if
((
p
->
dev_id
&&
!
dev_id
)
||
(
p
->
con_id
&&
!
con_id
))
continue
;
match
=
0
;
if
(
p
->
dev_id
)
match
+=
2
*
(
strcmp
(
p
->
dev_id
,
dev_id
)
==
0
);
if
(
p
->
con_id
)
match
+=
1
*
(
strcmp
(
p
->
con_id
,
con_id
)
==
0
);
if
(
match
==
0
)
continue
;
if
(
match
>
best
)
{
clk
=
p
->
clk
;
best
=
match
;
}
}
return
clk
;
}
struct
clk
*
clk_get
(
struct
device
*
dev
,
const
char
*
con_id
)
{
const
char
*
dev_id
=
dev
?
dev_name
(
dev
)
:
NULL
;
struct
clk
*
clk
;
mutex_lock
(
&
clocks_mutex
);
clk
=
clk_find
(
dev_id
,
con_id
);
if
(
clk
&&
!
__clk_get
(
clk
))
clk
=
NULL
;
mutex_unlock
(
&
clocks_mutex
);
return
clk
?
clk
:
ERR_PTR
(
-
ENOENT
);
}
EXPORT_SYMBOL
(
clk_get
);
void
clk_put
(
struct
clk
*
clk
)
{
__clk_put
(
clk
);
}
EXPORT_SYMBOL
(
clk_put
);
void
clkdev_add
(
struct
clk_lookup
*
cl
)
{
mutex_lock
(
&
clocks_mutex
);
list_add_tail
(
&
cl
->
node
,
&
clocks
);
mutex_unlock
(
&
clocks_mutex
);
}
EXPORT_SYMBOL
(
clkdev_add
);
#define MAX_DEV_ID 20
#define MAX_CON_ID 16
struct
clk_lookup_alloc
{
struct
clk_lookup
cl
;
char
dev_id
[
MAX_DEV_ID
];
char
con_id
[
MAX_CON_ID
];
};
struct
clk_lookup
*
clkdev_alloc
(
struct
clk
*
clk
,
const
char
*
con_id
,
const
char
*
dev_fmt
,
...)
{
struct
clk_lookup_alloc
*
cla
;
cla
=
kzalloc
(
sizeof
(
*
cla
),
GFP_KERNEL
);
if
(
!
cla
)
return
NULL
;
cla
->
cl
.
clk
=
clk
;
if
(
con_id
)
{
strlcpy
(
cla
->
con_id
,
con_id
,
sizeof
(
cla
->
con_id
));
cla
->
cl
.
con_id
=
cla
->
con_id
;
}
if
(
dev_fmt
)
{
va_list
ap
;
va_start
(
ap
,
dev_fmt
);
vscnprintf
(
cla
->
dev_id
,
sizeof
(
cla
->
dev_id
),
dev_fmt
,
ap
);
cla
->
cl
.
dev_id
=
cla
->
dev_id
;
va_end
(
ap
);
}
return
&
cla
->
cl
;
}
EXPORT_SYMBOL
(
clkdev_alloc
);
/*
* clkdev_drop - remove a clock dynamically allocated
*/
void
clkdev_drop
(
struct
clk_lookup
*
cl
)
{
mutex_lock
(
&
clocks_mutex
);
list_del
(
&
cl
->
node
);
mutex_unlock
(
&
clocks_mutex
);
kfree
(
cl
);
}
EXPORT_SYMBOL
(
clkdev_drop
);
arch/arm/include/asm/clkdev.h
0 → 100644
View file @
e902be56
/*
* arch/arm/include/asm/clkdev.h
*
* Copyright (C) 2008 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Helper for the clk API to assist looking up a struct clk.
*/
#ifndef __ASM_CLKDEV_H
#define __ASM_CLKDEV_H
struct
clk
;
struct
clk_lookup
{
struct
list_head
node
;
const
char
*
dev_id
;
const
char
*
con_id
;
struct
clk
*
clk
;
};
struct
clk_lookup
*
clkdev_alloc
(
struct
clk
*
clk
,
const
char
*
con_id
,
const
char
*
dev_fmt
,
...);
void
clkdev_add
(
struct
clk_lookup
*
cl
);
void
clkdev_drop
(
struct
clk_lookup
*
cl
);
#endif
arch/arm/mach-integrator/clock.c
View file @
e902be56
...
...
@@ -10,42 +10,12 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <asm/hardware/icst525.h>
#include "clock.h"
static
LIST_HEAD
(
clocks
);
static
DEFINE_MUTEX
(
clocks_mutex
);
struct
clk
*
clk_get
(
struct
device
*
dev
,
const
char
*
id
)
{
struct
clk
*
p
,
*
clk
=
ERR_PTR
(
-
ENOENT
);
mutex_lock
(
&
clocks_mutex
);
list_for_each_entry
(
p
,
&
clocks
,
node
)
{
if
(
strcmp
(
id
,
p
->
name
)
==
0
&&
try_module_get
(
p
->
owner
))
{
clk
=
p
;
break
;
}
}
mutex_unlock
(
&
clocks_mutex
);
return
clk
;
}
EXPORT_SYMBOL
(
clk_get
);
void
clk_put
(
struct
clk
*
clk
)
{
module_put
(
clk
->
owner
);
}
EXPORT_SYMBOL
(
clk_put
);
#include <asm/clkdev.h>
#include <mach/clkdev.h>
int
clk_enable
(
struct
clk
*
clk
)
{
...
...
@@ -67,7 +37,6 @@ EXPORT_SYMBOL(clk_get_rate);
long
clk_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
struct
icst525_vco
vco
;
vco
=
icst525_khz_to_vco
(
clk
->
params
,
rate
/
1000
);
return
icst525_khz
(
clk
->
params
,
vco
)
*
1000
;
}
...
...
@@ -76,56 +45,15 @@ EXPORT_SYMBOL(clk_round_rate);
int
clk_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
int
ret
=
-
EIO
;
if
(
clk
->
setvco
)
{
struct
icst525_vco
vco
;
vco
=
icst525_khz_to_vco
(
clk
->
params
,
rate
/
1000
);
clk
->
rate
=
icst525_khz
(
clk
->
params
,
vco
)
*
1000
;
printk
(
"Clock %s: setting VCO reg params: S=%d R=%d V=%d
\n
"
,
clk
->
name
,
vco
.
s
,
vco
.
r
,
vco
.
v
);
clk
->
setvco
(
clk
,
vco
);
ret
=
0
;
}
return
0
;
return
ret
;
}
EXPORT_SYMBOL
(
clk_set_rate
);
/*
* These are fixed clocks.
*/
static
struct
clk
kmi_clk
=
{
.
name
=
"KMIREFCLK"
,
.
rate
=
24000000
,
};
static
struct
clk
uart_clk
=
{
.
name
=
"UARTCLK"
,
.
rate
=
14745600
,
};
int
clk_register
(
struct
clk
*
clk
)
{
mutex_lock
(
&
clocks_mutex
);
list_add
(
&
clk
->
node
,
&
clocks
);
mutex_unlock
(
&
clocks_mutex
);
return
0
;
}
EXPORT_SYMBOL
(
clk_register
);
void
clk_unregister
(
struct
clk
*
clk
)
{
mutex_lock
(
&
clocks_mutex
);
list_del
(
&
clk
->
node
);
mutex_unlock
(
&
clocks_mutex
);
}
EXPORT_SYMBOL
(
clk_unregister
);
static
int
__init
clk_init
(
void
)
{
clk_register
(
&
kmi_clk
);
clk_register
(
&
uart_clk
);
return
0
;
}
arch_initcall
(
clk_init
);
arch/arm/mach-integrator/clock.h
View file @
e902be56
/*
* linux/arch/arm/mach-integrator/clock.h
*
* Copyright (C) 2004 ARM Limited.
* Written by Deep Blue Solutions Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
struct
module
;
struct
icst525_params
;
struct
clk
{
struct
list_head
node
;
unsigned
long
rate
;
struct
module
*
owner
;
const
char
*
name
;
const
struct
icst525_params
*
params
;
void
*
data
;
void
(
*
setvco
)(
struct
clk
*
,
struct
icst525_vco
vco
);
};
int
clk_register
(
struct
clk
*
clk
);
void
clk_unregister
(
struct
clk
*
clk
);
arch/arm/mach-integrator/core.c
View file @
e902be56
...
...
@@ -21,6 +21,8 @@
#include <linux/amba/serial.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/arm_timer.h>
...
...
@@ -108,10 +110,43 @@ static struct amba_device *amba_devs[] __initdata = {
&
kmi1_device
,
};
/*
* These are fixed clocks.
*/
static
struct
clk
clk24mhz
=
{
.
rate
=
24000000
,
};
static
struct
clk
uartclk
=
{
.
rate
=
14745600
,
};
static
struct
clk_lookup
lookups
[]
__initdata
=
{
{
/* UART0 */
.
dev_id
=
"mb:16"
,
.
clk
=
&
uartclk
,
},
{
/* UART1 */
.
dev_id
=
"mb:17"
,
.
clk
=
&
uartclk
,
},
{
/* KMI0 */
.
dev_id
=
"mb:18"
,
.
clk
=
&
clk24mhz
,
},
{
/* KMI1 */
.
dev_id
=
"mb:19"
,
.
clk
=
&
clk24mhz
,
},
{
/* MMCI - IntegratorCP */
.
dev_id
=
"mb:1c"
,
.
clk
=
&
uartclk
,
}
};
static
int
__init
integrator_init
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
lookups
);
i
++
)
clkdev_add
(
&
lookups
[
i
]);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
amba_devs
);
i
++
)
{
struct
amba_device
*
d
=
amba_devs
[
i
];
amba_device_register
(
d
,
&
iomem_resource
);
...
...
arch/arm/mach-integrator/impd1.c
View file @
e902be56
...
...
@@ -22,13 +22,13 @@
#include <linux/amba/clcd.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <asm/hardware/icst525.h>
#include <mach/lm.h>
#include <mach/impd1.h>
#include <asm/sizes.h>
#include "clock.h"
static
int
module_id
;
module_param_named
(
lmid
,
module_id
,
int
,
0444
);
...
...
@@ -37,6 +37,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct
impd1_module
{
void
__iomem
*
base
;
struct
clk
vcos
[
2
];
struct
clk_lookup
*
clks
[
3
];
};
static
const
struct
icst525_params
impd1_vco_params
=
{
...
...
@@ -339,9 +340,8 @@ static struct impd1_device impd1_devs[] = {
}
};
static
const
char
*
impd1_vconames
[
2
]
=
{
"CLCDCLK"
,
"AUXVCO2"
,
static
struct
clk
fixed_14745600
=
{
.
rate
=
14745600
,
};
static
int
impd1_probe
(
struct
lm_device
*
dev
)
...
...
@@ -374,14 +374,20 @@ static int impd1_probe(struct lm_device *dev)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
impd1
->
vcos
);
i
++
)
{
impd1
->
vcos
[
i
].
owner
=
THIS_MODULE
,
impd1
->
vcos
[
i
].
name
=
impd1_vconames
[
i
],
impd1
->
vcos
[
i
].
params
=
&
impd1_vco_params
,
impd1
->
vcos
[
i
].
data
=
impd1
,
impd1
->
vcos
[
i
].
setvco
=
impd1_setvco
;
clk_register
(
&
impd1
->
vcos
[
i
]);
}
impd1
->
clks
[
0
]
=
clkdev_alloc
(
&
impd1
->
vcos
[
0
],
NULL
,
"lm%x:01000"
,
dev
->
id
);
impd1
->
clks
[
1
]
=
clkdev_alloc
(
&
fixed_14745600
,
NULL
,
"lm%x:00100"
,
dev
->
id
);
impd1
->
clks
[
2
]
=
clkdev_alloc
(
&
fixed_14745600
,
NULL
,
"lm%x:00200"
,
dev
->
id
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
impd1
->
clks
);
i
++
)
clkdev_add
(
impd1
->
clks
[
i
]);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
impd1_devs
);
i
++
)
{
struct
impd1_device
*
idev
=
impd1_devs
+
i
;
struct
amba_device
*
d
;
...
...
@@ -434,8 +440,8 @@ static void impd1_remove(struct lm_device *dev)
device_for_each_child
(
&
dev
->
dev
,
NULL
,
impd1_remove_one
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
impd1
->
vco
s
);
i
++
)
clk
_unregister
(
&
impd1
->
vco
s
[
i
]);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
impd1
->
clk
s
);
i
++
)
clk
dev_drop
(
impd1
->
clk
s
[
i
]);
lm_set_drvdata
(
dev
,
NULL
);
...
...
arch/arm/mach-integrator/include/mach/clkdev.h
0 → 100644
View file @
e902be56
#ifndef __ASM_MACH_CLKDEV_H
#define __ASM_MACH_CLKDEV_H
#include <linux/module.h>
#include <asm/hardware/icst525.h>
struct
clk
{
unsigned
long
rate
;
struct
module
*
owner
;
const
struct
icst525_params
*
params
;
void
*
data
;
void
(
*
setvco
)(
struct
clk
*
,
struct
icst525_vco
vco
);
};
static
inline
int
__clk_get
(
struct
clk
*
clk
)
{
return
try_module_get
(
clk
->
owner
);
}
static
inline
void
__clk_put
(
struct
clk
*
clk
)
{
module_put
(
clk
->
owner
);
}
#endif
arch/arm/mach-integrator/integrator_cp.c
View file @
e902be56
...
...
@@ -21,6 +21,8 @@
#include <linux/amba/clcd.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/setup.h>
...
...
@@ -38,7 +40,6 @@
#include <asm/mach/time.h>
#include "common.h"
#include "clock.h"
#define INTCP_PA_MMC_BASE 0x1c000000
#define INTCP_PA_AACI_BASE 0x1d000000
...
...
@@ -289,15 +290,16 @@ static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
writel
(
0
,
CM_LOCK
);
}
static
struct
clk
cp_clcd_clk
=
{
.
name
=
"CLCDCLK"
,
static
struct
clk
cp_auxclk
=
{
.
params
=
&
cp_auxvco_params
,
.
setvco
=
cp_auxvco_set
,
};
static
struct
clk
cp_mmci_clk
=
{
.
name
=
"MCLK"
,
.
rate
=
14745600
,
static
struct
clk_lookup
cp_lookups
[]
=
{
{
/* CLCD */
.
dev_id
=
"mb:c0"
,
.
clk
=
&
cp_auxclk
,
},
};
/*
...
...
@@ -554,8 +556,8 @@ static void __init intcp_init(void)
{
int
i
;
clk_register
(
&
cp_clcd_clk
);
clk
_register
(
&
cp_mmci_clk
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cp_lookups
);
i
++
)
clk
dev_add
(
&
cp_lookups
[
i
]
);
platform_add_devices
(
intcp_devs
,
ARRAY_SIZE
(
intcp_devs
));
...
...
arch/arm/mach-pxa/clock.c
View file @
e902be56
...
...
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <asm/clkdev.h>
#include <mach/pxa2xx-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <mach/hardware.h>
...
...
@@ -20,45 +21,8 @@
#include "generic.h"
#include "clock.h"
static
LIST_HEAD
(
clocks
);
static
DEFINE_MUTEX
(
clocks_mutex
);
static
DEFINE_SPINLOCK
(
clocks_lock
);
static
struct
clk
*
clk_lookup
(
struct
device
*
dev
,
const
char
*
id
)
{
struct
clk
*
p
;
list_for_each_entry
(
p
,
&
clocks
,
node
)
if
(
strcmp
(
id
,
p
->
name
)
==
0
&&
p
->
dev
==
dev
)
return
p
;
return
NULL
;
}
struct
clk
*
clk_get
(
struct
device
*
dev
,
const
char
*
id
)
{
struct
clk
*
p
,
*
clk
=
ERR_PTR
(
-
ENOENT
);
mutex_lock
(
&
clocks_mutex
);
p
=
clk_lookup
(
dev
,
id
);
if
(
!
p
)
p
=
clk_lookup
(
NULL
,
id
);
if
(
p
)
clk
=
p
;
mutex_unlock
(
&
clocks_mutex
);
if
(
!
IS_ERR
(
clk
)
&&
clk
->
ops
==
NULL
)
clk
=
clk
->
other
;
return
clk
;
}
EXPORT_SYMBOL
(
clk_get
);
void
clk_put
(
struct
clk
*
clk
)
{
}
EXPORT_SYMBOL
(
clk_put
);
int
clk_enable
(
struct
clk
*
clk
)
{
unsigned
long
flags
;
...
...
@@ -116,37 +80,27 @@ const struct clkops clk_cken_ops = {
.
disable
=
clk_cken_disable
,
};
void
clks_register
(
struct
clk
*
clks
,
size_t
num
)
void
clks_register
(
struct
clk
_lookup
*
clks
,
size_t
num
)
{
int
i
;
mutex_lock
(
&
clocks_mutex
);
for
(
i
=
0
;
i
<
num
;
i
++
)
list_add
(
&
clks
[
i
].
node
,
&
clocks
);
mutex_unlock
(
&
clocks_mutex
);
clkdev_add
(
&
clks
[
i
]);
}
int
clk_add_alias
(
char
*
alias
,
struct
device
*
alias_dev
,
char
*
id
,
struct
device
*
dev
)
{
struct
clk
*
r
=
clk_
lookup
(
dev
,
id
);
struct
clk
*
new
;
struct
clk
*
r
=
clk_
get
(
dev
,
id
);
struct
clk
_lookup
*
l
;
if
(
!
r
)
return
-
ENODEV
;