diff options
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r-- | arch/arm/mach-davinci/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/mach-davinci/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/cp_intc.c | 75 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/cp_intc.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/dm365.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/dm646x.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/entry-macro.S | 8 | ||||
-rw-r--r-- | arch/arm/mach-davinci/pm_domain.c | 64 |
8 files changed, 130 insertions, 28 deletions
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 32d837d8eab..ab99c3c3b75 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -4,6 +4,7 @@ config AINTC bool config CP_INTC + select IRQ_DOMAIN bool config ARCH_DAVINCI_DMx @@ -61,7 +62,6 @@ config MACH_DAVINCI_EVM bool "TI DM644x EVM" default ARCH_DAVINCI_DM644x depends on ARCH_DAVINCI_DM644x - select MISC_DEVICES select EEPROM_AT24 select I2C help @@ -71,7 +71,6 @@ config MACH_DAVINCI_EVM config MACH_SFFSDR bool "Lyrtech SFFSDR" depends on ARCH_DAVINCI_DM644x - select MISC_DEVICES select EEPROM_AT24 select I2C help @@ -105,7 +104,6 @@ config MACH_DAVINCI_DM6467_EVM default ARCH_DAVINCI_DM646x depends on ARCH_DAVINCI_DM646x select MACH_DAVINCI_DM6467TEVM - select MISC_DEVICES select EEPROM_AT24 select I2C help @@ -119,7 +117,6 @@ config MACH_DAVINCI_DM365_EVM bool "TI DM365 EVM" default ARCH_DAVINCI_DM365 depends on ARCH_DAVINCI_DM365 - select MISC_DEVICES select EEPROM_AT24 select I2C help @@ -131,7 +128,6 @@ config MACH_DAVINCI_DA830_EVM default ARCH_DAVINCI_DA830 depends on ARCH_DAVINCI_DA830 select GPIO_PCF857X - select MISC_DEVICES select EEPROM_AT24 select I2C help @@ -218,7 +214,6 @@ config MACH_TNETV107X config MACH_MITYOMAPL138 bool "Critical Link MityDSP-L138/MityARM-1808 SoM" depends on ARCH_DAVINCI_DA850 - select MISC_DEVICES select EEPROM_AT24 select I2C help diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2db78bd5c83..2227effcb0e 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_SUSPEND) += pm.o sleep.o +obj-$(CONFIG_HAVE_CLK) += pm_domain.o diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index f83152d643c..006dae8dfe4 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -9,9 +9,14 @@ * kind, whether express or implied. */ +#include <linux/export.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/irqdomain.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <mach/common.h> #include <mach/cp_intc.h> @@ -28,7 +33,7 @@ static inline void cp_intc_write(unsigned long value, unsigned offset) static void cp_intc_ack_irq(struct irq_data *d) { - cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR); + cp_intc_write(d->hwirq, CP_INTC_SYS_STAT_IDX_CLR); } /* Disable interrupt */ @@ -36,20 +41,20 @@ static void cp_intc_mask_irq(struct irq_data *d) { /* XXX don't know why we need to disable nIRQ here... */ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR); - cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR); + cp_intc_write(d->hwirq, CP_INTC_SYS_ENABLE_IDX_CLR); cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); } /* Enable interrupt */ static void cp_intc_unmask_irq(struct irq_data *d) { - cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET); + cp_intc_write(d->hwirq, CP_INTC_SYS_ENABLE_IDX_SET); } static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type) { - unsigned reg = BIT_WORD(d->irq); - unsigned mask = BIT_MASK(d->irq); + unsigned reg = BIT_WORD(d->hwirq); + unsigned mask = BIT_MASK(d->hwirq); unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg)); unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg)); @@ -99,18 +104,43 @@ static struct irq_chip cp_intc_irq_chip = { .irq_set_wake = cp_intc_set_wake, }; -void __init cp_intc_init(void) +static struct irq_domain *cp_intc_domain; + +static int cp_intc_host_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) { - unsigned long num_irq = davinci_soc_info.intc_irq_num; + pr_debug("cp_intc_host_map(%d, 0x%lx)\n", virq, hw); + + irq_set_chip(virq, &cp_intc_irq_chip); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + irq_set_handler(virq, handle_edge_irq); + return 0; +} + +static const struct irq_domain_ops cp_intc_host_ops = { + .map = cp_intc_host_map, + .xlate = irq_domain_xlate_onetwocell, +}; + +int __init cp_intc_of_init(struct device_node *node, struct device_node *parent) +{ + u32 num_irq = davinci_soc_info.intc_irq_num; u8 *irq_prio = davinci_soc_info.intc_irq_prios; u32 *host_map = davinci_soc_info.intc_host_map; unsigned num_reg = BITS_TO_LONGS(num_irq); - int i; + int i, irq_base; davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC; - davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K); + if (node) { + davinci_intc_base = of_iomap(node, 0); + if (of_property_read_u32(node, "ti,intc-size", &num_irq)) + pr_warn("unable to get intc-size, default to %d\n", + num_irq); + } else { + davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K); + } if (WARN_ON(!davinci_intc_base)) - return; + return -EINVAL; cp_intc_write(0, CP_INTC_GLOBAL_ENABLE); @@ -165,13 +195,28 @@ void __init cp_intc_init(void) for (i = 0; host_map[i] != -1; i++) cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i)); - /* Set up genirq dispatching for cp_intc */ - for (i = 0; i < num_irq; i++) { - irq_set_chip(i, &cp_intc_irq_chip); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - irq_set_handler(i, handle_edge_irq); + irq_base = irq_alloc_descs(-1, 0, num_irq, 0); + if (irq_base < 0) { + pr_warn("Couldn't allocate IRQ numbers\n"); + irq_base = 0; + } + + /* create a legacy host */ + cp_intc_domain = irq_domain_add_legacy(node, num_irq, + irq_base, 0, &cp_intc_host_ops, NULL); + + if (!cp_intc_domain) { + pr_err("cp_intc: failed to allocate irq host!\n"); + return -EINVAL; } /* Enable global interrupt */ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE); + + return 0; +} + +void __init cp_intc_init(void) +{ + cp_intc_of_init(NULL, NULL); } diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h index 4e8190eed67..d13d8dfa2b0 100644 --- a/arch/arm/mach-davinci/include/mach/cp_intc.h +++ b/arch/arm/mach-davinci/include/mach/cp_intc.h @@ -52,5 +52,6 @@ #define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2)) void __init cp_intc_init(void); +int __init cp_intc_of_init(struct device_node *, struct device_node *); #endif /* __ASM_HARDWARE_CP_INTC_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h deleted file mode 100644 index b9bf3d6a442..00000000000 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ /dev/null @@ -1 +0,0 @@ -/* empty, remove once unused */ diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h deleted file mode 100644 index b9bf3d6a442..00000000000 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ /dev/null @@ -1 +0,0 @@ -/* empty, remove once unused */ diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index 768b3c06021..cf5f573eb5f 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -30,12 +30,10 @@ #endif #if defined(CONFIG_CP_INTC) 1001: ldr \irqnr, [\base, #0x80] /* get irq number */ + mov \tmp, \irqnr, lsr #31 and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */ - mov \tmp, \irqnr, lsr #3 - and \tmp, \tmp, #0xfc - add \tmp, \tmp, #0x280 /* get the register offset */ - ldr \irqstat, [\base, \tmp] /* get the intc status */ - cmp \irqstat, #0x0 + and \tmp, \tmp, #0x1 + cmp \tmp, #0x1 #endif 1002: .endm diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c new file mode 100644 index 00000000000..00946e23c1e --- /dev/null +++ b/arch/arm/mach-davinci/pm_domain.c @@ -0,0 +1,64 @@ +/* + * Runtime PM support code for DaVinci + * + * Author: Kevin Hilman + * + * Copyright (C) 2012 Texas Instruments, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/init.h> +#include <linux/pm_runtime.h> +#include <linux/pm_clock.h> +#include <linux/platform_device.h> + +#ifdef CONFIG_PM_RUNTIME +static int davinci_pm_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = pm_clk_suspend(dev); + if (ret) { + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +static int davinci_pm_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + pm_clk_resume(dev); + return pm_generic_runtime_resume(dev); +} +#endif + +static struct dev_pm_domain davinci_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(davinci_pm_runtime_suspend, + davinci_pm_runtime_resume, NULL) + USE_PLATFORM_PM_SLEEP_OPS + }, +}; + +static struct pm_clk_notifier_block platform_bus_notifier = { + .pm_domain = &davinci_pm_domain, +}; + +static int __init davinci_pm_runtime_init(void) +{ + pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); + + return 0; +} +core_initcall(davinci_pm_runtime_init); |