![Eric Miao](/assets/img/avatar_default.png)
"""The MarvellĀ® PXA168 processor is the first in a family of application processors targeted at mass market opportunities in computing and consumer devices. It balances high computing and multimedia performance with low power consumption to support extended battery life, and includes a wealth of integrated peripherals to reduce overall BOM cost .... """ See http://www.marvell.com/featured/pxa168.jsp for more information. 1. Marvell Mohawk core is a hybrid of xscale3 and its own ARM core, there are many enhancements like instructions for flushing the whole D-cache, and so on 2. Clock reuses Russell's common clkdev, and added the basic support for UART1/2. 3. Devices are a bit different from the 'mach-pxa' way, the platform devices are now dynamically allocated only when necessary (i.e. when pxa_register_device() is called). Description for each device are stored in an array of 'struct pxa_device_desc'. Now that: a. this array of device description is marked with __initdata and can be freed up system is fully up b. which means board code has to add all needed devices early in his initializing function c. platform specific data can now be marked as __initdata since they are allocated and copied by platform_device_add_data() 4. only the basic UART1/2/3 are added, more devices will come later. Signed-off-by: Jason Chagas <chagas@marvell.com> Signed-off-by: Eric Miao <eric.miao@marvell.com>
84 lines
1.6 KiB
C
84 lines
1.6 KiB
C
/*
|
|
* linux/arch/arm/mach-mmp/clock.c
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/io.h>
|
|
|
|
#include <mach/regs-apbc.h>
|
|
#include "clock.h"
|
|
|
|
static void apbc_clk_enable(struct clk *clk)
|
|
{
|
|
uint32_t clk_rst;
|
|
|
|
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
|
|
__raw_writel(clk_rst, clk->clk_rst);
|
|
}
|
|
|
|
static void apbc_clk_disable(struct clk *clk)
|
|
{
|
|
__raw_writel(0, clk->clk_rst);
|
|
}
|
|
|
|
struct clkops apbc_clk_ops = {
|
|
.enable = apbc_clk_enable,
|
|
.disable = apbc_clk_disable,
|
|
};
|
|
|
|
static DEFINE_SPINLOCK(clocks_lock);
|
|
|
|
int clk_enable(struct clk *clk)
|
|
{
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&clocks_lock, flags);
|
|
if (clk->enabled++ == 0)
|
|
clk->ops->enable(clk);
|
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(clk_enable);
|
|
|
|
void clk_disable(struct clk *clk)
|
|
{
|
|
unsigned long flags;
|
|
|
|
WARN_ON(clk->enabled == 0);
|
|
|
|
spin_lock_irqsave(&clocks_lock, flags);
|
|
if (--clk->enabled == 0)
|
|
clk->ops->disable(clk);
|
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
|
}
|
|
EXPORT_SYMBOL(clk_disable);
|
|
|
|
unsigned long clk_get_rate(struct clk *clk)
|
|
{
|
|
unsigned long rate;
|
|
|
|
if (clk->ops->getrate)
|
|
rate = clk->ops->getrate(clk);
|
|
else
|
|
rate = clk->rate;
|
|
|
|
return rate;
|
|
}
|
|
EXPORT_SYMBOL(clk_get_rate);
|
|
|
|
void clks_register(struct clk_lookup *clks, size_t num)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < num; i++)
|
|
clkdev_add(&clks[i]);
|
|
}
|