Skip to content

Commit

Permalink
[ARM] 3303/1: S3C24XX - add clock enable usage counting
Browse files Browse the repository at this point in the history
Patch from Ben Dooks

Move to using an enable count for the shared clocks
and protect the clock system using a mutex instead
of just disabling IRQs during the clock update.

Since there is little more code in the path for
non-shared clocks, the enable and disable calls
use the same code for each.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Ben Dooks authored and Russell King committed Feb 8, 2006
1 parent f8e5b28 commit 2a513ce
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
43 changes: 33 additions & 10 deletions arch/arm/mach-s3c2410/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <linux/mutex.h>

#include <asm/hardware.h>
#include <asm/atomic.h>
#include <asm/irq.h>
#include <asm/io.h>

Expand All @@ -59,22 +58,18 @@ static DEFINE_MUTEX(clocks_mutex);
void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
{
unsigned long clkcon;
unsigned long flags;

local_irq_save(flags);

clkcon = __raw_readl(S3C2410_CLKCON);
clkcon &= ~clocks;

if (enable)
clkcon |= clocks;
else
clkcon &= ~clocks;

/* ensure none of the special function bits set */
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);

__raw_writel(clkcon, S3C2410_CLKCON);

local_irq_restore(flags);
}

/* enable and disable calls for use with the clk struct */
Expand Down Expand Up @@ -138,16 +133,32 @@ void clk_put(struct clk *clk)

int clk_enable(struct clk *clk)
{
if (IS_ERR(clk))
if (IS_ERR(clk) || clk == NULL)
return -EINVAL;

return (clk->enable)(clk, 1);
clk_enable(clk->parent);

mutex_lock(&clocks_mutex);

if ((clk->usage++) == 0)
(clk->enable)(clk, 1);

mutex_unlock(&clocks_mutex);
return 0;
}

void clk_disable(struct clk *clk)
{
if (!IS_ERR(clk))
if (IS_ERR(clk) || clk == NULL)
return;

mutex_lock(&clocks_mutex);

if ((--clk->usage) == 0)
(clk->enable)(clk, 0);

mutex_unlock(&clocks_mutex);
clk_disable(clk->parent);
}


Expand Down Expand Up @@ -361,6 +372,14 @@ int s3c24xx_register_clock(struct clk *clk)
if (clk->enable == NULL)
clk->enable = clk_null_enable;

/* if this is a standard clock, set the usage state */

if (clk->ctrlbit) {
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);

clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
}

/* add to the list of available clocks */

mutex_lock(&clocks_mutex);
Expand Down Expand Up @@ -402,13 +421,17 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
* the LCD clock if it is not needed.
*/

mutex_lock(&clocks_mutex);

s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);

mutex_unlock(&clocks_mutex);

/* assume uart clocks are correctly setup */

/* register our clocks */
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-s3c2410/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct clk {
struct clk *parent;
const char *name;
int id;
int usage;
unsigned long rate;
unsigned long ctrlbit;
int (*enable)(struct clk *, int enable);
Expand Down

0 comments on commit 2a513ce

Please sign in to comment.