diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 15:50:46 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 15:50:46 -0700 |
commit | 2ad7b44f5dd63a34c8853ce55f7d3d351b2cbd33 (patch) | |
tree | d4c029108af9d7f14044a340dacdb920f7c2b1b5 /arch | |
parent | 43c9fad942b5afb9e03801c0721d83160fa5b0dd (diff) | |
parent | 079ed3681d748523e50c3947ca59507a7a181260 (diff) |
Merge branch 'for-linus-clk' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull clkdev updates from Russell King:
"This series addresses some breakage in clkdev caused by a previous
patch set from the clk tree which introduced per-user clk structures.
This basically renamed the existing 'struct clk' to 'struct clk_hw',
and introduced a new 'struct clk'.
This change will break anyone using clk_add_alias() with the common
clk code enabled. Thankfully, the intersection of users of
clk_add_alias() and those using the common clk code is practically
zero, but this is something which should be fixed to keep the code
sane.
The problem is that clk_add_alias() does this:
r = clk_get(...);
l = clkdev_alloc(r, ...);
clk_put(...);
which causes the alias to store a pointer to 'r', which has been
freed.
The original patch set tried to work around this problem incorrectly -
at clk_get() time, it tried to convert the struct clk to a struct
clk_hw, and then creating a new struct clk from that. Clearly, if the
original struct clk has been freed, then we have a use-after-free bug.
We have other places in the tree which do something similar, so this
series also addresses those locations too.
This series addresses this problem by converting clkdev to store and
use the clk_hw pointer. This allows clk_get() to only have to create
it's per-user struct clk from the clk_hw. We can also get to the
desired clk_hw at clk_add_alias() or clk lookup creation time, when
the struct clk is "alive".
We also perform some cleanups of the code:
- replacing looped calls to clkdev_add() with clkdev_add_table()
- replacing open-coded lookup allocation (which should have been
using clkdev_alloc()) and subsequent clkdev_add() with
clkdev_create()
- replacing open-coded clk_add_alias() with clk_add_alias()"
* 'for-linus-clk' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
clk: s2mps11: use clkdev_create()
ASoC: migor: use clkdev_create()
ARM: omap2: use clkdev_add_alias()
ARM: omap2: use clkdev_create()
ARM: orion: use clkdev_create()
ARM: lpc32xx: convert to use clkdev_add_table()
SH: use clkdev_add_table()
clkdev: add clkdev_create() helper
clkdev: const-ify connection id to clk_add_alias()
clkdev: get rid of redundant clk_add_alias() prototype in linux/clk.h
clkdev: drop __init from clkdev_add_table()
clk: update clk API documentation to clarify clk_round_rate()
clkdev: use clk_hw internally
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-davinci/da850.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-lpc32xx/clock.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-nokia770.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_device.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-pxa/eseries.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/lubbock.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 1 | ||||
-rw-r--r-- | arch/arm/plat-orion/common.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7734.c | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-shx3.c | 4 |
14 files changed, 27 insertions, 45 deletions
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 45ce065e7170..3b8740c083c4 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -11,6 +11,7 @@ * is licensed "as is" without any warranty of any kind, whether express * or implied. */ +#include <linux/clkdev.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/clk.h> diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index dd5d6f532e8c..661c8f4b2310 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -1238,10 +1238,7 @@ static struct clk_lookup lookups[] = { static int __init clk_init(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); /* * Setup muxed SYSCLK for HCLK PLL base -this selects the diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 85089d821982..3bc59390a943 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/clkdev.h> #include <linux/irq.h> #include <linux/gpio.h> #include <linux/kernel.h> @@ -14,7 +15,6 @@ #include <linux/mutex.h> #include <linux/platform_device.h> #include <linux/input.h> -#include <linux/clk.h> #include <linux/omapfb.h> #include <linux/spi/spi.h> diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 85e0b0c06718..b64d717bfab6 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -232,14 +232,12 @@ void omap2xxx_clkt_vps_init(void) struct clk_hw_omap *hw = NULL; struct clk *clk; const char *parent_name = "mpu_ck"; - struct clk_lookup *lookup = NULL; omap2xxx_clkt_vps_late_init(); omap2xxx_clkt_vps_check_bootloader_rates(); hw = kzalloc(sizeof(*hw), GFP_KERNEL); - lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); - if (!hw || !lookup) + if (!hw) goto cleanup; init.name = "virt_prcm_set"; init.ops = &virt_prcm_set_ops; @@ -249,15 +247,9 @@ void omap2xxx_clkt_vps_init(void) hw->hw.init = &init; clk = clk_register(NULL, &hw->hw); - - lookup->dev_id = NULL; - lookup->con_id = "cpufreq_ck"; - lookup->clk = clk; - - clkdev_add(lookup); + clkdev_create(clk, "cpufreq_ck", NULL); return; cleanup: kfree(hw); - kfree(lookup); } #endif diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 83a0f5ab85c2..e417f7fcb2ba 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -47,7 +47,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, const char *clk_name) { struct clk *r; - struct clk_lookup *l; + int rc; if (!clk_alias || !clk_name) return; @@ -62,21 +62,15 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, return; } - r = clk_get(NULL, clk_name); - if (IS_ERR(r)) { - dev_err(&od->pdev->dev, - "clk_get for %s failed\n", clk_name); - return; + rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), clk_name, NULL); + if (rc) { + if (rc == -ENODEV || rc == -ENOMEM) + dev_err(&od->pdev->dev, + "clkdev_alloc for %s failed\n", clk_alias); + else + dev_err(&od->pdev->dev, + "clk_get for %s failed\n", clk_name); } - - l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev->dev)); - if (!l) { - dev_err(&od->pdev->dev, - "clkdev_alloc for %s failed\n", clk_alias); - return; - } - - clkdev_add(l); } /** diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index cfb864173ce3..4427bf26ea47 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -10,6 +10,7 @@ * */ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/gpio.h> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 4ac9ab80d24b..7518310c9015 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -11,6 +11,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/clkdev.h> #include <linux/gpio.h> #include <linux/gpio/machine.h> #include <linux/module.h> diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 7780d1faa06f..92e56d8a24d8 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -12,6 +12,7 @@ * */ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index f5b00f41c4f6..2235081a04ee 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -28,11 +28,7 @@ void __init orion_clkdev_add(const char *con_id, const char *dev_id, struct clk *clk) { - struct clk_lookup *cl; - - cl = clkdev_alloc(clk, con_id, dev_id); - if (cl) - clkdev_add(cl); + clkdev_create(clk, con_id, "%s", dev_id); } /* Create clkdev entries for all orion platforms except kirkwood. diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c index 1fdf1ee672de..7f54bf2f453d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c @@ -246,8 +246,7 @@ int __init arch_clk_init(void) for (i = 0; i < ARRAY_SIZE(main_clks); i++) ret |= clk_register(main_clks[i]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index 9a28fdb36387..e40ec2c97ad1 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -141,8 +141,8 @@ int __init arch_clk_init(void) for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 17d0ea55a5a2..8eb6e62340c9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -164,8 +164,8 @@ int __init arch_clk_init(void) for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index bec2a83f1ba5..5e50e7ebeff0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -179,8 +179,8 @@ int __init arch_clk_init(void) for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 9a49a44f6f94..605221d1448a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -138,8 +138,8 @@ int __init arch_clk_init(void) for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), |