diff options
Diffstat (limited to 'arch/arm/plat-mxc')
| -rw-r--r-- | arch/arm/plat-mxc/Kconfig | 26 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/Makefile | 8 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/clock.c | 331 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/gpio.c | 253 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/iomux-mx1-mx2.c | 156 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/irq.c | 113 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/time.c | 228 |
7 files changed, 0 insertions, 1115 deletions
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig deleted file mode 100644 index e14eaad11dd..00000000000 --- a/arch/arm/plat-mxc/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -if ARCH_MXC - -menu "Freescale MXC Implementations" - -choice - prompt "MXC/iMX Base Type" - default ARCH_MX3 - -config ARCH_MX2 - bool "MX2-based" - help - This enables support for systems based on the Freescale i.MX2 family - -config ARCH_MX3 - bool "MX3-based" - help - This enables support for systems based on the Freescale i.MX3 family - -endchoice - -source "arch/arm/mach-mx2/Kconfig" -source "arch/arm/mach-mx3/Kconfig" - -endmenu - -endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile deleted file mode 100644 index db66e9ae841..00000000000 --- a/arch/arm/plat-mxc/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Common support -obj-y := irq.o clock.o gpio.o time.o - -obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c deleted file mode 100644 index 1aa86fd60d7..00000000000 --- a/arch/arm/plat-mxc/clock.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Based on arch/arm/plat-omap/clock.c - * - * Copyright (C) 2004 - 2005 Nokia corporation - * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> - * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> - * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -/* #define DEBUG */ - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/platform_device.h> -#include <linux/proc_fs.h> -#include <linux/semaphore.h> -#include <linux/string.h> -#include <linux/version.h> - -#include <asm/arch/clock.h> - -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); - -/*------------------------------------------------------------------------- - * Standard clock functions defined in include/linux/clk.h - *-------------------------------------------------------------------------*/ - -/* - * Retrieve a clock by name. - * - * Note that we first try to use device id on the bus - * and clock name. If this fails, we try to use "<name>.<id>". If this fails, - * we try to use clock name only. - * The reference count to the clock's module owner ref count is incremented. - */ -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *p, *clk = ERR_PTR(-ENOENT); - int idno; - const char *str; - - if (id == NULL) - return clk; - - if (dev == NULL || dev->bus != &platform_bus_type) - idno = -1; - else - idno = to_platform_device(dev)->id; - - mutex_lock(&clocks_mutex); - - list_for_each_entry(p, &clocks, node) { - if (p->id == idno && - strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - goto found; - } - } - - str = strrchr(id, '.'); - if (str) { - int cnt = str - id; - str++; - idno = simple_strtol(str, NULL, 10); - list_for_each_entry(p, &clocks, node) { - if (p->id == idno && - strlen(p->name) == cnt && - strncmp(id, p->name, cnt) == 0 && - try_module_get(p->owner)) { - clk = p; - goto found; - } - } - } - - list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - goto found; - } - } - - printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id); - -found: - mutex_unlock(&clocks_mutex); - - return clk; -} -EXPORT_SYMBOL(clk_get); - -static void __clk_disable(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return; - - __clk_disable(clk->parent); - __clk_disable(clk->secondary); - - if (!(--clk->usecount) && clk->disable) - clk->disable(clk); -} - -static int __clk_enable(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - __clk_enable(clk->parent); - __clk_enable(clk->secondary); - - if (clk->usecount++ == 0 && clk->enable) - clk->enable(clk); - - return 0; -} - -/* This function increments the reference count on the clock and enables the - * clock if not already enabled. The parent clock tree is recursively enabled - */ -int clk_enable(struct clk *clk) -{ - int ret = 0; - - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - ret = __clk_enable(clk); - mutex_unlock(&clocks_mutex); - - return ret; -} -EXPORT_SYMBOL(clk_enable); - -/* This function decrements the reference count on the clock and disables - * the clock when reference count is 0. The parent clock tree is - * recursively disabled - */ -void clk_disable(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return; - - mutex_lock(&clocks_mutex); - __clk_disable(clk); - mutex_unlock(&clocks_mutex); -} -EXPORT_SYMBOL(clk_disable); - -/* Retrieve the *current* clock rate. If the clock itself - * does not provide a special calculation routine, ask - * its parent and so on, until one is able to return - * a valid clock rate - */ -unsigned long clk_get_rate(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return 0UL; - - if (clk->get_rate) - return clk->get_rate(clk); - - return clk_get_rate(clk->parent); -} -EXPORT_SYMBOL(clk_get_rate); - -/* Decrement the clock's module reference count */ -void clk_put(struct clk *clk) -{ - if (clk && !IS_ERR(clk)) - module_put(clk->owner); -} -EXPORT_SYMBOL(clk_put); - -/* Round the requested clock rate to the nearest supported - * rate that is less than or equal to the requested rate. - * This is dependent on the clock's current parent. - */ -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (clk == NULL || IS_ERR(clk) || !clk->round_rate) - return 0; - - return clk->round_rate(clk, rate); -} -EXPORT_SYMBOL(clk_round_rate); - -/* Set the clock to the requested clock rate. The rate must - * match a supported rate exactly based on what clk_round_rate returns - */ -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EINVAL; - - if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0) - return ret; - - mutex_lock(&clocks_mutex); - ret = clk->set_rate(clk, rate); - mutex_unlock(&clocks_mutex); - - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -/* Set the clock's parent to another clock source */ -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - int ret = -EINVAL; - - if (clk == NULL || IS_ERR(clk) || parent == NULL || - IS_ERR(parent) || clk->set_parent == NULL) - return ret; - - mutex_lock(&clocks_mutex); - ret = clk->set_parent(clk, parent); - if (ret == 0) - clk->parent = parent; - mutex_unlock(&clocks_mutex); - - return ret; -} -EXPORT_SYMBOL(clk_set_parent); - -/* Retrieve the clock's parent clock source */ -struct clk *clk_get_parent(struct clk *clk) -{ - struct clk *ret = NULL; - - if (clk == NULL || IS_ERR(clk)) - return ret; - - return clk->parent; -} -EXPORT_SYMBOL(clk_get_parent); - -/* - * Add a new clock to the clock tree. - */ -int clk_register(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - mutex_lock(&clocks_mutex); - list_add(&clk->node, &clocks); - mutex_unlock(&clocks_mutex); - - return 0; -} -EXPORT_SYMBOL(clk_register); - -/* Remove a clock from the clock tree */ -void clk_unregister(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return; - - mutex_lock(&clocks_mutex); - list_del(&clk->node); - mutex_unlock(&clocks_mutex); -} -EXPORT_SYMBOL(clk_unregister); - -#ifdef CONFIG_PROC_FS -static int mxc_clock_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct clk *clkp; - char *p = page; - int len; - - list_for_each_entry(clkp, &clocks, node) { - p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id, - clk_get_rate(clkp), clkp->usecount); - if (clkp->parent) - p += sprintf(p, ", %s-%d\n", clkp->parent->name, - clkp->parent->id); - else - p += sprintf(p, "\n"); - } - - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; - - return len; -} - -static int __init mxc_setup_proc_entry(void) -{ - struct proc_dir_entry *res; - - res = create_proc_read_entry("cpu/clocks", 0, NULL, - mxc_clock_read_proc, NULL); - if (!res) { - printk(KERN_ERR "Failed to create proc/cpu/clocks\n"); - return -ENOMEM; - } - return 0; -} - -late_initcall(mxc_setup_proc_entry); -#endif diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c deleted file mode 100644 index 318b268f938..00000000000 --- a/arch/arm/plat-mxc/gpio.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * Based on code from Freescale, - * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <linux/init.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <asm/hardware.h> -#include <asm-generic/bug.h> - -static struct mxc_gpio_port *mxc_gpio_ports; -static int gpio_table_size; - -/* Note: This driver assumes 32 GPIOs are handled in one register */ - -static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) -{ - __raw_writel(1 << index, port->base + GPIO_ISR); -} - -static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, - int enable) -{ - u32 l; - - l = __raw_readl(port->base + GPIO_IMR); - l = (l & (~(1 << index))) | (!!enable << index); - __raw_writel(l, port->base + GPIO_IMR); -} - -static void gpio_ack_irq(u32 irq) -{ - u32 gpio = irq_to_gpio(irq); - _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); -} - -static void gpio_mask_irq(u32 irq) -{ - u32 gpio = irq_to_gpio(irq); - _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); -} - -static void gpio_unmask_irq(u32 irq) -{ - u32 gpio = irq_to_gpio(irq); - _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); -} - -static int gpio_set_irq_type(u32 irq, u32 type) -{ - u32 gpio = irq_to_gpio(irq); - struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; - u32 bit, val; - int edge; - void __iomem *reg = port->base; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - edge = GPIO_INT_RISE_EDGE; - break; - case IRQ_TYPE_EDGE_FALLING: - edge = GPIO_INT_FALL_EDGE; - break; - case IRQ_TYPE_LEVEL_LOW: - edge = GPIO_INT_LOW_LEV; - break; - case IRQ_TYPE_LEVEL_HIGH: - edge = GPIO_INT_HIGH_LEV; - break; - default: /* this includes IRQ_TYPE_EDGE_BOTH */ - return -EINVAL; - } - - reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ - bit = gpio & 0xf; - val = __raw_readl(reg) & ~(0x3 << (bit << 1)); - __raw_writel(val | (edge << (bit << 1)), reg); - _clear_gpio_irqstatus(port, gpio & 0x1f); - - return 0; -} - -/* handle n interrupts in one status register */ -static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) -{ - u32 gpio_irq_no; - - gpio_irq_no = port->virtual_irq_start; - for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { - - if ((irq_stat & 1) == 0) - continue; - - BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); - irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, - &irq_desc[gpio_irq_no]); - } -} - -#ifdef CONFIG_ARCH_MX3 -/* MX3 has one interrupt *per* gpio port */ -static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) -{ - u32 irq_stat; - struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); - - irq_stat = __raw_readl(port->base + GPIO_ISR) & - __raw_readl(port->base + GPIO_IMR); - BUG_ON(!irq_stat); - mxc_gpio_irq_handler(port, irq_stat); -} -#endif - -#ifdef CONFIG_ARCH_MX2 -/* MX2 has one interrupt *for all* gpio ports */ -static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) -{ - int i; - u32 irq_msk, irq_stat; - struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); - - /* walk through all interrupt status registers */ - for (i = 0; i < gpio_table_size; i++) { - irq_msk = __raw_readl(port[i].base + GPIO_IMR); - if (!irq_msk) - continue; - - irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; - if (irq_stat) - mxc_gpio_irq_handler(&port[i], irq_stat); - } -} -#endif - -static struct irq_chip gpio_irq_chip = { - .ack = gpio_ack_irq, - .mask = gpio_mask_irq, - .unmask = gpio_unmask_irq, - .set_type = gpio_set_irq_type, -}; - -static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, - int dir) -{ - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); - u32 l; - - l = __raw_readl(port->base + GPIO_GDIR); - if (dir) - l |= 1 << offset; - else - l &= ~(1 << offset); - __raw_writel(l, port->base + GPIO_GDIR); -} - -static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); - void __iomem *reg = port->base + GPIO_DR; - u32 l; - - l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); - __raw_writel(l, reg); -} - -static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); - - return (__raw_readl(port->base + GPIO_DR) >> offset) & 1; -} - -static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - _set_gpio_direction(chip, offset, 0); - return 0; -} - -static int mxc_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - _set_gpio_direction(chip, offset, 1); - mxc_gpio_set(chip, offset, value); - return 0; -} - -int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) -{ - int i, j; - - /* save for local usage */ - mxc_gpio_ports = port; - gpio_table_size = cnt; - - printk(KERN_INFO "MXC GPIO hardware\n"); - - for (i = 0; i < cnt; i++) { - /* disable the interrupt and clear the status */ - __raw_writel(0, port[i].base + GPIO_IMR); - __raw_writel(~0, port[i].base + GPIO_ISR); - for (j = port[i].virtual_irq_start; - j < port[i].virtual_irq_start + 32; j++) { - set_irq_chip(j, &gpio_irq_chip); - set_irq_handler(j, handle_edge_irq); - set_irq_flags(j, IRQF_VALID); - } - - /* register gpio chip */ - port[i].chip.direction_input = mxc_gpio_direction_input; - port[i].chip.direction_output = mxc_gpio_direction_output; - port[i].chip.get = mxc_gpio_get; - port[i].chip.set = mxc_gpio_set; - port[i].chip.base = i * 32; - port[i].chip.ngpio = 32; - - /* its a serious configuration bug when it fails */ - BUG_ON( gpiochip_add(&port[i].chip) < 0 ); - -#ifdef CONFIG_ARCH_MX3 - /* setup one handler for each entry */ - set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); - set_irq_data(port[i].irq, &port[i]); -#endif - } - -#ifdef CONFIG_ARCH_MX2 - /* setup one handler for all GPIO interrupts */ - set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); - set_irq_data(port[0].irq, port); -#endif - return 0; -} diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c deleted file mode 100644 index 1985571eb40..00000000000 --- a/arch/arm/plat-mxc/iomux-mx1-mx2.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * arch/arm/mach-mxc/generic.c - * - * author: Sascha Hauer - * Created: april 20th, 2004 - * Copyright: Synertronixx GmbH - * - * Common code for i.MX machines - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/gpio.h> - -#include <asm/hardware.h> -#include <asm/mach/map.h> -#include <asm/arch/iomux-mx1-mx2.h> - -void mxc_gpio_mode(int gpio_mode) -{ - unsigned int pin = gpio_mode & GPIO_PIN_MASK; - unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; - unsigned int tmp; - - /* Pullup enable */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port)); - if (gpio_mode & GPIO_PUEN) - tmp |= (1 << pin); - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port)); - - /* Data direction */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port)); - if (gpio_mode & GPIO_OUT) - tmp |= 1 << pin; - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port)); - - /* Primary / alternate function */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port)); - if (gpio_mode & GPIO_AF) - tmp |= (1 << pin); - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port)); - - /* use as gpio? */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port)); - if (gpio_mode & (GPIO_PF | GPIO_AF)) - tmp &= ~(1 << pin); - else - tmp |= (1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); - - if (pin < 16) { - tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); - } else { - pin -= 16; - - tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port)); - } -} -EXPORT_SYMBOL(mxc_gpio_mode); - -int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - int alloc_mode, const char *label) -{ - const int *p = pin_list; - int i; - unsigned gpio; - unsigned mode; - - for (i = 0; i < count; i++) { - gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); - mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK); - - if (gpio >= (GPIO_PORT_MAX + 1) * 32) - goto setup_error; - - if (alloc_mode & MXC_GPIO_ALLOC_MODE_RELEASE) - gpio_free(gpio); - else if (!(alloc_mode & MXC_GPIO_ALLOC_MODE_NO_ALLOC)) - if (gpio_request(gpio, label) - && !(alloc_mode & MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) - goto setup_error; - - if (!(alloc_mode & (MXC_GPIO_ALLOC_MODE_ALLOC_ONLY | - MXC_GPIO_ALLOC_MODE_RELEASE))) - mxc_gpio_mode(gpio | mode); - - p++; - } - return 0; - -setup_error: - if (alloc_mode & (MXC_GPIO_ALLOC_MODE_NO_ALLOC | - MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) - return -EINVAL; - - while (p != pin_list) { - p--; - gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); - gpio_free(gpio); - } - - return -EINVAL; -} -EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); - diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c deleted file mode 100644 index 1fbe01da692..00000000000 --- a/arch/arm/plat-mxc/irq.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <linux/irq.h> -#include <asm/io.h> -#include <asm/arch/common.h> - -#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) -#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ -#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ -#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ -#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ -#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ -#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ -#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ -#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ -#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ -#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ -#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ -#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ -#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ -#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ -#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ -#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ -#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ -#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ -#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ -#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ -#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ -#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ -#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ -#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ -#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ -#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ - -#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) -#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) -#define IIM_PROD_REV_SH 3 -#define IIM_PROD_REV_LEN 5 - -/* Disable interrupt number "irq" in the AVIC */ -static void mxc_mask_irq(unsigned int irq) -{ - __raw_writel(irq, AVIC_INTDISNUM); -} - -/* Enable interrupt number "irq" in the AVIC */ -static void mxc_unmask_irq(unsigned int irq) -{ - __raw_writel(irq, AVIC_INTENNUM); -} - -static struct irq_chip mxc_avic_chip = { - .ack = mxc_mask_irq, - .mask = mxc_mask_irq, - .unmask = mxc_unmask_irq, -}; - -/* - * This function initializes the AVIC hardware and disables all the - * interrupts. It registers the interrupt enable and disable functions - * to the kernel for each interrupt source. - */ -void __init mxc_init_irq(void) -{ - int i; - u32 reg; - - /* put the AVIC into the reset value with - * all interrupts disabled - */ - __raw_writel(0, AVIC_INTCNTL); - __raw_writel(0x1f, AVIC_NIMASK); - - /* disable all interrupts */ - __raw_writel(0, AVIC_INTENABLEH); - __raw_writel(0, AVIC_INTENABLEL); - - /* all IRQ no FIQ */ - __raw_writel(0, AVIC_INTTYPEH); - __raw_writel(0, AVIC_INTTYPEL); - for (i = 0; i < MXC_MAX_INT_LINES; i++) { - set_irq_chip(i, &mxc_avic_chip); - set_irq_handler(i, handle_level_irq); - set_irq_flags(i, IRQF_VALID); - } - - /* Set WDOG2's interrupt the highest priority level (bit 28-31) */ - reg = __raw_readl(AVIC_NIPRIORITY6); - reg |= (0xF << 28); - __raw_writel(reg, AVIC_NIPRIORITY6); - - /* init architectures chained interrupt handler */ - mxc_register_gpios(); - - printk(KERN_INFO "MXC IRQ initialized\n"); -} diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c deleted file mode 100644 index 3bf86343fdf..00000000000 --- a/arch/arm/plat-mxc/time.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * linux/arch/arm/plat-mxc/time.c - * - * Copyright (C) 2000-2001 Deep Blue Solutions - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) - * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/clockchips.h> -#include <linux/clk.h> - -#include <asm/hardware.h> -#include <asm/mach/time.h> -#include <asm/arch/common.h> -#include <asm/arch/mxc_timer.h> - -static struct clock_event_device clockevent_mxc; -static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; - -/* clock source for the timer */ -static struct clk *timer_clk; - -/* clock source */ - -static cycle_t mxc_get_cycles(void) -{ - return __raw_readl(TIMER_BASE + MXC_TCN); -} - -static struct clocksource clocksource_mxc = { - .name = "mxc_timer1", - .rating = 200, - .read = mxc_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init mxc_clocksource_init(void) -{ - unsigned int clock; - - clock = clk_get_rate(timer_clk); - - clocksource_mxc.mult = clocksource_hz2mult(clock, - clocksource_mxc.shift); - clocksource_register(&clocksource_mxc); - - return 0; -} - -/* clock event */ - -static int mxc_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long tcmp; - - tcmp = __raw_readl(TIMER_BASE + MXC_TCN) + evt; - __raw_writel(tcmp, TIMER_BASE + MXC_TCMP); - - return (int)(tcmp - __raw_readl(TIMER_BASE + MXC_TCN)) < 0 ? - -ETIME : 0; -} - -#ifdef DEBUG -static const char *clock_event_mode_label[] = { - [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", - [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", - [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", - [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED" -}; -#endif /* DEBUG */ - -static void mxc_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long flags; - - /* - * The timer interrupt generation is disabled at least - * for enough time to call mxc_set_next_event() - */ - local_irq_save(flags); - - /* Disable interrupt in GPT module */ - gpt_irq_disable(); - - if (mode != clockevent_mode) { - /* Set event time into far-far future */ - __raw_writel(__raw_readl(TIMER_BASE + MXC_TCN) - 3, - TIMER_BASE + MXC_TCMP); - /* Clear pending interrupt */ - gpt_irq_acknowledge(); - } - -#ifdef DEBUG - printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", - clock_event_mode_label[clockevent_mode], - clock_event_mode_label[mode]); -#endif /* DEBUG */ - - /* Remember timer mode */ - clockevent_mode = mode; - local_irq_restore(flags); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - printk(KERN_ERR"mxc_set_mode: Periodic mode is not " - "supported for i.MX\n"); - break; - case CLOCK_EVT_MODE_ONESHOT: - /* - * Do not put overhead of interrupt enable/disable into - * mxc_set_next_event(), the core has about 4 minutes - * to call mxc_set_next_event() or shutdown clock after - * mode switching - */ - local_irq_save(flags); - gpt_irq_enable(); - local_irq_restore(flags); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_RESUME: - /* Left event sources disabled, no more interrupts appear */ - break; - } -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_mxc; - uint32_t tstat; - - tstat = __raw_readl(TIMER_BASE + MXC_TSTAT); - - gpt_irq_acknowledge(); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction mxc_timer_irq = { - .name = "i.MX Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = mxc_timer_interrupt, -}; - -static struct clock_event_device clockevent_mxc = { - .name = "mxc_timer1", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .set_mode = mxc_set_mode, - .set_next_event = mxc_set_next_event, - .rating = 200, -}; - -static int __init mxc_clockevent_init(void) -{ - unsigned int clock; - - clock = clk_get_rate(timer_clk); - - clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC, - clockevent_mxc.shift); - clockevent_mxc.max_delta_ns = - clockevent_delta2ns(0xfffffffe, &clockevent_mxc); - clockevent_mxc.min_delta_ns = - clockevent_delta2ns(0xff, &clockevent_mxc); - - clockevent_mxc.cpumask = cpumask_of_cpu(0); - - clockevents_register_device(&clockevent_mxc); - - return 0; -} - -void __init mxc_timer_init(const char *clk_timer) -{ - timer_clk = clk_get(NULL, clk_timer); - if (!timer_clk) { - printk(KERN_ERR"Cannot determine timer clock. Giving up.\n"); - return; - } - - clk_enable(timer_clk); - - /* - * Initialise to a known state (all timers off, and timing reset) - */ - __raw_writel(0, TIMER_BASE + MXC_TCTL); - __raw_writel(0, TIMER_BASE + MXC_TPRER); /* see datasheet note */ - - __raw_writel(TCTL_FRR | /* free running */ - TCTL_VAL | /* set clocksource and arch specific bits */ - TCTL_TEN, /* start the timer */ - TIMER_BASE + MXC_TCTL); - - /* init and register the timer to the framework */ - mxc_clocksource_init(); - mxc_clockevent_init(); - - /* Make irqs happen */ - setup_irq(TIMER_INTERRUPT, &mxc_timer_irq); -} - |
