* [PATCH] nand: Fix S3C NAND clock stop @ 2011-04-11 1:27 Jiri Pinkava 2011-04-11 2:05 ` Randy Dunlap 0 siblings, 1 reply; 9+ messages in thread From: Jiri Pinkava @ 2011-04-11 1:27 UTC (permalink / raw) To: ben-linux Cc: kgene.kim, dwmw2, linux-arm-kernel, linux-mtd, linux-kernel, Jiri Pinkava Current implementation of s3c2410_nand_select_chip call clk_disable every time when chip = -1 (de-select). This happend multiple times even if chip was already de-selected. This causes disabling clock even if they are already disabled and due to nature of clock subsytem implementation this causes nand clock to be disabled and newer enabled again. Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 57 +++++++++++++++++++++++++++++++------------ 1 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832d..79e18a3 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -54,8 +54,14 @@ static int hardware_ecc = 1; static int hardware_ecc = 0; #endif +#define CLOCK_DISABLE 0 +#define CLOCK_ENABLE 1 +#define CLOCK_SUSPEND 2 + +static int clock_state = CLOCK_DISABLE; + #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static int clock_stop = 1; +static const int clock_stop = 1; #else static const int clock_stop = 0; #endif @@ -159,11 +165,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) return dev->dev.platform_data; } -static inline int allow_clk_stop(struct s3c2410_nand_info *info) +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { return clock_stop; } +/** + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. + * @info: The controller instance. + * @state: State to which clock should be set. + */ +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, + int new_state) +{ + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) + return; + + if (clock_state == CLOCK_ENABLE) { + if (new_state != CLOCK_ENABLE) + clk_disable(info->clk); + } else { + if (new_state == CLOCK_ENABLE) + clk_enable(info->clk); + } + + clock_state = new_state; +} + /* timing calculations */ #define NS_IN_KHZ 1000000 @@ -333,8 +361,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) nmtd = this->priv; info = nmtd->info; - if (chip != -1 && allow_clk_stop(info)) - clk_enable(info->clk); + if (chip != -1) + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); cur = readl(info->sel_reg); @@ -356,8 +384,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) writel(cur, info->sel_reg); - if (chip == -1 && allow_clk_stop(info)) - clk_disable(info->clk); + if (chip == -1) + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } /* s3c2410_nand_hwcontrol @@ -694,8 +722,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) /* free the common resources */ if (info->clk != NULL && !IS_ERR(info->clk)) { - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); clk_put(info->clk); } @@ -947,7 +974,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); /* allocate and map the resource */ @@ -1026,9 +1053,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - if (allow_clk_stop(info)) { + if (allow_clk_suspend(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } pr_debug("initialised ok\n"); @@ -1059,8 +1086,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) writel(info->save_sel | info->sel_bit, info->sel_reg); - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); } return 0; @@ -1072,7 +1098,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) unsigned long sel; if (info) { - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); s3c2410_nand_inithw(info); /* Restore the state of the nFCE line. */ @@ -1082,8 +1108,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) sel |= info->save_sel & info->sel_bit; writel(sel, info->sel_reg); - if (allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } return 0; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] nand: Fix S3C NAND clock stop 2011-04-11 1:27 [PATCH] nand: Fix S3C NAND clock stop Jiri Pinkava @ 2011-04-11 2:05 ` Randy Dunlap 2011-04-11 3:15 ` Jiří Pinkava 0 siblings, 1 reply; 9+ messages in thread From: Randy Dunlap @ 2011-04-11 2:05 UTC (permalink / raw) To: Jiri Pinkava Cc: ben-linux, kgene.kim, dwmw2, linux-arm-kernel, linux-mtd, linux-kernel On 4/10/2011 6:27 PM, Jiri Pinkava wrote: > Current implementation of s3c2410_nand_select_chip call > clk_disable every time when chip = -1 (de-select). This happend > multiple times even if chip was already de-selected. This causes > disabling clock even if they are already disabled and due to > nature of clock subsytem implementation this causes nand clock > to be disabled and newer enabled again. > > Signed-off-by: Jiri Pinkava<jiri.pinkava@vscht.cz> > --- > drivers/mtd/nand/s3c2410.c | 57 +++++++++++++++++++++++++++++++------------ > 1 files changed, 41 insertions(+), 16 deletions(-) > > diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c > index 33d832d..79e18a3 100644 > --- a/drivers/mtd/nand/s3c2410.c > +++ b/drivers/mtd/nand/s3c2410.c > @@ -159,11 +165,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) > return dev->dev.platform_data; > } > > -static inline int allow_clk_stop(struct s3c2410_nand_info *info) > +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) > { > return clock_stop; > } > > +/** > + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. > + * @info: The controller instance. > + * @state: State to which clock should be set. @new_state: > + */ > +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, > + int new_state) > +{ > + if (!allow_clk_suspend(info)&& new_state == CLOCK_SUSPEND) > + return; > + > + if (clock_state == CLOCK_ENABLE) { > + if (new_state != CLOCK_ENABLE) > + clk_disable(info->clk); > + } else { > + if (new_state == CLOCK_ENABLE) > + clk_enable(info->clk); > + } > + > + clock_state = new_state; > +} ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] nand: Fix S3C NAND clock stop 2011-04-11 2:05 ` Randy Dunlap @ 2011-04-11 3:15 ` Jiří Pinkava 2011-04-11 14:48 ` Jiri Pinkava 0 siblings, 1 reply; 9+ messages in thread From: Jiří Pinkava @ 2011-04-11 3:15 UTC (permalink / raw) To: Randy Dunlap Cc: ben-linux@fluff.org, kgene.kim@samsung.com, dwmw2@infradead.org, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org [-- Attachment #1: Type: text/plain, Size: 4329 bytes --] Current implementation of s3c2410_nand_select_chip call clk_disable every time when chip = -1 (de-select). This happend multiple times even if chip was already de-selected. This causes disabling clock even if they are already disabled and due to nature of clock subsytem implementation this causes nand clock to be disabled and newer enabled again. Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 57 +++++++++++++++++++++++++++++++------------ 1 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832d..fbc37dc 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -54,8 +54,14 @@ static int hardware_ecc = 1; static int hardware_ecc = 0; #endif +#define CLOCK_DISABLE 0 +#define CLOCK_ENABLE 1 +#define CLOCK_SUSPEND 2 + +static int clock_state = CLOCK_DISABLE; + #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static int clock_stop = 1; +static const int clock_stop = 1; #else static const int clock_stop = 0; #endif @@ -159,11 +165,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) return dev->dev.platform_data; } -static inline int allow_clk_stop(struct s3c2410_nand_info *info) +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { return clock_stop; } +/** + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. + * @info: The controller instance. + * @new_state: State to which clock should be set. + */ +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, + int new_state) +{ + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) + return; + + if (clock_state == CLOCK_ENABLE) { + if (new_state != CLOCK_ENABLE) + clk_disable(info->clk); + } else { + if (new_state == CLOCK_ENABLE) + clk_enable(info->clk); + } + + clock_state = new_state; +} + /* timing calculations */ #define NS_IN_KHZ 1000000 @@ -333,8 +361,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) nmtd = this->priv; info = nmtd->info; - if (chip != -1 && allow_clk_stop(info)) - clk_enable(info->clk); + if (chip != -1) + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); cur = readl(info->sel_reg); @@ -356,8 +384,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) writel(cur, info->sel_reg); - if (chip == -1 && allow_clk_stop(info)) - clk_disable(info->clk); + if (chip == -1) + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } /* s3c2410_nand_hwcontrol @@ -694,8 +722,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) /* free the common resources */ if (info->clk != NULL && !IS_ERR(info->clk)) { - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); clk_put(info->clk); } @@ -947,7 +974,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); /* allocate and map the resource */ @@ -1026,9 +1053,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - if (allow_clk_stop(info)) { + if (allow_clk_suspend(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } pr_debug("initialised ok\n"); @@ -1059,8 +1086,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) writel(info->save_sel | info->sel_bit, info->sel_reg); - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); } return 0; @@ -1072,7 +1098,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) unsigned long sel; if (info) { - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); s3c2410_nand_inithw(info); /* Restore the state of the nFCE line. */ @@ -1082,8 +1108,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) sel |= info->save_sel & info->sel_bit; writel(sel, info->sel_reg); - if (allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } return 0; -- 1.7.4.4 [-- Attachment #2: 0001-nand-Fix-S3C-NAND-clock-stop.patch --] [-- Type: text/x-patch, Size: 4499 bytes --] >From 4fd7086f28d6452f1edafa903e7becd5a0f017c6 Mon Sep 17 00:00:00 2001 From: Jiri Pinkava <jiri.pinkava@vscht.cz> Date: Mon, 11 Apr 2011 03:20:33 +0200 Subject: [PATCH] nand: Fix S3C NAND clock stop Current implementation of s3c2410_nand_select_chip call clk_disable every time when chip = -1 (de-select). This happend multiple times even if chip was already de-selected. This causes disabling clock even if they are already disabled and due to nature of clock subsytem implementation this causes nand clock to be disabled and newer enabled again. Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 57 +++++++++++++++++++++++++++++++------------ 1 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832d..fbc37dc 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -54,8 +54,14 @@ static int hardware_ecc = 1; static int hardware_ecc = 0; #endif +#define CLOCK_DISABLE 0 +#define CLOCK_ENABLE 1 +#define CLOCK_SUSPEND 2 + +static int clock_state = CLOCK_DISABLE; + #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static int clock_stop = 1; +static const int clock_stop = 1; #else static const int clock_stop = 0; #endif @@ -159,11 +165,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) return dev->dev.platform_data; } -static inline int allow_clk_stop(struct s3c2410_nand_info *info) +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { return clock_stop; } +/** + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. + * @info: The controller instance. + * @new_state: State to which clock should be set. + */ +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, + int new_state) +{ + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) + return; + + if (clock_state == CLOCK_ENABLE) { + if (new_state != CLOCK_ENABLE) + clk_disable(info->clk); + } else { + if (new_state == CLOCK_ENABLE) + clk_enable(info->clk); + } + + clock_state = new_state; +} + /* timing calculations */ #define NS_IN_KHZ 1000000 @@ -333,8 +361,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) nmtd = this->priv; info = nmtd->info; - if (chip != -1 && allow_clk_stop(info)) - clk_enable(info->clk); + if (chip != -1) + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); cur = readl(info->sel_reg); @@ -356,8 +384,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) writel(cur, info->sel_reg); - if (chip == -1 && allow_clk_stop(info)) - clk_disable(info->clk); + if (chip == -1) + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } /* s3c2410_nand_hwcontrol @@ -694,8 +722,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) /* free the common resources */ if (info->clk != NULL && !IS_ERR(info->clk)) { - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); clk_put(info->clk); } @@ -947,7 +974,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); /* allocate and map the resource */ @@ -1026,9 +1053,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - if (allow_clk_stop(info)) { + if (allow_clk_suspend(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } pr_debug("initialised ok\n"); @@ -1059,8 +1086,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) writel(info->save_sel | info->sel_bit, info->sel_reg); - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); } return 0; @@ -1072,7 +1098,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) unsigned long sel; if (info) { - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); s3c2410_nand_inithw(info); /* Restore the state of the nFCE line. */ @@ -1082,8 +1108,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) sel |= info->save_sel & info->sel_bit; writel(sel, info->sel_reg); - if (allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } return 0; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH] nand: Fix S3C NAND clock stop 2011-04-11 3:15 ` Jiří Pinkava @ 2011-04-11 14:48 ` Jiri Pinkava 2011-04-13 3:36 ` Artem Bityutskiy 0 siblings, 1 reply; 9+ messages in thread From: Jiri Pinkava @ 2011-04-11 14:48 UTC (permalink / raw) To: dedekind1; +Cc: ben-linux, linux-kernel, linux-mtd, Jiri Pinkava Current implementation of s3c2410_nand_select_chip call clk_disable every time when chip = -1 (de-select). This happend multiple times even if chip was already de-selected. This causes disabling clock even if they are already disabled and due to nature of clock subsytem implementation this causes nand clock to be disabled and newer enabled again. Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 59 ++++++++++++++++++++++++++++++++------------ 1 files changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832d..cea775a 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -55,7 +55,7 @@ static int hardware_ecc = 0; #endif #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static int clock_stop = 1; +static const int clock_stop = 1; #else static const int clock_stop = 0; #endif @@ -96,6 +96,12 @@ enum s3c_cpu_type { TYPE_S3C2440, }; +enum s3c_nand_clk_state { + CLOCK_DISABLE = 0, + CLOCK_ENABLE, + CLOCK_SUSPEND, +}; + /* overview of the s3c2410 nand state */ /** @@ -111,6 +117,7 @@ enum s3c_cpu_type { * @mtd_count: The number of MTDs created from this controller. * @save_sel: The contents of @sel_reg to be saved over suspend. * @clk_rate: The clock rate from @clk. + * @clk_state: The current clock state. * @cpu_type: The exact type of this controller. */ struct s3c2410_nand_info { @@ -129,6 +136,7 @@ struct s3c2410_nand_info { int mtd_count; unsigned long save_sel; unsigned long clk_rate; + enum s3c_nand_clk_state clk_state; enum s3c_cpu_type cpu_type; @@ -159,11 +167,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) return dev->dev.platform_data; } -static inline int allow_clk_stop(struct s3c2410_nand_info *info) +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { return clock_stop; } +/** + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. + * @info: The controller instance. + * @new_state: State to which clock should be set. + */ +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, + enum s3c_nand_clk_state new_state) +{ + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) + return; + + if (info->clk_state == CLOCK_ENABLE) { + if (new_state != CLOCK_ENABLE) + clk_disable(info->clk); + } else { + if (new_state == CLOCK_ENABLE) + clk_enable(info->clk); + } + + info->clk_state = new_state; +} + /* timing calculations */ #define NS_IN_KHZ 1000000 @@ -333,8 +363,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) nmtd = this->priv; info = nmtd->info; - if (chip != -1 && allow_clk_stop(info)) - clk_enable(info->clk); + if (chip != -1) + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); cur = readl(info->sel_reg); @@ -356,8 +386,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) writel(cur, info->sel_reg); - if (chip == -1 && allow_clk_stop(info)) - clk_disable(info->clk); + if (chip == -1) + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } /* s3c2410_nand_hwcontrol @@ -694,8 +724,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) /* free the common resources */ if (info->clk != NULL && !IS_ERR(info->clk)) { - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); clk_put(info->clk); } @@ -947,7 +976,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); /* allocate and map the resource */ @@ -1026,9 +1055,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - if (allow_clk_stop(info)) { + if (allow_clk_suspend(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } pr_debug("initialised ok\n"); @@ -1059,8 +1088,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) writel(info->save_sel | info->sel_bit, info->sel_reg); - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); } return 0; @@ -1072,7 +1100,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) unsigned long sel; if (info) { - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); s3c2410_nand_inithw(info); /* Restore the state of the nFCE line. */ @@ -1082,8 +1110,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) sel |= info->save_sel & info->sel_bit; writel(sel, info->sel_reg); - if (allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } return 0; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] nand: Fix S3C NAND clock stop 2011-04-11 14:48 ` Jiri Pinkava @ 2011-04-13 3:36 ` Artem Bityutskiy 2011-04-13 9:59 ` [PATCH 1/2] " Jiri Pinkava 0 siblings, 1 reply; 9+ messages in thread From: Artem Bityutskiy @ 2011-04-13 3:36 UTC (permalink / raw) To: Jiri Pinkava; +Cc: ben-linux, linux-kernel, linux-mtd On Mon, 2011-04-11 at 16:48 +0200, Jiri Pinkava wrote: > Current implementation of s3c2410_nand_select_chip call > clk_disable every time when chip = -1 (de-select). This happend > multiple times even if chip was already de-selected. This causes > disabling clock even if they are already disabled and due to > nature of clock subsytem implementation this causes nand clock > to be disabled and newer enabled again. > > Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> > --- > drivers/mtd/nand/s3c2410.c | 59 ++++++++++++++++++++++++++++++++------------ > 1 files changed, 43 insertions(+), 16 deletions(-) > > diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c > index 33d832d..cea775a 100644 > --- a/drivers/mtd/nand/s3c2410.c > +++ b/drivers/mtd/nand/s3c2410.c > @@ -55,7 +55,7 @@ static int hardware_ecc = 0; > #endif > > #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP > -static int clock_stop = 1; > +static const int clock_stop = 1; > #else > static const int clock_stop = 0; > #endif Please, kill clock_stop variable completely in a separate patch. -- Best Regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] nand: Fix S3C NAND clock stop 2011-04-13 3:36 ` Artem Bityutskiy @ 2011-04-13 9:59 ` Jiri Pinkava 2011-04-13 9:59 ` [PATCH 2/2] nand: Remove unnecessary variable Jiri Pinkava 2011-04-14 12:16 ` [PATCH 1/2] nand: Fix S3C NAND clock stop Artem Bityutskiy 0 siblings, 2 replies; 9+ messages in thread From: Jiri Pinkava @ 2011-04-13 9:59 UTC (permalink / raw) To: dedekind1; +Cc: ben-linux, linux-kernel, linux-mtd, Jiri Pinkava Current implementation of s3c2410_nand_select_chip call clk_disable every time when chip = -1 (de-select). This happend multiple times even if chip was already de-selected. This causes disabling clock even if they are already disabled and due to nature of clock subsytem implementation this causes nand clock to be disabled and newer enabled again. Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 59 ++++++++++++++++++++++++++++++++------------ 1 files changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832d..cea775a 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -55,7 +55,7 @@ static int hardware_ecc = 0; #endif #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static int clock_stop = 1; +static const int clock_stop = 1; #else static const int clock_stop = 0; #endif @@ -96,6 +96,12 @@ enum s3c_cpu_type { TYPE_S3C2440, }; +enum s3c_nand_clk_state { + CLOCK_DISABLE = 0, + CLOCK_ENABLE, + CLOCK_SUSPEND, +}; + /* overview of the s3c2410 nand state */ /** @@ -111,6 +117,7 @@ enum s3c_cpu_type { * @mtd_count: The number of MTDs created from this controller. * @save_sel: The contents of @sel_reg to be saved over suspend. * @clk_rate: The clock rate from @clk. + * @clk_state: The current clock state. * @cpu_type: The exact type of this controller. */ struct s3c2410_nand_info { @@ -129,6 +136,7 @@ struct s3c2410_nand_info { int mtd_count; unsigned long save_sel; unsigned long clk_rate; + enum s3c_nand_clk_state clk_state; enum s3c_cpu_type cpu_type; @@ -159,11 +167,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) return dev->dev.platform_data; } -static inline int allow_clk_stop(struct s3c2410_nand_info *info) +static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { return clock_stop; } +/** + * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. + * @info: The controller instance. + * @new_state: State to which clock should be set. + */ +static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, + enum s3c_nand_clk_state new_state) +{ + if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) + return; + + if (info->clk_state == CLOCK_ENABLE) { + if (new_state != CLOCK_ENABLE) + clk_disable(info->clk); + } else { + if (new_state == CLOCK_ENABLE) + clk_enable(info->clk); + } + + info->clk_state = new_state; +} + /* timing calculations */ #define NS_IN_KHZ 1000000 @@ -333,8 +363,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) nmtd = this->priv; info = nmtd->info; - if (chip != -1 && allow_clk_stop(info)) - clk_enable(info->clk); + if (chip != -1) + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); cur = readl(info->sel_reg); @@ -356,8 +386,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) writel(cur, info->sel_reg); - if (chip == -1 && allow_clk_stop(info)) - clk_disable(info->clk); + if (chip == -1) + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } /* s3c2410_nand_hwcontrol @@ -694,8 +724,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) /* free the common resources */ if (info->clk != NULL && !IS_ERR(info->clk)) { - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); clk_put(info->clk); } @@ -947,7 +976,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); /* allocate and map the resource */ @@ -1026,9 +1055,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) goto exit_error; } - if (allow_clk_stop(info)) { + if (allow_clk_suspend(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } pr_debug("initialised ok\n"); @@ -1059,8 +1088,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) writel(info->save_sel | info->sel_bit, info->sel_reg); - if (!allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); } return 0; @@ -1072,7 +1100,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) unsigned long sel; if (info) { - clk_enable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); s3c2410_nand_inithw(info); /* Restore the state of the nFCE line. */ @@ -1082,8 +1110,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) sel |= info->save_sel & info->sel_bit; writel(sel, info->sel_reg); - if (allow_clk_stop(info)) - clk_disable(info->clk); + s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); } return 0; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] nand: Remove unnecessary variable 2011-04-13 9:59 ` [PATCH 1/2] " Jiri Pinkava @ 2011-04-13 9:59 ` Jiri Pinkava 2011-04-14 12:17 ` Artem Bityutskiy 2011-04-14 12:16 ` [PATCH 1/2] nand: Fix S3C NAND clock stop Artem Bityutskiy 1 sibling, 1 reply; 9+ messages in thread From: Jiri Pinkava @ 2011-04-13 9:59 UTC (permalink / raw) To: dedekind1; +Cc: ben-linux, linux-kernel, linux-mtd, Jiri Pinkava Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> --- drivers/mtd/nand/s3c2410.c | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index cea775a..8041038 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -54,12 +54,6 @@ static int hardware_ecc = 1; static int hardware_ecc = 0; #endif -#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP -static const int clock_stop = 1; -#else -static const int clock_stop = 0; -#endif - /* new oob placement block for use with hardware ecc generation */ @@ -169,7 +163,11 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) static inline int allow_clk_suspend(struct s3c2410_nand_info *info) { - return clock_stop; +#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP + return 1; +#else + return 0; +#endif } /** -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] nand: Remove unnecessary variable 2011-04-13 9:59 ` [PATCH 2/2] nand: Remove unnecessary variable Jiri Pinkava @ 2011-04-14 12:17 ` Artem Bityutskiy 0 siblings, 0 replies; 9+ messages in thread From: Artem Bityutskiy @ 2011-04-14 12:17 UTC (permalink / raw) To: Jiri Pinkava; +Cc: ben-linux, linux-kernel, linux-mtd On Wed, 2011-04-13 at 11:59 +0200, Jiri Pinkava wrote: > Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> > --- > drivers/mtd/nand/s3c2410.c | 12 +++++------- > 1 files changed, 5 insertions(+), 7 deletions(-) Let's drop this, sorry, I gave you wrong advise. -- Best Regards, Artem Bityutskiy (Артём Битюцкий) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] nand: Fix S3C NAND clock stop 2011-04-13 9:59 ` [PATCH 1/2] " Jiri Pinkava 2011-04-13 9:59 ` [PATCH 2/2] nand: Remove unnecessary variable Jiri Pinkava @ 2011-04-14 12:16 ` Artem Bityutskiy 1 sibling, 0 replies; 9+ messages in thread From: Artem Bityutskiy @ 2011-04-14 12:16 UTC (permalink / raw) To: Jiri Pinkava; +Cc: ben-linux, linux-kernel, linux-mtd On Wed, 2011-04-13 at 11:59 +0200, Jiri Pinkava wrote: > Current implementation of s3c2410_nand_select_chip call > clk_disable every time when chip = -1 (de-select). This happend > multiple times even if chip was already de-selected. This causes > disabling clock even if they are already disabled and due to > nature of clock subsytem implementation this causes nand clock > to be disabled and newer enabled again. > > Signed-off-by: Jiri Pinkava <jiri.pinkava@vscht.cz> Pushed to l2-mtd-2.6.git, thanks. -- Best Regards, Artem Bityutskiy (Артём Битюцкий) ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-04-14 12:20 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-04-11 1:27 [PATCH] nand: Fix S3C NAND clock stop Jiri Pinkava 2011-04-11 2:05 ` Randy Dunlap 2011-04-11 3:15 ` Jiří Pinkava 2011-04-11 14:48 ` Jiri Pinkava 2011-04-13 3:36 ` Artem Bityutskiy 2011-04-13 9:59 ` [PATCH 1/2] " Jiri Pinkava 2011-04-13 9:59 ` [PATCH 2/2] nand: Remove unnecessary variable Jiri Pinkava 2011-04-14 12:17 ` Artem Bityutskiy 2011-04-14 12:16 ` [PATCH 1/2] nand: Fix S3C NAND clock stop Artem Bityutskiy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).